Re: [PATCH v5 3/3] fpga: dfl: add support for N3000 Nios private feature

2020-08-13 Thread Xu Yilun
On Thu, Aug 13, 2020 at 04:43:33PM +0800, Wu, Hao wrote:
> > Subject: [PATCH v5 3/3] fpga: dfl: add support for N3000 Nios private 
> > feature
> >
> > This patch adds support for the Nios handshake private feature on Intel
> > PAC (Programmable Acceleration Card) N3000.
> >
> > The Nios is the embedded processor on the FPGA card. This private feature
> > provides a handshake interface to FPGA Nois firmware, which receives
> > retimer configuration command from host and executes via an internal SPI
> > master (spi-altera). When Nios finishes the configuration, host takes over
> > the ownership of the SPI master to control an Intel MAX10 BMC (Board
> > Management Controller) Chip on the SPI bus.
> >
> > For Nios firmware handshake part, this driver requests the retimer
> > configuration for Nios with parameters from module param, and adds some
> > sysfs nodes for user to query the onboard retimer's working mode and
> > Nios firmware version.
> >
> > For SPI part, this driver adds a spi-altera platform device as well as
> > the MAX10 BMC spi slave info. A spi-altera driver will be matched to
> > handle the following SPI work.
> >
> > Signed-off-by: Xu Yilun 
> > Signed-off-by: Wu Hao 
> > Signed-off-by: Matthew Gerlach 
> > Signed-off-by: Russ Weight 
> > Reviewed-by: Tom Rix 
> > ---
> > v3: Add the doc for this driver
> > Minor fixes for comments from Tom
> > v4: Move the err log in regmap implementation, and delete
> >  n3000_nios_writel/readl(), they have nothing to wrapper now.
> > Some minor fixes and comments improvement.
> > v5: Fix the output of fec_mode sysfs inf to "no" on 10G configuration,
> > cause no FEC mode could be configured for 10G.
> > Rename the dfl_n3000_nios_* to n3000_nios_*
> > Improves comments.
> > ---
> >  .../ABI/testing/sysfs-bus-dfl-devices-n3000-nios   |  18 +
> >  Documentation/fpga/dfl-n3000-nios.rst  |  45 ++
> >  Documentation/fpga/index.rst   |   1 +
> >  drivers/fpga/Kconfig   |  11 +
> >  drivers/fpga/Makefile  |   2 +
> >  drivers/fpga/dfl-n3000-nios.c  | 528 
> > +
> >  6 files changed, 605 insertions(+)
> >  create mode 100644 Documentation/ABI/testing/sysfs-bus-dfl-devices-
> > n3000-nios
> >  create mode 100644 Documentation/fpga/dfl-n3000-nios.rst
> >  create mode 100644 drivers/fpga/dfl-n3000-nios.c
> >
> > diff --git a/Documentation/ABI/testing/sysfs-bus-dfl-devices-n3000-nios
> > b/Documentation/ABI/testing/sysfs-bus-dfl-devices-n3000-nios
> > new file mode 100644
> > index 000..221d635
> > --- /dev/null
> > +++ b/Documentation/ABI/testing/sysfs-bus-dfl-devices-n3000-nios
> > @@ -0,0 +1,18 @@
> > +What:/sys/bus/dfl/devices/dfl_dev.X/fec_mode
> > +Date:Aug 2020
> > +KernelVersion:5.10
> > +Contact:Xu Yilun 
> > +Description:Read-only. It returns the FEC mode of the ethernet retimer
> > +configured by NIOS firmware. "rs" for Reed Solomon FEC,
> > "kr"
> > +for Fire Code FEC, "no" FOR NO FEC. The FEC mode could be
> > set
> > +by module parameters, but it could only be set once after the
> > +board powers up.
> > +Format: string
> > +
> > +What:/sys/bus/dfl/devices/dfl_dev.X/nios_fw_version
> > +Date:Aug 2020
> > +KernelVersion:5.10
> > +Contact:Xu Yilun 
> > +Description:Read-only. It returns the NIOS firmware version in FPGA. Its
> > +format is "major.minor.patch".
> > +Format: %x.%x.%x
> > diff --git a/Documentation/fpga/dfl-n3000-nios.rst
> > b/Documentation/fpga/dfl-n3000-nios.rst
> > new file mode 100644
> > index 000..c562aab
> > --- /dev/null
> > +++ b/Documentation/fpga/dfl-n3000-nios.rst
> > @@ -0,0 +1,45 @@
> > +.. SPDX-License-Identifier: GPL-2.0
> > +
> > +=
> > +N3000 Nios Private Feature Driver
> > +=
> > +
> > +The N3000 Nios driver supports for the Nios handshake private feature on
> > Intel
> > +PAC (Programmable Acceleration Card) N3000.
> > +
> > +The Nios is the embedded processor on the FPGA card. This private feature
> > +provides a handshake interface to FPGA Nios firmware, which receives the
> > +ethernet retimer configuration command from host and does the
> > configuration via
> > +an internal SPI master (spi-altera). When Nios finishes the configuration,
> > host
> > +takes over the ownership of the SPI master to control an Intel MAX10 BMC
> > (Board
> > +Management Controller) Chip on the SPI bus.
> > +
> > +So the driver does 2 major tasks on probe, uses the Nios firmware to
> > configure
> > +the ethernet retimer, and then creates a spi master platform device with
> > the
> > +MAX10 device info in spi_board_info.
> > +
> > +Module Parameters
> > +=
> > +
> > +The N3000 Nios driver supports the following module parameters:
> > +
> > +* fec_mode: string
> > +  Require the Nios firmware to set the FEC (Forward Error Correction) mode
> > of
> > +  the ethernet retimer on the Intel PAC N3000. The 

[PATCH] regulator: Add support for RT4801 Display Bias regulator driver

2020-08-13 Thread cy_huang
From: ChiYuan Huang 

Adds support for the RT4801 DSV. It has two regulators (DSVP/DSVN) with an I2C
interface. DSVP/DSVN can provide the display panel module for the 
positive/negative
voltage range from (+/-)4V to (+/-)6V.
---
 .../regulator/richtek,rt4801-regulator.yaml|  80 
 drivers/regulator/Kconfig  |   7 +
 drivers/regulator/Makefile |   1 +
 drivers/regulator/rt4801-regulator.c   | 223 +
 4 files changed, 311 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/regulator/richtek,rt4801-regulator.yaml
 create mode 100644 drivers/regulator/rt4801-regulator.c

diff --git 
a/Documentation/devicetree/bindings/regulator/richtek,rt4801-regulator.yaml 
b/Documentation/devicetree/bindings/regulator/richtek,rt4801-regulator.yaml
new file mode 100644
index ..28d30e2
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/richtek,rt4801-regulator.yaml
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/richtek,rt4801-regulator.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT4801 Display Bias regulators
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  Regulator nodes should be named to DSVP and DSVN. The
+  definition for each of these nodes is defined using the standard
+  binding for regulators at
+  Documentation/devicetree/bindings/regulator/regulator.txt.
+  Datasheet is available at
+  https://www.richtek.com/assets/product_file/RT4801H/DS4801H-00.pdf
+
+#The valid names for RT4801 regulator nodes are:
+#DSVP, DSVN
+
+properties:
+  compatible:
+enum:
+  - richtek,rt4801
+
+  reg:
+maxItems: 1
+
+  enable-gpios:
+description: GPIOs to use to enable DSVP/DSVN regulator.
+  The first one is ENP to enable DSVP, and second one is ENM to enable 
DSVN.
+  Number of GPIO in the array list could be 1 or 2.
+  If only one gpio is specified, only one gpio used to control ENP/ENM.
+  Else both are spefied, DSVP/DSVN could be controlled individually.
+  Othersie, this property not specified. treat both as always-on regulator.
+minItems: 1
+maxItems: 2
+
+patternProperties:
+  "^DSV(P|N)$":
+type: object
+$ref: regulator.yaml#
+description:
+  Properties for single display bias regulator.
+
+required:
+  - compatible
+  - reg
+
+additionalProperties:
+  - enable-gpios
+
+examples:
+  - |
+i2c {
+#address-cells = <1>;
+#size-cells = <0>;
+
+rt4801@73 {
+compatible = "richtek,rt4801";
+reg = <0x73>;
+enable-gpios = < 2 0>, < 3 0>;
+
+dsvp: DSVP {
+regulator-name = "rt4801,dsvp";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <600>;
+regulator-boot-on;
+};
+dsvn: DSVN {
+regulator-name = "rt4801,dsvn";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <600>;
+regulator-boot-on;
+};
+
+};
+};
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index de17ef7..2786f11 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -894,6 +894,13 @@ config REGULATOR_RN5T618
 config REGULATOR_ROHM
tristate
 
+config REGULATOR_RT4801
+   tristate "Richtek RT4801 Regulators"
+   depends on I2C
+   help
+ This adds support for voltage regulators in Richtek RT4801 Display 
Bias IC.
+ The device supports two regulators (DSVP/DSVN).
+
 config REGULATOR_RT5033
tristate "Richtek RT5033 Regulators"
depends on MFD_RT5033
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index d8d3ecf..d091e52d 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -111,6 +111,7 @@ obj-$(CONFIG_REGULATOR_RC5T583)  += rc5t583-regulator.o
 obj-$(CONFIG_REGULATOR_RK808)   += rk808-regulator.o
 obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o
 obj-$(CONFIG_REGULATOR_ROHM)   += rohm-regulator.o
+obj-$(CONFIG_REGULATOR_RT4801) += rt4801-regulator.o
 obj-$(CONFIG_REGULATOR_RT5033) += rt5033-regulator.o
 obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
 obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
diff --git a/drivers/regulator/rt4801-regulator.c 
b/drivers/regulator/rt4801-regulator.c
new file mode 100644
index ..0ddc670
--- /dev/null
+++ b/drivers/regulator/rt4801-regulator.c
@@ -0,0 +1,223 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RT4801_REG_VOP 0x00
+#define RT4801_REG_VON 0x01
+#define RT4801_REG_APPS0x03
+
+#define VOUT_MASK  0x1F
+
+#define MIN_UV 400
+#define STEP_UV10
+#define MAX_UV 600

Re: [RFC][PATCH 2/2] dma-heap: Add a system-uncached heap

2020-08-13 Thread John Stultz
On Mon, Aug 3, 2020 at 4:06 AM Robin Murphy  wrote:
>
> On 2020-07-29 06:16, John Stultz wrote:
> > This adds a heap that allocates non-contiguous buffers that are
> > marked as writecombined, so they are not cached by the CPU.
> >
...
> > + ret = sg_alloc_table(new_table, table->nents, GFP_KERNEL);
> > + if (ret) {
> > + kfree(new_table);
> > + return ERR_PTR(-ENOMEM);
> > + }
> > +
> > + new_sg = new_table->sgl;
> > + for_each_sg(table->sgl, sg, table->nents, i) {
>
> Consider using the new sgtable helpers that are just about to land - in
> this case, for_each_sgtable_sg().

Ack! Thanks for the suggestion!


> > + memcpy(new_sg, sg, sizeof(*sg));
> > + new_sg->dma_address = 0;
>
> This seems a little bit hairy, as in theory a consumer could still treat
> a nonzero DMA length as the address being valid. Rather than copying the
> whole entry then trying to undo parts of that, maybe just:
>
> sg_set_page(new_sg, sg_page(sg), sg->len, sg->offset);
>
> ?

Sounds good.


> > +static struct sg_table *dma_heap_map_dma_buf(struct dma_buf_attachment 
> > *attachment,
> > +  enum dma_data_direction 
> > direction)
> > +{
> > + struct dma_heap_attachment *a = attachment->priv;
> > + struct sg_table *table = a->table;
> > +
> > + if (!dma_map_sg_attrs(attachment->dev, table->sgl, table->nents, 
> > direction,
> > +   DMA_ATTR_SKIP_CPU_SYNC | 
> > DMA_ATTR_WRITE_COMBINE))
>
> dma_map_sgtable()
>
> Also, DMA_ATTR_WRITE_COMBINE is meaningless for streaming DMA.
>

Hrm. Ok, my grasp of "streaming" vs "consistent" definitions are maybe
slightly off, since while we are mapping and unmapping buffers, the
point of this heap is that the allocated memory is uncached/coherent,
so we avoid the cache sync overhead on each mapping/unmapping, which I
thought was closer to the "consistent" definition.

But maybe if the mapping and unmapping part is really the key
difference, then ok.

Either way, from my testing, you seem to be right that the
ATTR_WRITE_COMBINE doesn't seem to make any difference in behavior.

> > + pgprot = pgprot_writecombine(PAGE_KERNEL);
> > +
> > + for_each_sg(table->sgl, sg, table->nents, i) {
>
> for_each_sg_page()

Ack.

> > + /*
> > +  * XXX This is hackish. While the buffer will be uncached, we need
> > +  * to initially flush cpu cache, since the the __GFP_ZERO on the
> > +  * allocation means the zeroing was done by the cpu and thus it is 
> > likely
> > +  * cached. Map & flush it out now so we don't get corruption later on.
> > +  *
> > +  * Ideally we could do this without using the heap device as a dummy 
> > dev.
> > +  */
> > + dma_map_sg_attrs(dma_heap_get_dev(heap), table->sgl, table->nents,
> > +  DMA_BIDIRECTIONAL, DMA_ATTR_WRITE_COMBINE);
>
> Again, DMA_ATTR_WRITE_COMBINE is meaningless here.
>
> > + dma_sync_sg_for_device(dma_heap_get_dev(heap), table->sgl, 
> > table->nents,
> > +DMA_BIDIRECTIONAL);
>
> This doesn't do anything that the map hasn't already just done.

Good point!

> > + }
> > + dma_heap_get_dev(heap->heap)->dma_mask = _mask;
> > + dma_set_mask(dma_heap_get_dev(heap->heap), DMA_BIT_MASK(64));
>
> Much as I'd hate to encourage using dma_coerce_mask_and_coherent(), I'm
> not sure this is really any better :/

Sounds fair.

Thanks so much for the review, I really appreciate the feedback!
(Sorry I was a little slow to respond. The merge window has really
been something this cycle.. :P)

I'll get this all integrated and resend the patch here shortly.

thanks
-john


[PATCH v2 3/4] powerpc: Rewrite 4xx flush_cache_instruction() in C

2020-08-13 Thread Christophe Leroy
Nothing prevents flush_cache_instruction() from being writen in C.

Do it to improve readability and maintainability.

This function is very small and isn't called from assembly,
make it static inline in asm/cacheflush.h

Signed-off-by: Christophe Leroy 
---
v2: Written as a static inline instead of adding a new C file for this function 
alone.
---
 arch/powerpc/include/asm/cacheflush.h | 8 
 arch/powerpc/kernel/misc_32.S | 7 +--
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/include/asm/cacheflush.h 
b/arch/powerpc/include/asm/cacheflush.h
index 481877879fec..138e46d8c04e 100644
--- a/arch/powerpc/include/asm/cacheflush.h
+++ b/arch/powerpc/include/asm/cacheflush.h
@@ -98,7 +98,15 @@ static inline void invalidate_dcache_range(unsigned long 
start,
mb();   /* sync */
 }
 
+#ifdef CONFIG_4xx
+static inline void flush_instruction_cache(void)
+{
+   iccci((void *)KERNELBASE);
+   isync();
+}
+#else
 void flush_instruction_cache(void);
+#endif
 
 #include 
 
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 5c074c2ff5b5..1bda207459a8 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -272,12 +272,8 @@ _ASM_NOKPROBE_SYMBOL(real_writeb)
 /*
  * Flush instruction cache.
  */
-#if !defined(CONFIG_PPC_8xx) && !defined(CONFIG_PPC_BOOK3S_32)
+#ifdef CONFIG_FSL_BOOKE
 _GLOBAL(flush_instruction_cache)
-#if defined(CONFIG_4xx)
-   lis r3, KERNELBASE@h
-   iccci   0,r3
-#elif defined(CONFIG_FSL_BOOKE)
 #ifdef CONFIG_E200
mfspr   r3,SPRN_L1CSR0
ori r3,r3,L1CSR0_CFI|L1CSR0_CLFC
@@ -289,7 +285,6 @@ _GLOBAL(flush_instruction_cache)
mfspr   r3,SPRN_L1CSR1
ori r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR
mtspr   SPRN_L1CSR1,r3
-#endif /* CONFIG_4xx */
isync
blr
 EXPORT_SYMBOL(flush_instruction_cache)
-- 
2.25.0



[PATCH v2 1/4] powerpc: Remove flush_instruction_cache for book3s/32

2020-08-13 Thread Christophe Leroy
The only callers of flush_instruction_cache() are:

arch/powerpc/kernel/swsusp_booke.S: bl flush_instruction_cache
arch/powerpc/mm/nohash/40x.c:   flush_instruction_cache();
arch/powerpc/mm/nohash/44x.c:   flush_instruction_cache();
arch/powerpc/mm/nohash/fsl_booke.c: flush_instruction_cache();
arch/powerpc/platforms/44x/machine_check.c: 
flush_instruction_cache();
arch/powerpc/platforms/44x/machine_check.c: 
flush_instruction_cache();

This function is not used by book3s/32, drop it.

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/kernel/misc_32.S | 12 ++--
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index b24f866fef81..5c074c2ff5b5 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -271,9 +271,8 @@ _ASM_NOKPROBE_SYMBOL(real_writeb)
 
 /*
  * Flush instruction cache.
- * This is a no-op on the 601.
  */
-#ifndef CONFIG_PPC_8xx
+#if !defined(CONFIG_PPC_8xx) && !defined(CONFIG_PPC_BOOK3S_32)
 _GLOBAL(flush_instruction_cache)
 #if defined(CONFIG_4xx)
lis r3, KERNELBASE@h
@@ -290,18 +289,11 @@ _GLOBAL(flush_instruction_cache)
mfspr   r3,SPRN_L1CSR1
ori r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR
mtspr   SPRN_L1CSR1,r3
-#elif defined(CONFIG_PPC_BOOK3S_601)
-   blr /* for 601, do nothing */
-#else
-   /* 603/604 processor - use invalidate-all bit in HID0 */
-   mfspr   r3,SPRN_HID0
-   ori r3,r3,HID0_ICFI
-   mtspr   SPRN_HID0,r3
 #endif /* CONFIG_4xx */
isync
blr
 EXPORT_SYMBOL(flush_instruction_cache)
-#endif /* CONFIG_PPC_8xx */
+#endif
 
 /*
  * Copy a whole page.  We use the dcbz instruction on the destination
-- 
2.25.0



[PATCH v2 2/4] powerpc: Move flush_instruction_cache() prototype in asm/cacheflush.h

2020-08-13 Thread Christophe Leroy
flush_instruction_cache() belongs to the cache flushing function
family.

Move its prototype in asm/cacheflush.h

Signed-off-by: Christophe Leroy 
---
v2: new
---
 arch/powerpc/include/asm/cacheflush.h  | 2 ++
 arch/powerpc/include/asm/processor.h   | 1 -
 arch/powerpc/platforms/44x/machine_check.c | 1 +
 3 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/cacheflush.h 
b/arch/powerpc/include/asm/cacheflush.h
index 54764c6e922d..481877879fec 100644
--- a/arch/powerpc/include/asm/cacheflush.h
+++ b/arch/powerpc/include/asm/cacheflush.h
@@ -98,6 +98,8 @@ static inline void invalidate_dcache_range(unsigned long 
start,
mb();   /* sync */
 }
 
+void flush_instruction_cache(void);
+
 #include 
 
 #endif /* _ASM_POWERPC_CACHEFLUSH_H */
diff --git a/arch/powerpc/include/asm/processor.h 
b/arch/powerpc/include/asm/processor.h
index ed0d633ab5aa..d828813e35de 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -435,7 +435,6 @@ extern void power7_idle_type(unsigned long type);
 extern void power9_idle_type(unsigned long stop_psscr_val,
  unsigned long stop_psscr_mask);
 
-extern void flush_instruction_cache(void);
 extern void hard_reset_now(void);
 extern void poweroff_now(void);
 extern int fix_alignment(struct pt_regs *);
diff --git a/arch/powerpc/platforms/44x/machine_check.c 
b/arch/powerpc/platforms/44x/machine_check.c
index 90ad6ac529d2..a5c898bb9bab 100644
--- a/arch/powerpc/platforms/44x/machine_check.c
+++ b/arch/powerpc/platforms/44x/machine_check.c
@@ -7,6 +7,7 @@
 #include 
 
 #include 
+#include 
 
 int machine_check_440A(struct pt_regs *regs)
 {
-- 
2.25.0



[PATCH v2 4/4] powerpc: Rewrite FSL_BOOKE flush_cache_instruction() in C

2020-08-13 Thread Christophe Leroy
Nothing prevents flush_cache_instruction() from being writen in C.

Do it to improve readability and maintainability.

This function is only use by low level callers, it is not
intended to be used by module. Don't export it.

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/kernel/misc_32.S  | 22 --
 arch/powerpc/mm/nohash/fsl_booke.c | 16 
 2 files changed, 16 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 1bda207459a8..87717966f5cd 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -268,28 +268,6 @@ _ASM_NOKPROBE_SYMBOL(real_writeb)
 
 #endif /* CONFIG_40x */
 
-
-/*
- * Flush instruction cache.
- */
-#ifdef CONFIG_FSL_BOOKE
-_GLOBAL(flush_instruction_cache)
-#ifdef CONFIG_E200
-   mfspr   r3,SPRN_L1CSR0
-   ori r3,r3,L1CSR0_CFI|L1CSR0_CLFC
-   /* msync; isync recommended here */
-   mtspr   SPRN_L1CSR0,r3
-   isync
-   blr
-#endif
-   mfspr   r3,SPRN_L1CSR1
-   ori r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR
-   mtspr   SPRN_L1CSR1,r3
-   isync
-   blr
-EXPORT_SYMBOL(flush_instruction_cache)
-#endif
-
 /*
  * Copy a whole page.  We use the dcbz instruction on the destination
  * to reduce memory traffic (it eliminates the unnecessary reads of
diff --git a/arch/powerpc/mm/nohash/fsl_booke.c 
b/arch/powerpc/mm/nohash/fsl_booke.c
index 0c294827d6e5..36bda962d3b3 100644
--- a/arch/powerpc/mm/nohash/fsl_booke.c
+++ b/arch/powerpc/mm/nohash/fsl_booke.c
@@ -219,6 +219,22 @@ unsigned long __init mmu_mapin_ram(unsigned long base, 
unsigned long top)
return tlbcam_addrs[tlbcam_index - 1].limit - PAGE_OFFSET + 1;
 }
 
+void flush_instruction_cache(void)
+{
+   unsigned long tmp;
+
+   if (IS_ENABLED(CONFIG_E200)) {
+   tmp = mfspr(SPRN_L1CSR0);
+   tmp |= L1CSR0_CFI | L1CSR0_CLFC;
+   mtspr(SPRN_L1CSR0, tmp);
+   } else {
+   tmp = mfspr(SPRN_L1CSR1);
+   tmp |= L1CSR1_ICFI | L1CSR1_ICLFR;
+   mtspr(SPRN_L1CSR1, tmp);
+   }
+   isync();
+}
+
 /*
  * MMU_init_hw does the chip-specific initialization of the MMU hardware.
  */
-- 
2.25.0



[PATCH] usb: gadget: f_tcm: Fix some resource leaks in some error paths

2020-08-13 Thread Christophe JAILLET
If a memory allocation fails within a 'usb_ep_alloc_request()' call, the
already allocated memory must be released.

Fix a mix-up in the code and free the correct requests.

Fixes: c52661d60f63 ("usb-gadget: Initial merge of target module for UASP + 
BOT")
Signed-off-by: Christophe JAILLET 
---
 drivers/usb/gadget/function/f_tcm.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/gadget/function/f_tcm.c 
b/drivers/usb/gadget/function/f_tcm.c
index d94b814328c8..184165e27908 100644
--- a/drivers/usb/gadget/function/f_tcm.c
+++ b/drivers/usb/gadget/function/f_tcm.c
@@ -753,12 +753,13 @@ static int uasp_alloc_stream_res(struct f_uas *fu, struct 
uas_stream *stream)
goto err_sts;
 
return 0;
+
 err_sts:
-   usb_ep_free_request(fu->ep_status, stream->req_status);
-   stream->req_status = NULL;
-err_out:
usb_ep_free_request(fu->ep_out, stream->req_out);
stream->req_out = NULL;
+err_out:
+   usb_ep_free_request(fu->ep_in, stream->req_in);
+   stream->req_in = NULL;
 out:
return -ENOMEM;
 }
-- 
2.25.1



Re: [PATCH 1/5] powerpc: Remove flush_instruction_cache for book3s/32

2020-08-13 Thread Christophe Leroy




Le 13/08/2020 à 14:14, Christoph Hellwig a écrit :

On Thu, Aug 13, 2020 at 01:13:08PM +0100, Christoph Hellwig wrote:

On Thu, Aug 13, 2020 at 10:12:00AM +, Christophe Leroy wrote:

-#ifndef CONFIG_PPC_8xx
+#if !defined(CONFIG_PPC_8xx) && !defined(CONFIG_PPC_BOOK3S_32)
  _GLOBAL(flush_instruction_cache)
  #if defined(CONFIG_4xx)
lis r3, KERNELBASE@h
@@ -290,18 +289,11 @@ _GLOBAL(flush_instruction_cache)
mfspr   r3,SPRN_L1CSR1
ori r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR
mtspr   SPRN_L1CSR1,r3
-#elif defined(CONFIG_PPC_BOOK3S_601)
-   blr /* for 601, do nothing */
-#else
-   /* 603/604 processor - use invalidate-all bit in HID0 */
-   mfspr   r3,SPRN_HID0
-   ori r3,r3,HID0_ICFI
-   mtspr   SPRN_HID0,r3
  #endif /* CONFIG_4xx */
isync
blr
  EXPORT_SYMBOL(flush_instruction_cache)
-#endif /* CONFIG_PPC_8xx */
+#endif /* CONFIG_PPC_8xx || CONFIG_PPC_BOOK3S_32 */


What about untangling this into entirely separate versions instead
of the ifdef mess?  Also the export does not seem to be needed at all.


Ok, I see that you do that later, sorry.



In v2, I drop the untangling patch, because the series completely 
dismantles flush_instruction_cache() so there is no need for an 
ephemeral untanggled version of it.


Christophe


Re: [PATCH] perf stat: update POWER9 metrics to utilize other metrics

2020-08-13 Thread kajoljain



On 8/14/20 9:13 AM, Ian Rogers wrote:
> On Thu, Aug 13, 2020 at 3:21 PM Paul A. Clarke  wrote:
>>
>> These changes take advantage of the new capability added in
>> merge commit 00e4db51259a5f936fec1424b884f029479d3981
>> "Allow using computed metrics in calculating other metrics".
>>
>> The net is a simplification of the expressions for a handful
>> of metrics, but no functional change.
>>
>> Signed-off-by: Paul A. Clarke 
> 

Hi Paul,
  The patch looks good to me.

Reviewed-by: Kajol Jain

Thanks,
Kajol Jain

> Acked-by: Ian Rogers 
> (Re-sent with plain text enabled to avoid lkml bounce)
> 
> Thanks,
> Ian
> 
> 
>>
>> ---
>>  .../arch/powerpc/power9/metrics.json  | 48 +--
>>  1 file changed, 24 insertions(+), 24 deletions(-)
>>
>> diff --git a/tools/perf/pmu-events/arch/powerpc/power9/metrics.json 
>> b/tools/perf/pmu-events/arch/powerpc/power9/metrics.json
>> index 80816d6402e9..f8784c608479 100644
>> --- a/tools/perf/pmu-events/arch/powerpc/power9/metrics.json
>> +++ b/tools/perf/pmu-events/arch/powerpc/power9/metrics.json
>> @@ -60,7 +60,7 @@
>>  },
>>  {
>>  "BriefDescription": "Stalls due to short latency decimal floating 
>> ops.",
>> -"MetricExpr": "(PM_CMPLU_STALL_DFU - 
>> PM_CMPLU_STALL_DFLONG)/PM_RUN_INST_CMPL",
>> +"MetricExpr": "dfu_stall_cpi - dflong_stall_cpi",
>>  "MetricGroup": "cpi_breakdown",
>>  "MetricName": "dfu_other_stall_cpi"
>>  },
>> @@ -72,7 +72,7 @@
>>  },
>>  {
>>  "BriefDescription": "Completion stall by Dcache miss which resolved 
>> off node memory/cache",
>> -"MetricExpr": "(PM_CMPLU_STALL_DMISS_L3MISS - 
>> PM_CMPLU_STALL_DMISS_L21_L31 - PM_CMPLU_STALL_DMISS_LMEM - 
>> PM_CMPLU_STALL_DMISS_REMOTE)/PM_RUN_INST_CMPL",
>> +"MetricExpr": "dmiss_non_local_stall_cpi - dmiss_remote_stall_cpi",
>>  "MetricGroup": "cpi_breakdown",
>>  "MetricName": "dmiss_distant_stall_cpi"
>>  },
>> @@ -90,7 +90,7 @@
>>  },
>>  {
>>  "BriefDescription": "Completion stall due to cache miss that 
>> resolves in the L2 or L3 without conflict",
>> -"MetricExpr": "(PM_CMPLU_STALL_DMISS_L2L3 - 
>> PM_CMPLU_STALL_DMISS_L2L3_CONFLICT)/PM_RUN_INST_CMPL",
>> +"MetricExpr": "dmiss_l2l3_stall_cpi - 
>> dmiss_l2l3_conflict_stall_cpi",
>>  "MetricGroup": "cpi_breakdown",
>>  "MetricName": "dmiss_l2l3_noconflict_stall_cpi"
>>  },
>> @@ -114,7 +114,7 @@
>>  },
>>  {
>>  "BriefDescription": "Completion stall by Dcache miss which resolved 
>> outside of local memory",
>> -"MetricExpr": "(PM_CMPLU_STALL_DMISS_L3MISS - 
>> PM_CMPLU_STALL_DMISS_L21_L31 - PM_CMPLU_STALL_DMISS_LMEM)/PM_RUN_INST_CMPL",
>> +"MetricExpr": "dmiss_l3miss_stall_cpi - dmiss_l21_l31_stall_cpi - 
>> dmiss_lmem_stall_cpi",
>>  "MetricGroup": "cpi_breakdown",
>>  "MetricName": "dmiss_non_local_stall_cpi"
>>  },
>> @@ -126,7 +126,7 @@
>>  },
>>  {
>>  "BriefDescription": "Stalls due to short latency double precision 
>> ops.",
>> -"MetricExpr": "(PM_CMPLU_STALL_DP - 
>> PM_CMPLU_STALL_DPLONG)/PM_RUN_INST_CMPL",
>> +"MetricExpr": "dp_stall_cpi - dplong_stall_cpi",
>>  "MetricGroup": "cpi_breakdown",
>>  "MetricName": "dp_other_stall_cpi"
>>  },
>> @@ -155,7 +155,7 @@
>>  "MetricName": "emq_full_stall_cpi"
>>  },
>>  {
>> -"MetricExpr": "(PM_CMPLU_STALL_ERAT_MISS + 
>> PM_CMPLU_STALL_EMQ_FULL)/PM_RUN_INST_CMPL",
>> +"MetricExpr": "erat_miss_stall_cpi + emq_full_stall_cpi",
>>  "MetricGroup": "cpi_breakdown",
>>  "MetricName": "emq_stall_cpi"
>>  },
>> @@ -173,7 +173,7 @@
>>  },
>>  {
>>  "BriefDescription": "Completion stall due to execution units for 
>> other reasons.",
>> -"MetricExpr": "(PM_CMPLU_STALL_EXEC_UNIT - PM_CMPLU_STALL_FXU - 
>> PM_CMPLU_STALL_DP - PM_CMPLU_STALL_DFU - PM_CMPLU_STALL_PM - 
>> PM_CMPLU_STALL_CRYPTO - PM_CMPLU_STALL_VFXU - 
>> PM_CMPLU_STALL_VDP)/PM_RUN_INST_CMPL",
>> +"MetricExpr": "exec_unit_stall_cpi - scalar_stall_cpi - 
>> vector_stall_cpi",
>>  "MetricGroup": "cpi_breakdown",
>>  "MetricName": "exec_unit_other_stall_cpi"
>>  },
>> @@ -197,7 +197,7 @@
>>  },
>>  {
>>  "BriefDescription": "Stalls due to short latency integer ops",
>> -"MetricExpr": "(PM_CMPLU_STALL_FXU - 
>> PM_CMPLU_STALL_FXLONG)/PM_RUN_INST_CMPL",
>> +"MetricExpr": "fxu_stall_cpi - fxlong_stall_cpi",
>>  "MetricGroup": "cpi_breakdown",
>>  "MetricName": "fxu_other_stall_cpi"
>>  },
>> @@ -221,7 +221,7 @@
>>  },
>>  {
>>  "BriefDescription": "Instruction Completion Table other stalls",
>> -"MetricExpr": "(PM_ICT_NOSLOT_CYC - PM_ICT_NOSLOT_IC_MISS - 
>> PM_ICT_NOSLOT_BR_MPRED_ICMISS - PM_ICT_NOSLOT_BR_MPRED - 
>> PM_ICT_NOSLOT_DISP_HELD)/PM_RUN_INST_CMPL",
>> +"MetricExpr": 

Re: [PATCH] kexec: Delete an unnecessary comparison

2020-08-13 Thread Dave Young
On 08/13/20 at 08:45pm, Youling Tang wrote:
> Regardless of whether the ret value is zero or non-zero, the trajectory
> of the program execution is the same, so there is no need to compare.
> 
> Signed-off-by: Youling Tang 
> ---
>  kernel/kexec_file.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
> index 78c0837..3ad0ae2 100644
> --- a/kernel/kexec_file.c
> +++ b/kernel/kexec_file.c
> @@ -800,8 +800,6 @@ static int kexec_calculate_store_digests(struct kimage 
> *image)
>  
>   ret = kexec_purgatory_get_set_symbol(image, 
> "purgatory_sha256_digest",
>digest, 
> SHA256_DIGEST_SIZE, 0);
> - if (ret)
> - goto out_free_digest;
>   }
>  
>  out_free_digest:
> -- 
> 2.1.0
> 

Acked-by: Dave Young 

Thanks
Dave



[PATCH v2] powerpc: Remove flush_instruction_cache() on 8xx

2020-08-13 Thread Christophe Leroy
flush_instruction_cache() is never used on 8xx, remove it.

Signed-off-by: Christophe Leroy 
---
v2: Becomes a standalone patch independant of the series dismantling the ASM 
flush_instruction_cache()
---
 arch/powerpc/mm/nohash/8xx.c | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/arch/powerpc/mm/nohash/8xx.c b/arch/powerpc/mm/nohash/8xx.c
index d2b37146ae6c..231ca95f9ffb 100644
--- a/arch/powerpc/mm/nohash/8xx.c
+++ b/arch/powerpc/mm/nohash/8xx.c
@@ -244,13 +244,6 @@ void set_context(unsigned long id, pgd_t *pgd)
mb();
 }
 
-void flush_instruction_cache(void)
-{
-   isync();
-   mtspr(SPRN_IC_CST, IDC_INVALL);
-   isync();
-}
-
 #ifdef CONFIG_PPC_KUEP
 void __init setup_kuep(bool disabled)
 {
-- 
2.25.0



Re: [PATCH v4 2/2] fcntl: introduce F_SET_DESCRIPTION

2020-08-13 Thread Pascal Bouchareine
On Thu, Aug 13, 2020 at 10:28 PM Christoph Hellwig  wrote:
> > One intended usage is to allow processes to self-document sockets
> > for netstat and friends to report
>
> NAK.  There is no way we're going to bloat a criticial structure like
> struct file for some vanity information like this.

The useful case is for sockets - Is there a more suited place to do that?
Do you think adding a setsockopt and sk_description to struct sock
would work, or would be considered the same?


[PATCH v5 2/2] Add Intel LGM soc DMA support.

2020-08-13 Thread Amireddy Mallikarjuna reddy
Add DMA controller driver for Lightning Mountain(LGM) family of SoCs.

The main function of the DMA controller is the transfer of data from/to any
DPlus compliant peripheral to/from the memory. A memory to memory copy
capability can also be configured.

This ldma driver is used for configure the device and channnels for data
and control paths.

Signed-off-by: Amireddy Mallikarjuna reddy 
---
v1:
- Initial version.

v2:
- Fix device tree bot issues, correspondign driver changes done.
- Fix kerntel test robot warnings.
  
  >> drivers/dma/lgm/lgm-dma.c:729:5: warning: no previous prototype for 
function 'intel_dma_chan_desc_cfg' [-Wmissing-prototypes]
  int intel_dma_chan_desc_cfg(struct dma_chan *chan, dma_addr_t desc_base,
  ^
  drivers/dma/lgm/lgm-dma.c:729:1: note: declare 'static' if the function is 
not intended to be used outside of this translation unit
  int intel_dma_chan_desc_cfg(struct dma_chan *chan, dma_addr_t desc_base,
  ^
  static
  1 warning generated.

  vim +/intel_dma_chan_desc_cfg +729 drivers/dma/lgm/lgm-dma.c

728
  > 729 int intel_dma_chan_desc_cfg(struct dma_chan *chan, dma_addr_t desc_base,
730 int desc_num)
731 {
732 return ldma_chan_desc_cfg(to_ldma_chan(chan), desc_base, 
desc_num);
733 }
734 EXPORT_SYMBOL_GPL(intel_dma_chan_desc_cfg);
735

   Reported-by: kernel test robot 
   ---

v3:
- Fix smatch warning.
  
  smatch warnings:
  drivers/dma/lgm/lgm-dma.c:1306 ldma_cfg_init() error: uninitialized symbol 
'ret'.

  Reported-by: kernel test robot 
  Reported-by: Dan Carpenter 
  

v4:
- Address Thomas Langer comments in dtbinding and corresponding driver side 
changes.
- Driver side changes to corresponding device tree changes.

v5:
- Add changes to read 'dmas' properties and update the config properties driver 
side.
- Add virt_dma_desc utilizes virt-dma API.
---
 drivers/dma/Kconfig |2 +
 drivers/dma/Makefile|1 +
 drivers/dma/lgm/Kconfig |9 +
 drivers/dma/lgm/Makefile|2 +
 drivers/dma/lgm/lgm-dma.c   | 1944 +++
 include/linux/dma/lgm_dma.h |   27 +
 6 files changed, 1985 insertions(+)
 create mode 100644 drivers/dma/lgm/Kconfig
 create mode 100644 drivers/dma/lgm/Makefile
 create mode 100644 drivers/dma/lgm/lgm-dma.c
 create mode 100644 include/linux/dma/lgm_dma.h

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index de41d7928bff..caeaf12fd524 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -737,6 +737,8 @@ source "drivers/dma/ti/Kconfig"
 
 source "drivers/dma/fsl-dpaa2-qdma/Kconfig"
 
+source "drivers/dma/lgm/Kconfig"
+
 # clients
 comment "DMA Clients"
depends on DMA_ENGINE
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index e60f81331d4c..0b899b076f4e 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -83,6 +83,7 @@ obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
 obj-$(CONFIG_ZX_DMA) += zx_dma.o
 obj-$(CONFIG_ST_FDMA) += st_fdma.o
 obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/
+obj-$(CONFIG_INTEL_LDMA) += lgm/
 
 obj-y += mediatek/
 obj-y += qcom/
diff --git a/drivers/dma/lgm/Kconfig b/drivers/dma/lgm/Kconfig
new file mode 100644
index ..bdb5b0d91afb
--- /dev/null
+++ b/drivers/dma/lgm/Kconfig
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config INTEL_LDMA
+   bool "Lightning Mountain centralized low speed DMA and high speed DMA 
controllers"
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ Enable support for intel Lightning Mountain SOC DMA controllers.
+ These controllers provide DMA capabilities for a variety of on-chip
+ devices such as SSC, HSNAND and GSWIP.
diff --git a/drivers/dma/lgm/Makefile b/drivers/dma/lgm/Makefile
new file mode 100644
index ..f318a8eff464
--- /dev/null
+++ b/drivers/dma/lgm/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_INTEL_LDMA)   += lgm-dma.o
diff --git a/drivers/dma/lgm/lgm-dma.c b/drivers/dma/lgm/lgm-dma.c
new file mode 100644
index ..4bd6ef9a2656
--- /dev/null
+++ b/drivers/dma/lgm/lgm-dma.c
@@ -0,0 +1,1944 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Lightning Mountain centralized low speed and high speed DMA controller 
driver
+ *
+ * Copyright (c) 2016 ~ 2020 Intel Corporation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../dmaengine.h"
+#include "../virt-dma.h"
+
+#define DRIVER_NAME"lgm-ldma"
+
+#define DMA_ID 0x0008
+#define DMA_ID_REV GENMASK(7, 0)
+#define DMA_ID_PNR 

Re: [PATCH] dma-debug: fix debug_dma_assert_idle(), use rcu_read_lock()

2020-08-13 Thread Christoph Hellwig
On Thu, Aug 13, 2020 at 12:02:41PM -0700, Linus Torvalds wrote:
> Yeah, that's ridiculously expensive, and serializes things for no good reason.
> 
> Your patch looks obviously correct to me (Christoph?),

It also looks correct to me.

> but it also
> makes me go "why are we doing this in the first place"?
> 
> Because it looks to me like
>  (a) the debug check is wrong
>  (b) this is left-over from early debugging
> 
> In particular, I don't see why we couldn't do a COW on a page that is
> under writeback at the same time. We're not changing the page that is
> doing DMA.

Yes.  We don't need to check for a DMA to the device, but a DMA from
the device while under DMA obviously is bogus.  But then again you'd
need to try really hard to do that.

> In fact, the whole "COW with DMA" makes me feel like the real bug may
> have been due that whole "ambiguous COW" thing, which was fixed in
> 17839856fd58 ("gup: document and work around "COW can break either
> way" issue")
> 
> That debug thing goes back almost 7 years, and I don't think it has
> caught anything in those seven years, but I could be wrong.
> 
> The commit that adds it does talk about a bug, but that code was
> removed entirely eventually. And google shows no hits for
> debug_dma_assert_idle() since - until your email.
> 
> So my gut feel is that we should remove the check entirely, although
> your patch does seem like a big improvement.
> 
> Christoph?

The whole thing predates my involvement with the code, but I defintively
think the patch from Hugh is a major improvement.  But I would also
have no problem with just removing it entirely.


[PATCH v2] media: v4l2-ctrl: add control for long term reference.

2020-08-13 Thread Dikshita Agarwal
LTR (Long Term Reference) frames are the frames that are encoded
sometime in the past and stored in the DPB buffer list to be used
as reference to encode future frames.
This change adds controls to enable this feature.

Signed-off-by: Dikshita Agarwal 
---
 .../userspace-api/media/v4l/ext-ctrls-codec.rst| 23 ++
 drivers/media/v4l2-core/v4l2-ctrls.c   |  6 ++
 include/uapi/linux/v4l2-controls.h |  4 
 3 files changed, 33 insertions(+)

diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst 
b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
index d0d506a..6d1b005 100644
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
@@ -4272,3 +4272,26 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
   - Selecting this value specifies that HEVC slices are expected
 to be prefixed by Annex B start codes. According to :ref:`hevc`
 valid start codes can be 3-bytes 0x01 or 4-bytes 0x0001.
+
+``V4L2_CID_MPEG_VIDEO_LTRCOUNT (enum)``
+   Specifies the number of Long Term Reference frames encoder needs to
+   generate or keep.
+   This control is used to query or configure the number of Long Term
+   Reference frames.
+
+``V4L2_CID_MPEG_VIDEO_MARKLTRFRAME (enum)``
+   This control is used to mark current frame as Long Term Reference
+   frame.
+   this provides a Long Term Reference index that ranges from 0
+   to LTR count-1 and then the particular frame will be marked with that
+   Long Term Reference index.
+
+``V4L2_CID_MPEG_VIDEO_USELTRFRAME (enum)``
+   Specifies the Long Term Reference frame(s) to be used for encoding
+   the current frame.
+   This provides a bitmask which consists of bits [0, 15]. A total of N
+   LSB bits of this field are valid, where N is the maximum number of
+   Long Term Reference frames supported.
+   All the other bits are invalid and should be rejected.
+   The LSB corresponds to the Long Term Reference index 0. Bit N-1 from
+   the LSB corresponds to the Long Term Reference index max LTR count-1.
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c 
b/drivers/media/v4l2-core/v4l2-ctrls.c
index 3f3fbcd..3138c72 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -991,6 +991,9 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS: return "HEVC 
Slice Parameters";
case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE:  return "HEVC 
Decode Mode";
case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE:   return "HEVC 
Start Code";
+   case V4L2_CID_MPEG_VIDEO_LTRCOUNT:  return "LTR Count";
+   case V4L2_CID_MPEG_VIDEO_MARKLTRFRAME:  return "Mark LTR";
+   case V4L2_CID_MPEG_VIDEO_USELTRFRAME:   return "Use LTR";
 
/* CAMERA controls */
/* Keep the order of the 'case's the same as in v4l2-controls.h! */
@@ -1224,6 +1227,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum 
v4l2_ctrl_type *type,
break;
case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE:
case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE:
+   case V4L2_CID_MPEG_VIDEO_LTRCOUNT:
+   case V4L2_CID_MPEG_VIDEO_MARKLTRFRAME:
+   case V4L2_CID_MPEG_VIDEO_USELTRFRAME:
*type = V4L2_CTRL_TYPE_INTEGER;
break;
case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:
diff --git a/include/uapi/linux/v4l2-controls.h 
b/include/uapi/linux/v4l2-controls.h
index 6227141..f2daa86 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -742,6 +742,10 @@ enum v4l2_cid_mpeg_video_hevc_size_of_length_field {
 #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_BR (V4L2_CID_MPEG_BASE + 
642)
 #define V4L2_CID_MPEG_VIDEO_REF_NUMBER_FOR_PFRAMES (V4L2_CID_MPEG_BASE + 
643)
 #define V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR  (V4L2_CID_MPEG_BASE + 
644)
+#define V4L2_CID_MPEG_VIDEO_LTRCOUNT   (V4L2_CID_MPEG_BASE + 645)
+#define V4L2_CID_MPEG_VIDEO_MARKLTRFRAME   (V4L2_CID_MPEG_BASE + 646)
+#define V4L2_CID_MPEG_VIDEO_USELTRFRAME(V4L2_CID_MPEG_BASE + 
647)
+
 
 /*  MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */
 #define V4L2_CID_MPEG_CX2341X_BASE 
(V4L2_CTRL_CLASS_MPEG | 0x1000)
-- 
1.9.1



Re: [PATCH v4 2/2] fcntl: introduce F_SET_DESCRIPTION

2020-08-13 Thread Christoph Hellwig
On Thu, Aug 13, 2020 at 08:54:53PM -0700, Pascal Bouchareine wrote:
> This command attaches a description to a file descriptor for
> troubleshooting purposes. The free string is displayed in the
> process fdinfo file for that fd /proc/pid/fdinfo/fd.
> 
> One intended usage is to allow processes to self-document sockets
> for netstat and friends to report

NAK.  There is no way we're going to bloat a criticial structure like
struct file for some vanity information like this.


[PATCH v5 0/2] Add Intel LGM soc DMA support

2020-08-13 Thread Amireddy Mallikarjuna reddy
Add DMA controller driver for Lightning Mountain(LGM) family of SoCs.

The main function of the DMA controller is the transfer of data from/to any
DPlus compliant peripheral to/from the memory. A memory to memory copy
capability can also be configured.
This ldma driver is used for configure the device and channnels for data
and control paths.

These controllers provide DMA capabilities for a variety of on-chip
devices such as SSC, HSNAND and GSWIP.

-
Future Plans:
-
LGM SOC also supports Hardware Memory Copy engine.
The role of the HW Memory copy engine is to offload memory copy operations
from the CPU.

Amireddy Mallikarjuna reddy (2):
  dt-bindings: dma: Add bindings for intel LGM SOC
  Add Intel LGM soc DMA support.

 .../devicetree/bindings/dma/intel,ldma.yaml|  319 
 drivers/dma/Kconfig|2 +
 drivers/dma/Makefile   |1 +
 drivers/dma/lgm/Kconfig|9 +
 drivers/dma/lgm/Makefile   |2 +
 drivers/dma/lgm/lgm-dma.c  | 1944 
 include/linux/dma/lgm_dma.h|   27 +
 7 files changed, 2304 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/intel,ldma.yaml
 create mode 100644 drivers/dma/lgm/Kconfig
 create mode 100644 drivers/dma/lgm/Makefile
 create mode 100644 drivers/dma/lgm/lgm-dma.c
 create mode 100644 include/linux/dma/lgm_dma.h

-- 
2.11.0



[PATCH v5 1/2] dt-bindings: dma: Add bindings for intel LGM SOC

2020-08-13 Thread Amireddy Mallikarjuna reddy
Add DT bindings YAML schema for DMA controller driver
of Lightning Mountain(LGM) SoC.

Signed-off-by: Amireddy Mallikarjuna reddy 
---
v1:
- Initial version.

v2:
- Fix bot errors.

v3:
- No change.

v4:
- Address Thomas langer comments
  - use node name pattern as dma-controller as in common binding.
  - Remove "_" (underscore) in instance name.
  - Remove "port-" and "chan-" in attribute name for both 'dma-ports' & 
'dma-channels' child nodes.

v5:
- Moved some of the attributes in 'dma-ports' & 'dma-channels' child nodes to 
dma client/consumer side as cells in 'dmas' properties.
---
 .../devicetree/bindings/dma/intel,ldma.yaml| 319 +
 1 file changed, 319 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/intel,ldma.yaml

diff --git a/Documentation/devicetree/bindings/dma/intel,ldma.yaml 
b/Documentation/devicetree/bindings/dma/intel,ldma.yaml
new file mode 100644
index ..9beaf191a6de
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/intel,ldma.yaml
@@ -0,0 +1,319 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/intel,ldma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Lightning Mountain centralized low speed DMA and high speed DMA 
controllers.
+
+maintainers:
+  - chuanhua@intel.com
+  - mallikarjunax.re...@intel.com
+
+allOf:
+  - $ref: "dma-controller.yaml#"
+
+properties:
+ $nodename:
+   pattern: "^dma-controller(@.*)?$"
+
+ "#dma-cells":
+   const: 1
+
+ compatible:
+  anyOf:
+   - const: intel,lgm-cdma
+   - const: intel,lgm-dma2tx
+   - const: intel,lgm-dma1rx
+   - const: intel,lgm-dma1tx
+   - const: intel,lgm-dma0tx
+   - const: intel,lgm-dma3
+   - const: intel,lgm-toe-dma30
+   - const: intel,lgm-toe-dma31
+
+ reg:
+  maxItems: 1
+
+ clocks:
+  maxItems: 1
+
+ resets:
+  maxItems: 1
+
+ interrupts:
+  maxItems: 1
+
+ intel,dma-poll-cnt:
+   $ref: /schemas/types.yaml#definitions/uint32
+   description:
+ DMA descriptor polling counter. It may need fine tune according
+ to the system application scenario.
+
+ intel,dma-byte-en:
+   type: boolean
+   description:
+ DMA byte enable is only valid for DMA write(RX).
+ Byte enable(1) means DMA write will be based on the number of dwords
+ instead of the whole burst.
+
+ intel,dma-drb:
+type: boolean
+description:
+  DMA descriptor read back to make sure data and desc synchronization.
+
+ intel,dma-burst:
+$ref: /schemas/types.yaml#definitions/uint32
+description:
+   Specifiy the DMA burst size(in dwords), the valid value will be 8, 16, 
32.
+   Default is 16 for data path dma, 32 is for memcopy DMA.
+
+ intel,dma-polling-cnt:
+$ref: /schemas/types.yaml#definitions/uint32
+description:
+   DMA descriptor polling counter. It may need fine tune according to
+   the system application scenario.
+
+ intel,dma-desc-in-sram:
+type: boolean
+description:
+   DMA descritpors in SRAM or not. Some old controllers descriptors
+   can be in DRAM or SRAM. The new ones are all in SRAM.
+
+ intel,dma-orrc:
+$ref: /schemas/types.yaml#definitions/uint32
+description:
+   DMA outstanding read counter. The maximum value is 16, and it may
+   need fine tune according to the system application scenarios.
+
+ intel,dma-dburst-wr:
+type: boolean
+description:
+   Enable RX dynamic burst write. It only applies to RX DMA and memcopy 
DMA.
+
+
+ dma-ports:
+type: object
+description:
+   This sub-node must contain a sub-node for each DMA port.
+properties:
+  '#address-cells':
+const: 1
+  '#size-cells':
+const: 0
+
+patternProperties:
+  "^dma-ports@[0-9]+$":
+  type: object
+
+  properties:
+reg:
+  items:
+- enum: [0, 1, 2, 3, 4, 5]
+  description:
+ Which port this node refers to.
+
+intel,name:
+  $ref: /schemas/types.yaml#definitions/string-array
+  description:
+ Port name of each DMA port.
+
+intel,chans:
+  $ref: /schemas/types.yaml#/definitions/uint32-array
+  description:
+ The channels included on this port. Format is channel start
+ number and how many channels on this port.
+
+  required:
+- reg
+- intel,name
+- intel,chans
+
+
+ ldma-channels:
+type: object
+description:
+   This sub-node must contain a sub-node for each DMA channel.
+properties:
+  '#address-cells':
+const: 1
+  '#size-cells':
+const: 0
+
+patternProperties:
+  "^ldma-channels@[0-15]+$":
+  type: object
+
+  properties:
+reg:
+  items:
+- enum: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
+  description:

Re: [RFC PATCH 00/16] Core scheduling v6(Internet mail)

2020-08-13 Thread Li, Aubrey
On 2020/8/14 12:04, benbjiang(蒋彪) wrote:
> 
> 
>> On Aug 14, 2020, at 9:36 AM, Li, Aubrey  wrote:
>>
>> On 2020/8/14 8:26, benbjiang(蒋彪) wrote:
>>>
>>>
 On Aug 13, 2020, at 12:28 PM, Li, Aubrey  wrote:

 On 2020/8/13 7:08, Joel Fernandes wrote:
> On Wed, Aug 12, 2020 at 10:01:24AM +0800, Li, Aubrey wrote:
>> Hi Joel,
>>
>> On 2020/8/10 0:44, Joel Fernandes wrote:
>>> Hi Aubrey,
>>>
>>> Apologies for replying late as I was still looking into the details.
>>>
>>> On Wed, Aug 05, 2020 at 11:57:20AM +0800, Li, Aubrey wrote:
>>> [...]
 +/*
 + * Core scheduling policy:
 + * - CORE_SCHED_DISABLED: core scheduling is disabled.
 + * - CORE_COOKIE_MATCH: tasks with same cookie can run
 + * on the same core concurrently.
 + * - CORE_COOKIE_TRUST: trusted task can run with kernel
thread on the same core concurrently. 
 + * - CORE_COOKIE_LONELY: tasks with cookie can run only
 + * with idle thread on the same core.
 + */
 +enum coresched_policy {
 +   CORE_SCHED_DISABLED,
 +   CORE_SCHED_COOKIE_MATCH,
 +  CORE_SCHED_COOKIE_TRUST,
 +   CORE_SCHED_COOKIE_LONELY,
 +};

 We can set policy to CORE_COOKIE_TRUST of uperf cgroup and fix this 
 kind
 of performance regression. Not sure if this sounds attractive?
>>>
>>> Instead of this, I think it can be something simpler IMHO:
>>>
>>> 1. Consider all cookie-0 task as trusted. (Even right now, if you apply 
>>> the
>>>  core-scheduling patchset, such tasks will share a core and sniff on 
>>> each
>>>  other. So let us not pretend that such tasks are not trusted).
>>>
>>> 2. All kernel threads and idle task would have a cookie 0 (so that will 
>>> cover
>>>  ksoftirqd reported in your original issue).
>>>
>>> 3. Add a config option (CONFIG_SCHED_CORE_DEFAULT_TASKS_UNTRUSTED). 
>>> Default
>>>  enable it. Setting this option would tag all tasks that are forked 
>>> from a
>>>  cookie-0 task with their own cookie. Later on, such tasks can be added 
>>> to
>>>  a group. This cover's PeterZ's ask about having 'default untrusted').
>>>  (Users like ChromeOS that don't want to userspace system processes to 
>>> be
>>>  tagged can disable this option so such tasks will be cookie-0).
>>>
>>> 4. Allow prctl/cgroup interfaces to create groups of tasks and override 
>>> the
>>>  above behaviors.
>>
>> How does uperf in a cgroup work with ksoftirqd? Are you suggesting I set 
>> uperf's
>> cookie to be cookie-0 via prctl?
>
> Yes, but let me try to understand better. There are 2 problems here I 
> think:
>
> 1. ksoftirqd getting idled when HT is turned on, because uperf is sharing 
> a
> core with it: This should not be any worse than SMT OFF, because even SMT 
> OFF
> would also reduce ksoftirqd's CPU time just core sched is doing. Sure
> core-scheduling adds some overhead with IPIs but such a huge drop of perf 
> is
> strange. Peter any thoughts on that?
>
> 2. Interface: To solve the performance problem, you are saying you want 
> uperf
> to share a core with ksoftirqd so that it is not forced into idle.  Why 
> not
> just keep uperf out of the cgroup?

 I guess this is unacceptable for who runs their apps in container and vm.
>>> IMHO,  just as Joel proposed, 
>>> 1. Consider all cookie-0 task as trusted.
>>> 2. All kernel threads and idle task would have a cookie 0 
>>> In that way, all tasks with cookies(including uperf in a cgroup) could run
>>> concurrently with kernel threads.
>>> That could be a good solution for the issue. :)
>>
>> From uperf point of review, it can trust cookie-0(I assume we still need
>> some modifications to change cookie-match to cookie-compatible to allow
>> ZERO and NONZERO run together).
>>
>> But from kernel thread point of review, it can NOT trust uperf, unless
>> we set uperf's cookie to 0.
> That’s right. :)
> Could we set the cookie of cgroup where uperf lies to 0?
> 
IMHO the disadvantage is that if there are two or more cgroups set cookie-0,
then the user applications in these cgroups could run concurrently on a core,
though all of them are set as trusted, we made a hole of user->user isolation.

Thanks,
-Aubrey


[PATCH] xhci: Do not use GFP_KERNEL in (potentially) atomic context

2020-08-13 Thread Christophe JAILLET
'xhci_urb_enqueue()' is passed a 'mem_flags' argument, because "URBs may be
submitted in interrupt context" (see comment related to 'usb_submit_urb()'
in 'drivers/usb/core/urb.c')

So this flag should be used in all the calling chain.
Up to now, 'xhci_check_maxpacket()' which is only called from
'xhci_urb_enqueue()', uses GFP_KERNEL.

Be safe and pass the mem_flags to this function as well.

Fixes: ddba5cd0aeff ("xhci: Use command structures when queuing commands on the 
command ring")
Signed-off-by: Christophe JAILLET 
---
I'm not 100% sure of the Fixes tag. The commit is the only that introduced
this GFP_KERNEL, but I've not checked what was the behavior before that.

If the patch is correct, I guess that a cc stable should be welcome.
---
 drivers/usb/host/xhci.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 3c41b14ecce7..b536f18e4cfd 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1382,7 +1382,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,
  * we need to issue an evaluate context command and wait on it.
  */
 static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id,
-   unsigned int ep_index, struct urb *urb)
+   unsigned int ep_index, struct urb *urb, gfp_t mem_flags)
 {
struct xhci_container_ctx *out_ctx;
struct xhci_input_control_ctx *ctrl_ctx;
@@ -1413,7 +1413,7 @@ static int xhci_check_maxpacket(struct xhci_hcd *xhci, 
unsigned int slot_id,
 * changes max packet sizes.
 */
 
-   command = xhci_alloc_command(xhci, true, GFP_KERNEL);
+   command = xhci_alloc_command(xhci, true, mem_flags);
if (!command)
return -ENOMEM;
 
@@ -1509,7 +1509,7 @@ static int xhci_urb_enqueue(struct usb_hcd *hcd, struct 
urb *urb, gfp_t mem_flag
 */
if (urb->dev->speed == USB_SPEED_FULL) {
ret = xhci_check_maxpacket(xhci, slot_id,
-   ep_index, urb);
+   ep_index, urb, mem_flags);
if (ret < 0) {
xhci_urb_free_priv(urb_priv);
urb->hcpriv = NULL;
-- 
2.25.1



Re: [PATCH] soc: qcom: socinfo: add SC7180 entry to soc_id array

2020-08-13 Thread Sai Prakash Ranjan

On 2020-08-13 20:33, Douglas Anderson wrote:

Add an entry for SC7180 SoC.

Signed-off-by: Douglas Anderson 
---

 drivers/soc/qcom/socinfo.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
index e19102f46302..e56eea29615c 100644
--- a/drivers/soc/qcom/socinfo.c
+++ b/drivers/soc/qcom/socinfo.c
@@ -223,6 +223,7 @@ static const struct soc_id soc_id[] = {
{ 321, "SDM845" },
{ 341, "SDA845" },
{ 356, "SM8250" },
+   { 425, "SC7180" },
 };

 static const char *socinfo_machine(struct device *dev, unsigned int 
id)


From the chipinfo document that I have at hand, this is correct soc id 
for SC7180, so


Reviewed-by: Sai Prakash Ranjan 


Thanks,
Sai

--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a 
member

of Code Aurora Forum, hosted by The Linux Foundation


[PATCH v2] softirq: add irq off checking for __raise_softirq_irqoff

2020-08-13 Thread Jiafei Pan
__raise_softirq_irqoff() will update per-CPU mask of pending softirqs,
it need to be called in irq disabled context in order to keep it atomic
operation, otherwise it will be interrupted by hardware interrupt,
and per-CPU softirqs pending mask will be corrupted, the result is
there will be unexpected issue, for example hrtimer soft irq will
be losed and soft hrtimer will never be expire and handled.

Enable CONFIG_PROVE_LOCKING to use lockdep_assert_irqs_disabled() to
check hardirqs and softirqs status, and provide warning in irqs enabled
context.

Signed-off-by: Jiafei Pan 
---
Changes in v2:
- use lockdep_assert_irqs_disabled()
- removed extra comments
- changed commit message

 kernel/softirq.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/kernel/softirq.c b/kernel/softirq.c
index bf88d7f62433..09229ad82209 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -481,6 +481,7 @@ void raise_softirq(unsigned int nr)
 
 void __raise_softirq_irqoff(unsigned int nr)
 {
+   lockdep_assert_irqs_disabled();
trace_softirq_raise(nr);
or_softirq_pending(1UL << nr);
 }
-- 
2.17.1



[GIT PULL] Kconfig updates for v5.9-rc1

2020-08-13 Thread Masahiro Yamada
Hi Linus,

Please pull Kconfig updates for v5.9-rc1

Thanks.



The following changes since commit bcf876870b95592b52519ed4aafcf9d95999bc9c:

  Linux 5.8 (2020-08-02 14:21:45 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild.git
tags/kconfig-v5.9

for you to fetch changes up to d4bbe8a1b55aeaadfa0fa982b468eaec9b799f1a:

  kconfig: qconf: move setOptionMode() to ConfigList from ConfigView
(2020-08-14 13:47:21 +0900)


Kconfig updates for v5.9

 - remove '---help---' keyword support

 - fix mouse events for 'menuconfig' symbols in search view of qconf

 - code cleanups of qconf


Masahiro Yamada (23):
  kconfig: remove '---help---' support
  Revert "checkpatch: kconfig: prefer 'help' over '---help---'"
  kconfig: constify XPM data
  kconfig: add 'static' to some file-local data
  kconfig: qconf: remove ->addSeparator() to menuBar
  kconfig: qconf: do not use 'menu' variable for (QMenuBar *)
  kconfig: qconf: use 'menu' variable for (QMenu *)
  kconfig: qconf: remove toolBar from ConfigMainWindow members
  kconfig: qconf: overload addToolBar() to create and insert toolbar
  kconfig: qconf: remove unused ConfigList::listView()
  kconfig: qconf: remove name from ConfigSearchWindow constructor
  kconfig: qconf: omit parent to QHBoxLayout()
  kconfig: qconf: remove unused argument from ConfigList::updateList()
  kconfig: qconf: remove unused argument from ConfigView::updateList()
  kconfig: qconf: remove 'parent' from ConfigList::updateMenuList()
  kconfig: qconf: drop more localization code
  kconfig: qconf: remove ConfigItem::pixmap/setPixmap
  kconfig: qconf: remove ConfigList::addColumn/removeColumn
  kconfig: qconf: remove ConfigItem::text/setText
  kconfig: qconf: remove unused voidPix, menuInvPix
  kconfig: qconf: refactor icon setups
  kconfig: qconf: do not limit the pop-up menu to the first row
  kconfig: qconf: move setOptionMode() to ConfigList from ConfigView

Maxime Chretien (1):
  kconfig: qconf: Fix mouse events in search view

 scripts/checkkconfigsymbols.py |   2 +-
 scripts/checkpatch.pl  |   6 +-
 scripts/kconfig/images.c   |  30 +++
 scripts/kconfig/images.h   |  30 +++
 scripts/kconfig/lexer.l|   4 +-
 scripts/kconfig/qconf.cc   | 319
++--
 scripts/kconfig/qconf.h|  56 +++-
 scripts/kconfig/symbol.c   |  14 ++-
 8 files changed, 218 insertions(+), 243 deletions(-)

-- 
Best Regards
Masahiro Yamada


[PATCH] ALSA: hda/realtek: Add quirk for Samsung Galaxy Flex Book

2020-08-13 Thread Mike Pozulp
The Flex Book uses the same ALC298 codec as other Samsung laptops which
have the no headphone sound bug, like my Samsung Notebook. The Flex Book
owner used Early Patching to confirm that this quirk fixes the bug.

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=207423
Signed-off-by: Mike Pozulp 
---
 sound/pci/hda/patch_realtek.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 2477f3ed7237..449ea64919ec 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -7688,6 +7688,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", 
ALC269_FIXUP_INV_DMIC),
SND_PCI_QUIRK(0x144d, 0xc169, "Samsung Notebook 9 Pen 
(NP930SBE-K01US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
SND_PCI_QUIRK(0x144d, 0xc176, "Samsung Notebook 9 Pro 
(NP930MBE-K04US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
+   SND_PCI_QUIRK(0x144d, 0xc189, "Samsung Galaxy Flex Book 
(NT950QCG-X716)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", 
ALC269_FIXUP_ATIV_BOOK_8),
SND_PCI_QUIRK(0x144d, 0xc812, "Samsung Notebook Pen S (NT950SBE-X58)", 
ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", 
ALC283_FIXUP_HEADSET_MIC),
-- 
2.26.2



Re: [PATCH v5 3/6] ov5670: Support probe whilst the device is in a low power state

2020-08-13 Thread Bingbu Cao



On 8/12/20 5:12 PM, Bingbu Cao wrote:
> 
> 
> On 8/10/20 10:27 PM, Sakari Ailus wrote:
>> Tell ACPI device PM code that the driver supports the device being in a
>> low power state when the driver's probe function is entered.
>>
>> Signed-off-by: Sakari Ailus 
>> ---
>>  drivers/media/i2c/ov5670.c | 23 ++-
>>  1 file changed, 14 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c
>> index f26252e35e08d..1f75b888d2a18 100644
>> --- a/drivers/media/i2c/ov5670.c
>> +++ b/drivers/media/i2c/ov5670.c
>> @@ -2456,6 +2456,7 @@ static int ov5670_probe(struct i2c_client *client)
>>  struct ov5670 *ov5670;
>>  const char *err_msg;
>>  u32 input_clk = 0;
>> +bool low_power;
>>  int ret;
>>  
>>  device_property_read_u32(>dev, "clock-frequency", _clk);
>> @@ -2472,11 +2473,14 @@ static int ov5670_probe(struct i2c_client *client)
>>  /* Initialize subdev */
>>  v4l2_i2c_subdev_init(>sd, client, _subdev_ops);
>>  
>> -/* Check module identity */
>> -ret = ov5670_identify_module(ov5670);
>> -if (ret) {
>> -err_msg = "ov5670_identify_module() error";
>> -goto error_print;
>> +low_power = acpi_dev_state_low_power(>dev);
>> +if (!low_power) {
>> +/* Check module identity */
>> +ret = ov5670_identify_module(ov5670);
>> +if (ret) {
>> +err_msg = "ov5670_identify_module() error";
>> +goto error_print;
>> +
> 
> Sakari, thanks for your patch.
> one question - With this change, there will be no chance for driver to 
> guarantee
> that the camera sensor plugged in is the camera that the matched driver 
> actually
> can drive until try to streaming the camera, so is it necessary to return
> appropriate error in .s_stream ops to notify user it is not the hardware that
> current driver can drive? if no other better way.

Sakari, please ignore my previous comment, it is not related to this change. I
see the sub device open is caused by v4l_id program from udev.

> 

-- 
Best regards,
Bingbu Cao


Re: [PATCH] arm64: Add KRYO4XX gold CPU core to spectre-v2 safe list

2020-08-13 Thread Sai Prakash Ranjan

On 2020-08-13 23:29, Marc Zyngier wrote:

On 2020-08-13 13:33, Sai Prakash Ranjan wrote:

On 2020-08-13 16:09, Marc Zyngier wrote:

On 2020-08-13 10:40, Will Deacon wrote:

On Thu, Aug 13, 2020 at 02:49:37PM +0530, Sai Prakash Ranjan wrote:

On 2020-08-13 14:33, Will Deacon wrote:
> On Thu, Aug 13, 2020 at 01:48:34PM +0530, Sai Prakash Ranjan wrote:
> > KRYO4XX gold/big CPU cores are based on Cortex-A76 which has CSV2
> > bits set and are spectre-v2 safe. But on big.LITTLE systems where
> > they are coupled with other CPU cores such as the KRYO4XX silver
> > based on Cortex-A55 which are spectre-v2 safe but do not have CSV2
> > bits set, the system wide safe value will be set to the lowest value
> > of CSV2 bits as per FTR_LOWER_SAFE defined for CSV2 bits of register
> > ID_AA64PFR0_EL1.
> >
> > This is a problem when booting a guest kernel on gold CPU cores
> > where it will incorrectly report ARM_SMCCC_ARCH_WORKAROUND_1 warning
> > and consider them as vulnerable for Spectre variant 2 due to system
> > wide safe value which is used in kvm emulation code when reading id
> > registers. One wrong way of fixing this is to set the FTR_HIGHER_SAFE
> > for CSV2 bits, so instead add the KRYO4XX gold CPU core to the safe
> > list which will be consulted even when the sanitised read reports
> > that CSV2 bits are not set for KRYO4XX gold cores.
> >
> > Reported-by: Stephen Boyd 
> > Signed-off-by: Sai Prakash Ranjan 
> > ---
> >  arch/arm64/kernel/cpu_errata.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/arch/arm64/kernel/cpu_errata.c
> > b/arch/arm64/kernel/cpu_errata.c
> > index 6bd1d3ad037a..6cbdd2d98a2a 100644
> > --- a/arch/arm64/kernel/cpu_errata.c
> > +++ b/arch/arm64/kernel/cpu_errata.c
> > @@ -545,6 +545,7 @@ static const struct midr_range
> > spectre_v2_safe_list[] = {
> >   MIDR_ALL_VERSIONS(MIDR_HISI_TSV110),
> >   MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_3XX_SILVER),
> >   MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_SILVER),
> > + MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_GOLD),
>
> We shouldn't be putting CPUs in the safe list when they have CSV2
> reporting
> that they are mitigated in hardware, so I don't think this is the right
> approach.
>

Ok but the only thing I find wrong in this approach is that it is a
redundant
information because CSV2 is already advertising the mitigation, but 
again
CSV2 check is done first so it doesn't really hurt to add it to the 
safe

list because we already know that it is safe.


It simply doesn't scale. That's why CSV2 exists in the first place, 
so we

don't have to modify the kernel everytime a new CPU is invented.


> Sounds more like KVM should advertise CSV2 for the vCPUs if all of the
> physical CPUs without CSV2 set are on the safe list. But then again, KVM
> has always been slightly in denial about big.LITTLE because you can't
> sensibly expose it to a guest if there are detectable differences...
>

Sorry but I don't see how the guest kernel will see the CSV2 bits 
set for
gold CPU cores without actually adding them to the safe list or 
reading the

not sanitised value of ID_AA64PFR0_EL1 ?


Well that's for somebody to figure out in the patch. I'm just saying 
that
adding cores to the safe list when they already have a CSV2 field 
conveying
the same information is the wrong approach. The right appproach is 
for KVM
to expose CSV2 as set when the system is not affected by the 
erratum.


A sensible way to fix this would be with something like that:

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 077293b5115f..2735db21ff0d 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1131,6 +1131,9 @@ static u64 read_id_reg(const struct kvm_vcpu 
*vcpu,

if (!vcpu_has_sve(vcpu))
val &= ~(0xfUL << ID_AA64PFR0_SVE_SHIFT);
val &= ~(0xfUL << ID_AA64PFR0_AMU_SHIFT);
+   if (!(val & (0xfUL << ID_AA64PFR0_CSV2_SHIFT)) &&
+		get_spectre_v2_workaround_state() == 
ARM64_BP_HARDEN_NOT_REQUIRED)

+   val |= (1UL << ID_AA64PFR0_CSV2_SHIFT);
} else if (id == SYS_ID_AA64ISAR1_EL1 && !vcpu_has_ptrauth(vcpu)) {
val &= ~((0xfUL << ID_AA64ISAR1_APA_SHIFT) |
 (0xfUL << ID_AA64ISAR1_API_SHIFT) |



Thanks Marc, I gave this a go on SC7180 where the issue was seen and
this fix is good.

Tested-by: Sai Prakash Ranjan 


There is still a problem with this approach. A late CPU could
come up after a guest has been started. If that CPU identified
as vulnerable by the host kernel, get_spectre_v2_workaround_state()
will return a different value, breaking the guest (or more
likely, leaving it exposed to Spectre-v2 attacks).

We'd need to disable the late onlining of CPUs that would change
the mitigation state, and this is... ugly.



Ugh, yes indeed and here I was thinking that these things are 
straightforward :(


Thanks,
Sai

--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is 

Re: net/tipc/udp_media.c:743: undefined reference to `ipv6_dev_find'

2020-08-13 Thread Randy Dunlap
On 8/13/20 2:35 AM, Xin Long wrote:
> On Wed, Aug 12, 2020 at 7:21 AM kernel test robot  wrote:
>>
>> tree:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 
>> master
>> head:   c636eef2ee3696f261a35f34989842701a107895
>> commit: 5a6f6f579178dbeb33002d93b4f646c31348fac9 tipc: set ub->ifindex for 
>> local ipv6 address
>> date:   6 days ago
>> config: ia64-randconfig-r005-20200811 (attached as .config)
>> compiler: ia64-linux-gcc (GCC) 9.3.0
>> reproduce (this is a W=1 build):
>> wget 
>> https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
>> ~/bin/make.cross
>> chmod +x ~/bin/make.cross
>> git checkout 5a6f6f579178dbeb33002d93b4f646c31348fac9
>> # save the attached .config to linux build tree
>> COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross 
>> ARCH=ia64
>>
>> If you fix the issue, kindly add following tag as appropriate
>> Reported-by: kernel test robot 
>>
>> All errors (new ones prefixed by >>):
>>
>>ia64-linux-ld: net/tipc/udp_media.o: in function `tipc_udp_enable':
 net/tipc/udp_media.c:743: undefined reference to `ipv6_dev_find'
> To use some APIs exported from ipv6 code.
> We need add this:
> 
> --- a/net/tipc/Kconfig
> +++ b/net/tipc/Kconfig
> @@ -6,6 +6,7 @@
>  menuconfig TIPC
> tristate "The TIPC Protocol"
> depends on INET
> +   depends on IPV6 || IPV6=n
> 

Thanks. Works for me.

Acked-by: Randy Dunlap  # build-tested

Please make a proper patch and send it to the maintainers.
-- 
~Randy


RE: [EXT] Re: [PATCH] softirq: add irq off checking for __raise_softirq_irqoff

2020-08-13 Thread Jiafei Pan
> From: Steven Rostedt 
> Sent: Thursday, August 13, 2020 10:57 PM
> 
> On Thu, 13 Aug 2020 03:03:46 +
> Jiafei Pan  wrote:
> 
> > Any comments? Thanks.
> >
> > @Steven Rostedt, I thinks irq off checking is necessary especially
> 
> This is probably more for Thomas Gleixner.
> 
> > for Preempt-RT kernel, because some context may be changed from irq
> > off to irq on when enable Preempt RT, I once met a issue that hrtimer
> > soft irq is lost when enabled Preempt RT, finally I found
> > napi_schedule_irqoff is called in hardware interrupt handler, there
> > maybe no issue for non RT kernel, but for Preempt RT, interrupt is
> > threaded, so irq is on in interrupt handler, the result is
> > __raise_softirq_irqoff is called in irq on context, so that per-CPU
> > softirq masking is corrupted because of the process of updating of
> > soft irq masking is interrupted and not a atomic operation , and then
> > caused hrtimer soft irq is lost. So I think adding irq status checking
> > in __raise_softirq_irqoff can report such issue directly and help us
> > to find the root cause of such issue.
> >
> > I know that there may be performance impaction to add extra checking
> > here, if it is the case, how about to include it in some debug
> > configuration items? Such as CONFIG_DEBUG_PREEMPT or other debug
> > items?
> >
> 
> 
> > Best Regards,
> > Jiafei.
> >
> > -Original Message-
> > From: Jiafei Pan 
> > Sent: Thursday, August 6, 2020 12:07 PM
> > To: pet...@infradead.org; mi...@kernel.org; t...@linutronix.de;
> > rost...@goodmis.org; romain.per...@gmail.com; w...@kernel.org
> > Cc: linux-kernel@vger.kernel.org; linux-rt-us...@vger.kernel.org;
> > Jiafei Pan ; Leo Li ; Vladimir
> > Oltean ; Jiafei Pan 
> > Subject: [PATCH] softirq: add irq off checking for
> > __raise_softirq_irqoff
> >
> > __raise_softirq_irqoff will update per-CPU mask of pending softirqs, it need
> to be called in irq disabled context in order to keep it atomic operation,
> otherwise it will be interrupted by hardware interrupt, and per-CPU softirqs
> pending mask will be corrupted, the result is there will be unexpected issue,
> for example hrtimer soft irq will be losed and soft hrtimer will never be 
> expire
> and handled.
> 
> Please wrap your change logs.
[Jiafei Pan] Thanks, will update it.
> 
> >
> > Adding irqs disabled checking here to provide warning in irqs enabled
> context.
> >
> > Signed-off-by: Jiafei Pan 
> > ---
> >  kernel/softirq.c | 5 +
> >  1 file changed, 5 insertions(+)
> >
> > diff --git a/kernel/softirq.c b/kernel/softirq.c index
> > bf88d7f62433..11f61e54a3ae 100644
> > --- a/kernel/softirq.c
> > +++ b/kernel/softirq.c
> > @@ -481,6 +481,11 @@ void raise_softirq(unsigned int nr)
> >
> >  void __raise_softirq_irqoff(unsigned int nr)  {
> > + /* This function can only be called in irq disabled context,
> > +  * otherwise or_softirq_pending will be interrupted by hardware
> > +  * interrupt, so that there will be unexpected issue.
> > +  */
> > + WARN_ON_ONCE(!irqs_disabled());
> 
> Perhaps: lockdep_assert_irqs_disabled() is more appropriate, and doesn't add
> extra overhead on production systems.
> 
> -- Steve
[Jiafei Pan] Thanks, will update it.
> 
> 
> >   trace_softirq_raise(nr);
> >   or_softirq_pending(1UL << nr);
> >  }
> > --
> > 2.17.1



Re: [PATCH v5 0/6] Support running driver's probe for a device powered off

2020-08-13 Thread Bingbu Cao



On 8/10/20 10:27 PM, Sakari Ailus wrote:
> Hi all,
> 
...snip...
> 
> The use case is such that there is a privacy LED next to an integrated
> user-facing laptop camera, and this LED is there to signal the user that
> the camera is recording a video or capturing images. That LED also happens
> to be wired to one of the power supplies of the camera, so whenever you
> power on the camera, the LED will be lit, whether images are captured from
> the camera --- or not. There's no way to implement this differently
> without additional software control (allowing of which is itself a
> hardware design decision) on most CSI-2-connected camera sensors as they
> simply have no pin to signal the camera streaming state.
> 
> This is also what happens during driver probe: the camera will be powered
> on by the I²C subsystem calling dev_pm_domain_attach() and the device is
> already powered on when the driver's own probe function is called. To the
> user this visible during the boot process as a blink of the privacy LED,
> suggesting that the camera is recording without the user having used an
> application to do that. From the end user's point of view the behaviour is
> not expected and for someone unfamiliar with internal workings of a
> computer surely seems quite suspicious --- even if images are not being
> actually captured.
> 
> I've tested these on linux-next master. They also apply to Wolfram's
> i2c/for-next branch, there's a patch that affects the I²C core changes
> here (see below). The patches apart from that apply to Bartosz's
> at24/for-next as well as Mauro's linux-media master branch.

Sakari, we meet one issue - once the vcm sub-device registered, the user space
will try to open the VCM (I have not figure out who did that), it will also
trigger the acpi pm resume/suspend, as the VCM always shares same power rail
with camera sensor, so the privacy LED still has a blink.

> 
...snip...
-- 
Best regards,
Bingbu Cao


[PATCH v2] seqlock: Fix build errors

2020-08-13 Thread Xingxing Su
Fix the following build errors:

In file included from ./include/linux/time.h:6:0,
 from ./include/linux/compat.h:10,
 from arch/mips/kernel/asm-offsets.c:12:
./include/linux/seqlock.h: In function ???write_seqcount_begin_nested???:
./include/linux/seqlock.h:286:2: error: implicit declaration of function 
 ???raw_smp_processor_id??? [-Werror=implicit-function-declaration]
  lockdep_assert_preemption_disabled();
  ^
./arch/mips/include/asm/smp.h: At top level:
./arch/mips/include/asm/smp.h:28:19: error: static declaration of 
 ???raw_smp_processor_id??? follows non-static declaration
 static inline int raw_smp_processor_id(void)
 ^
cc1: some warnings being treated as errors
scripts/Makefile.build:117: recipe for target 'arch/mips/kernel/asm-offsets.s' 
failed
make[1]: *** [arch/mips/kernel/asm-offsets.s] Error 1
arch/mips/Makefile:396: recipe for target 'archprepare' failed
make: *** [archprepare] Error 2


Signed-off-by: Xingxing Su 
---
 v2:  update the commit message

 include/linux/seqlock.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h
index 54bc204..4763c13 100644
--- a/include/linux/seqlock.h
+++ b/include/linux/seqlock.h
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /*
-- 
2.1.0



Re: [RFC PATCH 00/16] Core scheduling v6(Internet mail)

2020-08-13 Thread 蒋彪


> On Aug 14, 2020, at 9:36 AM, Li, Aubrey  wrote:
> 
> On 2020/8/14 8:26, benbjiang(蒋彪) wrote:
>> 
>> 
>>> On Aug 13, 2020, at 12:28 PM, Li, Aubrey  wrote:
>>> 
>>> On 2020/8/13 7:08, Joel Fernandes wrote:
 On Wed, Aug 12, 2020 at 10:01:24AM +0800, Li, Aubrey wrote:
> Hi Joel,
> 
> On 2020/8/10 0:44, Joel Fernandes wrote:
>> Hi Aubrey,
>> 
>> Apologies for replying late as I was still looking into the details.
>> 
>> On Wed, Aug 05, 2020 at 11:57:20AM +0800, Li, Aubrey wrote:
>> [...]
>>> +/*
>>> + * Core scheduling policy:
>>> + * - CORE_SCHED_DISABLED: core scheduling is disabled.
>>> + * - CORE_COOKIE_MATCH: tasks with same cookie can run
>>> + * on the same core concurrently.
>>> + * - CORE_COOKIE_TRUST: trusted task can run with kernel
>>> thread on the same core concurrently. 
>>> + * - CORE_COOKIE_LONELY: tasks with cookie can run only
>>> + * with idle thread on the same core.
>>> + */
>>> +enum coresched_policy {
>>> +   CORE_SCHED_DISABLED,
>>> +   CORE_SCHED_COOKIE_MATCH,
>>> +   CORE_SCHED_COOKIE_TRUST,
>>> +   CORE_SCHED_COOKIE_LONELY,
>>> +};
>>> 
>>> We can set policy to CORE_COOKIE_TRUST of uperf cgroup and fix this kind
>>> of performance regression. Not sure if this sounds attractive?
>> 
>> Instead of this, I think it can be something simpler IMHO:
>> 
>> 1. Consider all cookie-0 task as trusted. (Even right now, if you apply 
>> the
>>  core-scheduling patchset, such tasks will share a core and sniff on each
>>  other. So let us not pretend that such tasks are not trusted).
>> 
>> 2. All kernel threads and idle task would have a cookie 0 (so that will 
>> cover
>>  ksoftirqd reported in your original issue).
>> 
>> 3. Add a config option (CONFIG_SCHED_CORE_DEFAULT_TASKS_UNTRUSTED). 
>> Default
>>  enable it. Setting this option would tag all tasks that are forked from 
>> a
>>  cookie-0 task with their own cookie. Later on, such tasks can be added 
>> to
>>  a group. This cover's PeterZ's ask about having 'default untrusted').
>>  (Users like ChromeOS that don't want to userspace system processes to be
>>  tagged can disable this option so such tasks will be cookie-0).
>> 
>> 4. Allow prctl/cgroup interfaces to create groups of tasks and override 
>> the
>>  above behaviors.
> 
> How does uperf in a cgroup work with ksoftirqd? Are you suggesting I set 
> uperf's
> cookie to be cookie-0 via prctl?
 
 Yes, but let me try to understand better. There are 2 problems here I 
 think:
 
 1. ksoftirqd getting idled when HT is turned on, because uperf is sharing a
 core with it: This should not be any worse than SMT OFF, because even SMT 
 OFF
 would also reduce ksoftirqd's CPU time just core sched is doing. Sure
 core-scheduling adds some overhead with IPIs but such a huge drop of perf 
 is
 strange. Peter any thoughts on that?
 
 2. Interface: To solve the performance problem, you are saying you want 
 uperf
 to share a core with ksoftirqd so that it is not forced into idle.  Why not
 just keep uperf out of the cgroup?
>>> 
>>> I guess this is unacceptable for who runs their apps in container and vm.
>> IMHO,  just as Joel proposed, 
>> 1. Consider all cookie-0 task as trusted.
>> 2. All kernel threads and idle task would have a cookie 0 
>> In that way, all tasks with cookies(including uperf in a cgroup) could run
>> concurrently with kernel threads.
>> That could be a good solution for the issue. :)
> 
> From uperf point of review, it can trust cookie-0(I assume we still need
> some modifications to change cookie-match to cookie-compatible to allow
> ZERO and NONZERO run together).
> 
> But from kernel thread point of review, it can NOT trust uperf, unless
> we set uperf's cookie to 0.
That’s right. :)
Could we set the cookie of cgroup where uperf lies to 0?

Thx.
Regards,
Jiang

> 
> Thanks,
> -Aubrey
> 



[PATCH v4 1/2] mm: add GFP mask param to strndup_user

2020-08-13 Thread Pascal Bouchareine
Let caller specify allocation.
Keep the existing calls with GFP_USER, and enforce the existing
defense against log spam from userspace with __GFP_NOWARN.

Signed-off-by: Pascal Bouchareine 
---
 drivers/dma-buf/dma-buf.c  |  2 +-
 drivers/gpu/drm/i915/i915_debugfs_params.c |  2 +-
 drivers/gpu/drm/vc4/vc4_bo.c   |  3 +-
 drivers/input/misc/uinput.c|  2 +-
 drivers/s390/char/keyboard.c   |  3 +-
 drivers/vfio/vfio.c|  3 +-
 drivers/virt/fsl_hypervisor.c  |  4 +--
 fs/f2fs/file.c |  3 +-
 fs/fsopen.c|  6 ++--
 fs/namespace.c |  2 +-
 fs/nfs/fs_context.c|  8 +++--
 fs/xfs/xfs_ioctl.c |  2 +-
 include/linux/string.h |  2 +-
 kernel/events/core.c   |  2 +-
 kernel/module.c|  2 +-
 kernel/trace/trace_event_perf.c|  2 +-
 mm/util.c  | 34 +-
 net/core/pktgen.c  |  2 +-
 security/keys/dh.c |  3 +-
 security/keys/keyctl.c | 17 +++
 security/keys/keyctl_pkey.c|  2 +-
 21 files changed, 63 insertions(+), 43 deletions(-)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 1ca609f66fdf..3d94ba811f4b 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -326,7 +326,7 @@ static __poll_t dma_buf_poll(struct file *file, poll_table 
*poll)
  */
 static long dma_buf_set_name(struct dma_buf *dmabuf, const char __user *buf)
 {
-   char *name = strndup_user(buf, DMA_BUF_NAME_LEN);
+   char *name = strndup_user(buf, DMA_BUF_NAME_LEN, GFP_USER);
long ret = 0;
 
if (IS_ERR(name))
diff --git a/drivers/gpu/drm/i915/i915_debugfs_params.c 
b/drivers/gpu/drm/i915/i915_debugfs_params.c
index 62b2c5f0495d..4c0a77e15c09 100644
--- a/drivers/gpu/drm/i915/i915_debugfs_params.c
+++ b/drivers/gpu/drm/i915/i915_debugfs_params.c
@@ -142,7 +142,7 @@ static ssize_t i915_param_charp_write(struct file *file,
kernel_param_lock(THIS_MODULE);
 
old = *s;
-   new = strndup_user(ubuf, PAGE_SIZE);
+   new = strndup_user(ubuf, PAGE_SIZE, GFP_USER);
if (IS_ERR(new)) {
len = PTR_ERR(new);
goto out;
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 72d30d90b856..deb2c4957a6f 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -1072,7 +1072,8 @@ int vc4_label_bo_ioctl(struct drm_device *dev, void *data,
if (!args->len)
return -EINVAL;
 
-   name = strndup_user(u64_to_user_ptr(args->name), args->len + 1);
+   name = strndup_user(u64_to_user_ptr(args->name), args->len + 1,
+   GFP_USER);
if (IS_ERR(name))
return PTR_ERR(name);
 
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index f2593133e524..11627a4b4d87 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -926,7 +926,7 @@ static long uinput_ioctl_handler(struct file *file, 
unsigned int cmd,
goto out;
}
 
-   phys = strndup_user(p, 1024);
+   phys = strndup_user(p, 1024, GFP_USER);
if (IS_ERR(phys)) {
retval = PTR_ERR(phys);
goto out;
diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c
index 567aedc03c76..8e58921d5db4 100644
--- a/drivers/s390/char/keyboard.c
+++ b/drivers/s390/char/keyboard.c
@@ -464,7 +464,8 @@ do_kdgkb_ioctl(struct kbd_data *kbd, struct kbsentry __user 
*u_kbs,
case KDSKBSENT:
if (!perm)
return -EPERM;
-   p = strndup_user(u_kbs->kb_string, sizeof(u_kbs->kb_string));
+   p = strndup_user(u_kbs->kb_string,
+   sizeof(u_kbs->kb_string), GFP_USER);
if (IS_ERR(p))
return PTR_ERR(p);
kfree(kbd->func_table[kb_func]);
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index 580099afeaff..d55aae6661eb 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -1547,7 +1547,8 @@ static long vfio_group_fops_unl_ioctl(struct file *filep,
{
char *buf;
 
-   buf = strndup_user((const char __user *)arg, PAGE_SIZE);
+   buf = strndup_user((const char __user *)arg, PAGE_SIZE,
+   GFP_USER);
if (IS_ERR(buf))
return PTR_ERR(buf);
 
diff --git a/drivers/virt/fsl_hypervisor.c b/drivers/virt/fsl_hypervisor.c
index 1b0b11b55d2a..142c74aab2b0 100644
--- a/drivers/virt/fsl_hypervisor.c
+++ b/drivers/virt/fsl_hypervisor.c
@@ -346,11 

[PATCH v4 0/2] proc,fcntl: introduce F_SET_DESCRIPTION

2020-08-13 Thread Pascal Bouchareine
This is a first attempt at taking Alexey's comments into account

This goes against v5.8

tl;dr in commit 2/2 but motivation is also described a bit in
https://lore.kernel.org/linux-api/CAGbU3_nVvuzMn2wo4_ZKufWcGfmGsopVujzTWw-Bbeky=xs...@mail.gmail.com/




[PATCH v4 2/2] fcntl: introduce F_SET_DESCRIPTION

2020-08-13 Thread Pascal Bouchareine
This command attaches a description to a file descriptor for
troubleshooting purposes. The free string is displayed in the
process fdinfo file for that fd /proc/pid/fdinfo/fd.

One intended usage is to allow processes to self-document sockets
for netstat and friends to report

Signed-off-by: Pascal Bouchareine 
---
 fs/fcntl.c | 21 +
 fs/file_table.c|  2 ++
 fs/proc/fd.c   |  5 +
 include/linux/fs.h |  3 +++
 include/uapi/linux/fcntl.h |  5 +
 5 files changed, 36 insertions(+)

diff --git a/fs/fcntl.c b/fs/fcntl.c
index 2e4c0fa2074b..9fbeaaf02802 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -319,6 +319,24 @@ static long fcntl_rw_hint(struct file *file, unsigned int 
cmd,
}
 }
 
+static long fcntl_set_description(struct file *file, char __user *desc)
+{
+   char *d, *old;
+
+   d = strndup_user(desc, MAX_FILE_DESC_SIZE, GFP_KERNEL_ACCOUNT);
+   if (IS_ERR(d))
+   return PTR_ERR(d);
+
+   spin_lock(>f_lock);
+   old = file->f_description;
+   file->f_description = d;
+   spin_unlock(>f_lock);
+
+   kfree(old);
+
+   return 0;
+}
+
 static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
struct file *filp)
 {
@@ -426,6 +444,9 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned 
long arg,
case F_SET_FILE_RW_HINT:
err = fcntl_rw_hint(filp, cmd, arg);
break;
+   case F_SET_DESCRIPTION:
+   err = fcntl_set_description(filp, argp);
+   break;
default:
break;
}
diff --git a/fs/file_table.c b/fs/file_table.c
index 656647f9575a..6673a48d2ea1 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -272,6 +272,8 @@ static void __fput(struct file *file)
eventpoll_release(file);
locks_remove_file(file);
 
+   kfree(file->f_description);
+
ima_file_free(file);
if (unlikely(file->f_flags & FASYNC)) {
if (file->f_op->fasync)
diff --git a/fs/proc/fd.c b/fs/proc/fd.c
index 81882a13212d..60b3ff971b2b 100644
--- a/fs/proc/fd.c
+++ b/fs/proc/fd.c
@@ -57,6 +57,11 @@ static int seq_show(struct seq_file *m, void *v)
   (long long)file->f_pos, f_flags,
   real_mount(file->f_path.mnt)->mnt_id);
 
+   spin_lock(>f_lock);
+   if (file->f_description)
+   seq_printf(m, "desc:\t%s\n", file->f_description);
+   spin_unlock(>f_lock);
+
show_fd_locks(m, file, files);
if (seq_has_overflowed(m))
goto out;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index f5abba86107d..a2a683d603b6 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -980,6 +980,9 @@ struct file {
struct address_space*f_mapping;
errseq_tf_wb_err;
errseq_tf_sb_err; /* for syncfs */
+
+#define MAX_FILE_DESC_SIZE 256
+   char*f_description;
 } __randomize_layout
   __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */
 
diff --git a/include/uapi/linux/fcntl.h b/include/uapi/linux/fcntl.h
index 2f86b2ad6d7e..465385e52f49 100644
--- a/include/uapi/linux/fcntl.h
+++ b/include/uapi/linux/fcntl.h
@@ -55,6 +55,11 @@
 #define F_GET_FILE_RW_HINT (F_LINUX_SPECIFIC_BASE + 13)
 #define F_SET_FILE_RW_HINT (F_LINUX_SPECIFIC_BASE + 14)
 
+/*
+ * Set file description
+ */
+#define F_SET_DESCRIPTION  (F_LINUX_SPECIFIC_BASE + 15)
+
 /*
  * Valid hint values for F_{GET,SET}_RW_HINT. 0 is "not set", or can be
  * used to clear any hints previously set.
-- 
2.25.1



[PATCH v8 2/4] power: supply: core: add wireless charger adapter type property

2020-08-13 Thread Qiwu Huang
From: Qiwu Huang 

Reports what type of wireless adapter connection is
currently active for the supply.
for example it can show if ADAPTER_PD capable source is attached.

Signed-off-by: Qiwu Huang 
---
 Documentation/ABI/testing/sysfs-class-power | 28 +
 drivers/power/supply/power_supply_sysfs.c   |  1 +
 include/linux/power_supply.h| 19 ++
 3 files changed, 48 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-class-power 
b/Documentation/ABI/testing/sysfs-class-power
index dd3773dcf16a..03ab449fae8a 100644
--- a/Documentation/ABI/testing/sysfs-class-power
+++ b/Documentation/ABI/testing/sysfs-class-power
@@ -729,3 +729,31 @@ Contact:   Fei Jiang 
3: QUICK_CHARGE_TURBE,
4: QUICK_CHARGE_SUPER.
 
+= Wireless Charger Properties =
+What:  /sys/class/power_supply//tx_adapter
+Date:  Jul 2020
+Contact:   Fei Jiang 
+Description:
+   Reports the type of wireless adapter connection is currently 
active for
+   the supply, for example it can show if ADAPTER_PD capable source
+   is attached. Expect common wireless adapter type, also increase 
by
+   some vendor private adapter type(ex. ADAPTER_PD_40W).
+
+   Access: Read-Only
+   Valid values:
+   0: ADAPTER_NONE,
+   1: ADAPTER_SDP,
+   2: ADAPTER_DCP,
+   3: ADAPTER_CDP,
+   4: ADAPTER_OCP,
+   5: ADAPTER_QC2,
+   6: ADAPTER_QC3,
+   7: ADAPTER_PD,
+   8: ADAPTER_AUTH_FAILED,
+   9: ADAPTER_PRIVATE_QC3,
+   10: ADAPTER_PRIVATE_PD,
+   11: ADAPTER_CAR_POWER,
+   12: ADAPTER_PRIVATE_PD_40W,
+   13: ADAPTER_VOICE_BOX,
+   14: ADAPTER_PRIVATE_PD_50W.
+
diff --git a/drivers/power/supply/power_supply_sysfs.c 
b/drivers/power/supply/power_supply_sysfs.c
index 9554d7907373..f2458e21d02b 100644
--- a/drivers/power/supply/power_supply_sysfs.c
+++ b/drivers/power/supply/power_supply_sysfs.c
@@ -207,6 +207,7 @@ static struct power_supply_attr power_supply_attrs[] = {
POWER_SUPPLY_ATTR(MANUFACTURER),
POWER_SUPPLY_ATTR(SERIAL_NUMBER),
POWER_SUPPLY_ATTR(QUICK_CHARGE_TYPE),
+   POWER_SUPPLY_ATTR(TX_ADAPTER),
 };
 
 static struct attribute *
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index bd99658c05be..00254e096a4a 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -168,6 +168,7 @@ enum power_supply_property {
POWER_SUPPLY_PROP_MANUFACTURER,
POWER_SUPPLY_PROP_SERIAL_NUMBER,
POWER_SUPPLY_PROP_QUICK_CHARGE_TYPE,
+   POWER_SUPPLY_PROP_TX_ADAPTER,
 };
 
 enum power_supply_type {
@@ -211,6 +212,24 @@ enum power_supply_quick_charge_type {
QUICK_CHARGE_MAX,
 };
 
+enum power_supply_tx_adapter_type {
+   ADAPTER_NONE = 0,   /* Nothing Attached */
+   ADAPTER_SDP,/* Standard Downstream Port */
+   ADAPTER_CDP,/* Charging Downstream Port */
+   ADAPTER_DCP,/* Dedicated Charging Port */
+   ADAPTER_OCP,/* Other Charging Port */
+   ADAPTER_QC2,/* Qualcomm Charge 2.0 */
+   ADAPTER_QC3,/* Qualcomm Charge 3.0 */
+   ADAPTER_PD, /* Power Delivery Port */
+   ADAPTER_AUTH_FAILED,/* Authenticated Failed Adapter 
*/
+   ADAPTER_PRIVATE_QC3,/* Qualcomm Charge 3.0 with 
Private Protocol */
+   ADAPTER_PRIVATE_PD, /* PD Adapter with Private 
Protocol */
+   ADAPTER_CAR_POWER,  /* Wireless Car Charger */
+   ADAPTER_PRIVATE_PD_40W, /* 40W PD Adapter with Private 
Protocol */
+   ADAPTER_VOICE_BOX,  /* Voice Box which Support 
Wireless Charger */
+   ADAPTER_PRIVATE_PD_50W, /* 50W PD Adapter with Private 
Protocol */
+};
+
 enum power_supply_notifier_events {
PSY_EVENT_PROP_CHANGED,
 };
-- 
2.28.0



[PATCH v8 4/4] power: supply: core: property to control reverse charge

2020-08-13 Thread Qiwu Huang
From: Qiwu Huang 

Interface to control wireless reverse charge.

Signed-off-by: Qiwu Huang 
---
 Documentation/ABI/testing/sysfs-class-power | 14 ++
 drivers/power/supply/power_supply_sysfs.c   |  1 +
 include/linux/power_supply.h|  1 +
 3 files changed, 16 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-class-power 
b/Documentation/ABI/testing/sysfs-class-power
index 4459b720feb2..8840fdf483a7 100644
--- a/Documentation/ABI/testing/sysfs-class-power
+++ b/Documentation/ABI/testing/sysfs-class-power
@@ -779,3 +779,17 @@ Description:
 
Access: Read-Only
Valid values: 0 - 100
+
+What:  /sys/class/power_supply//reverse_chg_mode
+Date:  Jul 2020
+Contact:   Fei Jiang 
+Description:
+   Some devices support wireless reverse charge function which
+   charge other devices.The property provider interface to
+   enable/disable wireless reverse charge.If enabled, start TX
+   mode and detect RX. Disabled when timeout or manual setting.
+
+   Access: Read, Write
+   Valid values:
+   - 1: enabled
+   - 0: disabled
diff --git a/drivers/power/supply/power_supply_sysfs.c 
b/drivers/power/supply/power_supply_sysfs.c
index e420a453095e..81916b6b6ccf 100644
--- a/drivers/power/supply/power_supply_sysfs.c
+++ b/drivers/power/supply/power_supply_sysfs.c
@@ -209,6 +209,7 @@ static struct power_supply_attr power_supply_attrs[] = {
POWER_SUPPLY_ATTR(QUICK_CHARGE_TYPE),
POWER_SUPPLY_ATTR(TX_ADAPTER),
POWER_SUPPLY_ATTR(SIGNAL_STRENGTH),
+   POWER_SUPPLY_ATTR(REVERSE_CHG_MODE),
 };
 
 static struct attribute *
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 747338118fa1..988d3f05ea1c 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -170,6 +170,7 @@ enum power_supply_property {
POWER_SUPPLY_PROP_QUICK_CHARGE_TYPE,
POWER_SUPPLY_PROP_TX_ADAPTER,
POWER_SUPPLY_PROP_SIGNAL_STRENGTH,
+   POWER_SUPPLY_PROP_REVERSE_CHG_MODE,
 };
 
 enum power_supply_type {
-- 
2.28.0



[PATCH v8 3/4] power: supply: core: add wireless signal strength property

2020-08-13 Thread Qiwu Huang
From: Qiwu Huang 

reports wireless signal strength.
The value show degree of coupling between tx and rx.

Signed-off-by: Qiwu Huang 
---
 Documentation/ABI/testing/sysfs-class-power | 22 +
 drivers/power/supply/power_supply_sysfs.c   |  1 +
 include/linux/power_supply.h|  1 +
 3 files changed, 24 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-class-power 
b/Documentation/ABI/testing/sysfs-class-power
index 03ab449fae8a..4459b720feb2 100644
--- a/Documentation/ABI/testing/sysfs-class-power
+++ b/Documentation/ABI/testing/sysfs-class-power
@@ -757,3 +757,25 @@ Description:
13: ADAPTER_VOICE_BOX,
14: ADAPTER_PRIVATE_PD_50W.
 
+What:  /sys/class/power_supply//signal_strength
+Date:  Jul 2020
+Contact:   Fei Jiang 
+Description:
+   In PING phase, RX transmits a signal strength packet as the
+   first communication packet to instruct the base to keep power
+   signal on.The value reports wireless signal strength and show
+   degree of coupling.
+
+   The Qi Wireless Power Transfer System is published by the
+   Wireless Power Consortium.The ping phase is the necessary stage
+   for matching transmitter and receiver. In this phase,the Power
+   Transmitter executes a Digital Ping, and listens for a response.
+   If the Power Transmitter discovers a Power Receiver, the Power
+   Transmitter may extend the Digital Ping,i.e. maintain the Power
+   Signal at the level of the Digital Ping. This causes the system
+   to proceed to the identification & configuration phase. If the
+   Power Transmitter does not extend the Digital Ping, the system
+   shall revert to the selection phase.
+
+   Access: Read-Only
+   Valid values: 0 - 100
diff --git a/drivers/power/supply/power_supply_sysfs.c 
b/drivers/power/supply/power_supply_sysfs.c
index f2458e21d02b..e420a453095e 100644
--- a/drivers/power/supply/power_supply_sysfs.c
+++ b/drivers/power/supply/power_supply_sysfs.c
@@ -208,6 +208,7 @@ static struct power_supply_attr power_supply_attrs[] = {
POWER_SUPPLY_ATTR(SERIAL_NUMBER),
POWER_SUPPLY_ATTR(QUICK_CHARGE_TYPE),
POWER_SUPPLY_ATTR(TX_ADAPTER),
+   POWER_SUPPLY_ATTR(SIGNAL_STRENGTH),
 };
 
 static struct attribute *
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 00254e096a4a..747338118fa1 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -169,6 +169,7 @@ enum power_supply_property {
POWER_SUPPLY_PROP_SERIAL_NUMBER,
POWER_SUPPLY_PROP_QUICK_CHARGE_TYPE,
POWER_SUPPLY_PROP_TX_ADAPTER,
+   POWER_SUPPLY_PROP_SIGNAL_STRENGTH,
 };
 
 enum power_supply_type {
-- 
2.28.0



[PATCH v8 0/4] add some power supply properties about wireless/wired charging

2020-08-13 Thread Qiwu Huang
From: Qiwu Huang 

This patchset aims to provide power supply properties about wireless/wired 
charging.
"quick_charge_type" reports different types of quick charge based on the 
charging power;
"tx_adapter" shows" the type of wireless charging adapter;
"signal_strength" shows the coupling level between TX and RX;
"reverse_chg_mode" provides the interface of enabling/disabling wireless 
reverse charging.

Changes in v8
 - Add quick charge type driver in qcom_smbb suggested by GregKH

Changes in v7
 - Fix PATCH version error in 0/X email

Changes in v6
 - Replace "phones" with "devices" suggested by GregKH
 - Add permission statement for "reverse_chg_mode"
 - Update description for "reverse_chg_mode" in ABI suggested by GregKH
 - Update description for "PING phase" in ABI suggested by GregKH

Changes in v5
 - Add details in 0/X email

Changes in v4
 - Exclude the patch of "power: supply: supply battery soc with decimal form"
 - Fix some typo

Changes in v3
 - Add enumederated for quick charge type
 - Add enumederated for tx adapter type
 - Update the return type and description in ABI

Changes in v2
 - modify to capital letters for "power_supply_attrs"
 - Update the return type and description in ABI
Qiwu Huang (4):
  power: supply: core: add quick charge type property
  power: supply: core: add wireless charger adapter type property
  power: supply: core: add wireless signal strength property
  power: supply: core: property to control reverse charge

 Documentation/ABI/testing/sysfs-class-power | 85 +
 drivers/power/supply/power_supply_sysfs.c   |  4 +
 drivers/power/supply/qcom_smbb.c| 51 +
 include/linux/power_supply.h| 35 +
 4 files changed, 175 insertions(+)

-- 
2.28.0



[PATCH v8 1/4] power: supply: core: add quick charge type property

2020-08-13 Thread Qiwu Huang
From: Qiwu Huang 

Reports the kind of quick charge type based on
different adapter power.

Signed-off-by: Qiwu Huang 
---
 Documentation/ABI/testing/sysfs-class-power | 21 +
 drivers/power/supply/power_supply_sysfs.c   |  1 +
 drivers/power/supply/qcom_smbb.c| 51 +
 include/linux/power_supply.h| 14 ++
 4 files changed, 87 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-class-power 
b/Documentation/ABI/testing/sysfs-class-power
index 216d61a22f1e..dd3773dcf16a 100644
--- a/Documentation/ABI/testing/sysfs-class-power
+++ b/Documentation/ABI/testing/sysfs-class-power
@@ -708,3 +708,24 @@ Description:
 
Access: Read
Valid values: 1-31
+
+What:  /sys/class/power_supply//quick_charge_type
+Date:  Jul 2020
+Contact:   Fei Jiang 
+   Description:
+   Reports the kind of quick charge type based on different 
adapter power.
+   Different quick charge type represent different charging power.
+   QUICK_CHARGE_NORMAL : Charging Power <= 10W
+   QUICK_CHARGE_FAST : 10W < Charging Power <= 20W
+   QUICK_CHARGE_FLASH : 20W < Charging Power <= 30W
+   QUICK_CHARGE_TURBE : 30W < Charging Power <= 50W
+   QUICK_CHARGE_SUPER : Charging Power > 50W
+
+   Access: Read-Only
+   Valid values:
+   0: QUICK_CHARGE_NORMAL,
+   1: QUICK_CHARGE_FAST,
+   2: QUICK_CHARGE_FLASH,
+   3: QUICK_CHARGE_TURBE,
+   4: QUICK_CHARGE_SUPER.
+
diff --git a/drivers/power/supply/power_supply_sysfs.c 
b/drivers/power/supply/power_supply_sysfs.c
index bc79560229b5..9554d7907373 100644
--- a/drivers/power/supply/power_supply_sysfs.c
+++ b/drivers/power/supply/power_supply_sysfs.c
@@ -206,6 +206,7 @@ static struct power_supply_attr power_supply_attrs[] = {
POWER_SUPPLY_ATTR(MODEL_NAME),
POWER_SUPPLY_ATTR(MANUFACTURER),
POWER_SUPPLY_ATTR(SERIAL_NUMBER),
+   POWER_SUPPLY_ATTR(QUICK_CHARGE_TYPE),
 };
 
 static struct attribute *
diff --git a/drivers/power/supply/qcom_smbb.c b/drivers/power/supply/qcom_smbb.c
index c890e1cec720..afd38cf38832 100644
--- a/drivers/power/supply/qcom_smbb.c
+++ b/drivers/power/supply/qcom_smbb.c
@@ -485,6 +485,53 @@ static const struct smbb_irq {
{ "dc-valid", smbb_dc_valid_handler },
 };
 
+struct quick_charge {
+   enum power_supply_type adap_type;
+   enum power_supply_quick_charge_type adap_cap;
+};
+
+static struct quick_charge adapter_cap[10] = {
+   { POWER_SUPPLY_TYPE_USB,QUICK_CHARGE_NORMAL },
+   { POWER_SUPPLY_TYPE_USB_DCP,QUICK_CHARGE_NORMAL },
+   { POWER_SUPPLY_TYPE_USB_CDP,QUICK_CHARGE_NORMAL },
+   { POWER_SUPPLY_TYPE_USB_ACA,QUICK_CHARGE_NORMAL },
+   { POWER_SUPPLY_TYPE_USB_FLOAT,  QUICK_CHARGE_NORMAL },
+   { POWER_SUPPLY_TYPE_USB_PD, QUICK_CHARGE_FAST },
+   { POWER_SUPPLY_TYPE_USB_HVDCP,  QUICK_CHARGE_FAST },
+   { POWER_SUPPLY_TYPE_USB_HVDCP_3,QUICK_CHARGE_FAST },
+   { POWER_SUPPLY_TYPE_USB_HVDCP_3P5,  QUICK_CHARGE_FAST },
+   {0, 0},
+};
+
+static int get_quick_charge_type(struct smbb_charger *chg)
+{
+   union power_supply_propval prop = {0, };
+   int charger_type, rc;
+   int i = 0;
+
+   rc = power_supply_get_property(chg->bat_psy,
+   POWER_SUPPLY_PROP_STATUS, );
+   if (rc < 0)
+   return rc;
+   if (prop.intval == POWER_SUPPLY_STATUS_DISCHARGING)
+   return 0;
+
+   rc = power_supply_get_property(chg->usb_psy,
+   POWER_SUPPLY_PROP_USB_TYPE, );
+   if (rc < 0)
+   return rc;
+   charger_type = prop.intval;
+
+   while (adapter_cap[i].adap_type != 0) {
+   if (charger_type == adapter_cap[i].adap_type) {
+   return adapter_cap[i].adap_cap;
+   }
+   i++;
+   }
+
+   return 0;
+}
+
 static int smbb_usbin_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
@@ -505,6 +552,9 @@ static int smbb_usbin_get_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX:
val->intval = 250;
break;
+   case POWER_SUPPLY_PROP_QUICK_CHARGE_TYPE:
+   val->intval = get_quick_charge_type(chg);
+   break;
default:
rc = -EINVAL;
break;
@@ -695,6 +745,7 @@ static enum power_supply_property smbb_charger_properties[] 
= {
POWER_SUPPLY_PROP_ONLINE,
POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT,
POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX,
+   POWER_SUPPLY_PROP_QUICK_CHARGE_TYPE,
 };
 
 static enum 

Re: [PATCH] perf stat: update POWER9 metrics to utilize other metrics

2020-08-13 Thread Ian Rogers
On Thu, Aug 13, 2020 at 3:21 PM Paul A. Clarke  wrote:
>
> These changes take advantage of the new capability added in
> merge commit 00e4db51259a5f936fec1424b884f029479d3981
> "Allow using computed metrics in calculating other metrics".
>
> The net is a simplification of the expressions for a handful
> of metrics, but no functional change.
>
> Signed-off-by: Paul A. Clarke 

Acked-by: Ian Rogers 
(Re-sent with plain text enabled to avoid lkml bounce)

Thanks,
Ian


>
> ---
>  .../arch/powerpc/power9/metrics.json  | 48 +--
>  1 file changed, 24 insertions(+), 24 deletions(-)
>
> diff --git a/tools/perf/pmu-events/arch/powerpc/power9/metrics.json 
> b/tools/perf/pmu-events/arch/powerpc/power9/metrics.json
> index 80816d6402e9..f8784c608479 100644
> --- a/tools/perf/pmu-events/arch/powerpc/power9/metrics.json
> +++ b/tools/perf/pmu-events/arch/powerpc/power9/metrics.json
> @@ -60,7 +60,7 @@
>  },
>  {
>  "BriefDescription": "Stalls due to short latency decimal floating 
> ops.",
> -"MetricExpr": "(PM_CMPLU_STALL_DFU - 
> PM_CMPLU_STALL_DFLONG)/PM_RUN_INST_CMPL",
> +"MetricExpr": "dfu_stall_cpi - dflong_stall_cpi",
>  "MetricGroup": "cpi_breakdown",
>  "MetricName": "dfu_other_stall_cpi"
>  },
> @@ -72,7 +72,7 @@
>  },
>  {
>  "BriefDescription": "Completion stall by Dcache miss which resolved 
> off node memory/cache",
> -"MetricExpr": "(PM_CMPLU_STALL_DMISS_L3MISS - 
> PM_CMPLU_STALL_DMISS_L21_L31 - PM_CMPLU_STALL_DMISS_LMEM - 
> PM_CMPLU_STALL_DMISS_REMOTE)/PM_RUN_INST_CMPL",
> +"MetricExpr": "dmiss_non_local_stall_cpi - dmiss_remote_stall_cpi",
>  "MetricGroup": "cpi_breakdown",
>  "MetricName": "dmiss_distant_stall_cpi"
>  },
> @@ -90,7 +90,7 @@
>  },
>  {
>  "BriefDescription": "Completion stall due to cache miss that 
> resolves in the L2 or L3 without conflict",
> -"MetricExpr": "(PM_CMPLU_STALL_DMISS_L2L3 - 
> PM_CMPLU_STALL_DMISS_L2L3_CONFLICT)/PM_RUN_INST_CMPL",
> +"MetricExpr": "dmiss_l2l3_stall_cpi - dmiss_l2l3_conflict_stall_cpi",
>  "MetricGroup": "cpi_breakdown",
>  "MetricName": "dmiss_l2l3_noconflict_stall_cpi"
>  },
> @@ -114,7 +114,7 @@
>  },
>  {
>  "BriefDescription": "Completion stall by Dcache miss which resolved 
> outside of local memory",
> -"MetricExpr": "(PM_CMPLU_STALL_DMISS_L3MISS - 
> PM_CMPLU_STALL_DMISS_L21_L31 - PM_CMPLU_STALL_DMISS_LMEM)/PM_RUN_INST_CMPL",
> +"MetricExpr": "dmiss_l3miss_stall_cpi - dmiss_l21_l31_stall_cpi - 
> dmiss_lmem_stall_cpi",
>  "MetricGroup": "cpi_breakdown",
>  "MetricName": "dmiss_non_local_stall_cpi"
>  },
> @@ -126,7 +126,7 @@
>  },
>  {
>  "BriefDescription": "Stalls due to short latency double precision 
> ops.",
> -"MetricExpr": "(PM_CMPLU_STALL_DP - 
> PM_CMPLU_STALL_DPLONG)/PM_RUN_INST_CMPL",
> +"MetricExpr": "dp_stall_cpi - dplong_stall_cpi",
>  "MetricGroup": "cpi_breakdown",
>  "MetricName": "dp_other_stall_cpi"
>  },
> @@ -155,7 +155,7 @@
>  "MetricName": "emq_full_stall_cpi"
>  },
>  {
> -"MetricExpr": "(PM_CMPLU_STALL_ERAT_MISS + 
> PM_CMPLU_STALL_EMQ_FULL)/PM_RUN_INST_CMPL",
> +"MetricExpr": "erat_miss_stall_cpi + emq_full_stall_cpi",
>  "MetricGroup": "cpi_breakdown",
>  "MetricName": "emq_stall_cpi"
>  },
> @@ -173,7 +173,7 @@
>  },
>  {
>  "BriefDescription": "Completion stall due to execution units for 
> other reasons.",
> -"MetricExpr": "(PM_CMPLU_STALL_EXEC_UNIT - PM_CMPLU_STALL_FXU - 
> PM_CMPLU_STALL_DP - PM_CMPLU_STALL_DFU - PM_CMPLU_STALL_PM - 
> PM_CMPLU_STALL_CRYPTO - PM_CMPLU_STALL_VFXU - 
> PM_CMPLU_STALL_VDP)/PM_RUN_INST_CMPL",
> +"MetricExpr": "exec_unit_stall_cpi - scalar_stall_cpi - 
> vector_stall_cpi",
>  "MetricGroup": "cpi_breakdown",
>  "MetricName": "exec_unit_other_stall_cpi"
>  },
> @@ -197,7 +197,7 @@
>  },
>  {
>  "BriefDescription": "Stalls due to short latency integer ops",
> -"MetricExpr": "(PM_CMPLU_STALL_FXU - 
> PM_CMPLU_STALL_FXLONG)/PM_RUN_INST_CMPL",
> +"MetricExpr": "fxu_stall_cpi - fxlong_stall_cpi",
>  "MetricGroup": "cpi_breakdown",
>  "MetricName": "fxu_other_stall_cpi"
>  },
> @@ -221,7 +221,7 @@
>  },
>  {
>  "BriefDescription": "Instruction Completion Table other stalls",
> -"MetricExpr": "(PM_ICT_NOSLOT_CYC - PM_ICT_NOSLOT_IC_MISS - 
> PM_ICT_NOSLOT_BR_MPRED_ICMISS - PM_ICT_NOSLOT_BR_MPRED - 
> PM_ICT_NOSLOT_DISP_HELD)/PM_RUN_INST_CMPL",
> +"MetricExpr": "nothing_dispatched_cpi - ict_noslot_ic_miss_cpi - 
> ict_noslot_br_mpred_icmiss_cpi - ict_noslot_br_mpred_cpi - 
> ict_noslot_disp_held_cpi",
>  "MetricGroup": "cpi_breakdown",
>  "MetricName": "ict_noslot_cyc_other_cpi"
>  },
> @@ -245,7 +245,7 @@
>

Re: POC: Alternative solution: Re: [PATCH 0/4] printk: reimplement LOG_CONT handling

2020-08-13 Thread Sergey Senozhatsky
On (20/08/13 12:35), John Ogness wrote:
> I believe I failed to recognize the fundamental problem. The fundamental
> problem is that the pr_cont() semantics are very poor.

The semantics is pretty clear - use it only in UP early bootup,
anything else is broken :)

  /*
   * Annotation for a "continued" line of log printout (only done after a
   * line that had no enclosing \n). Only to be used by core/arch code
   * during early bootup (a continued line is not SMP-safe otherwise).
   */
  #define KERN_CONT KERN_SOH "c"

> I now strongly believe that we need to fix those semantics by having the
> pr_cont() user take responsibility for buffering the message. Patching the
> ~2000 pr_cont() users will be far easier than continuing to twist ourselves
> around this madness.

I welcome this effort. We've been talking about the fact that pr_cont() is
not something we can ignore anymore (we have more and more SMP users of
it) since the Kernel Summit in Santa Fe, NM, but the general response back
then was "oh my god, who cares" (pretty sure this is very close to what Ted
Ts'o said during the printk session).

> Here is an example for a new pr_cont() API:
> 
> struct pr_cont c;
> 
> pr_cont_alloc_info();
>(or alternatively)
> dev_cont_alloc_info(dev, );
> 
> pr_cont(, "1");
> pr_cont(, "2");
> 
> pr_cont_flush();

This might be a bit more complex.

One thing that we need to handle here, I believe, is that the context
which crashes the kernel should flush its cont buffer, because the
information there is relevant to the crash:

pr_cont_alloc_info();
pr_cont(, "1");
pr_cont(, "2");
>>
   oops
  panic()
<<
pr_cont_flush();

We better flush that context's pr_cont buffer during panic().

Another example:


pr_cont_alloc_info();

for (i = 0; i < p->sz; i++)
pr_cont(, p->buf[i]);
>>
   page fault
exit
<<
pr_cont_flush();

I believe we need to preliminary flush pr_cont() in this case as well,
because the information there might be very helpful.

-ss


RE: [EXT] Re: [PATCH] softirq: add irq off checking for __raise_softirq_irqoff

2020-08-13 Thread Jiafei Pan
> From: Peter Zijlstra 
> Sent: Thursday, August 13, 2020 1:58 PM
> 
> On Thu, Aug 06, 2020 at 12:07:29PM +0800, Jiafei Pan wrote:
> > __raise_softirq_irqoff will update per-CPU mask of pending softirqs,
> > it need to be called in irq disabled context in order to keep it
> > atomic operation, otherwise it will be interrupted by hardware
> > interrupt, and per-CPU softirqs pending mask will be corrupted, the
> > result is there will be unexpected issue, for example hrtimer soft irq
> > will be losed and soft hrtimer will never be expire and handled.
> >
> > Adding irqs disabled checking here to provide warning in irqs enabled
> > context.
> >
> > Signed-off-by: Jiafei Pan 
> > ---
> >  kernel/softirq.c | 5 +
> >  1 file changed, 5 insertions(+)
> >
> > diff --git a/kernel/softirq.c b/kernel/softirq.c index
> > bf88d7f62433..11f61e54a3ae 100644
> > --- a/kernel/softirq.c
> > +++ b/kernel/softirq.c
> > @@ -481,6 +481,11 @@ void raise_softirq(unsigned int nr)
> >
> >  void __raise_softirq_irqoff(unsigned int nr)  {
> > + /* This function can only be called in irq disabled context,
> > +  * otherwise or_softirq_pending will be interrupted by hardware
> > +  * interrupt, so that there will be unexpected issue.
> > +  */
> 
> Comment style is wrong, also I'm not sure the comment is really helpfull.
[Jiafei Pan] Thanks for your comments, yes, function name already indicate the 
function
Should be called in irq off context, will remove the comment in next version.
> 
> > + WARN_ON_ONCE(!irqs_disabled());
> 
> lockdep_assert_irqs_disabled();
> 
> >   trace_softirq_raise(nr);
> >   or_softirq_pending(1UL << nr);
> >  }


Re: [PATCH] mm : update ra->ra_pages if it's NOT equal to bdi->ra_pages

2020-08-13 Thread Matthew Wilcox
On Fri, Aug 14, 2020 at 10:45:37AM +0800, Zhaoyang Huang wrote:
> On Fri, Aug 14, 2020 at 10:33 AM Andrew Morton
>  wrote:
> >
> > On Fri, 14 Aug 2020 10:20:11 +0800 Zhaoyang Huang  
> > wrote:
> >
> > > On Fri, Aug 14, 2020 at 10:07 AM Matthew Wilcox  
> > > wrote:
> > > >
> > > > On Fri, Aug 14, 2020 at 02:43:55AM +0100, Matthew Wilcox wrote:
> > > > > On Fri, Aug 14, 2020 at 09:30:11AM +0800, Zhaoyang Huang wrote:
> > > > > > file->f_ra->ra_pages will remain the initialized value since it 
> > > > > > opend, which may
> > > > > > be NOT equal to bdi->ra_pages as the latter one is updated 
> > > > > > somehow(etc,
> > > > > > echo xxx > /sys/block/dm/queue/read_ahead_kb).So sync ra->ra_pages 
> > > > > > to the
> > > > > > updated value when sync read.
> > > > >
> > > > > It still ignores the work done by shrink_readahead_size_eio()
> > > > > and fadvise(POSIX_FADV_SEQUENTIAL).
> > > >
> > > > ... by the way, if you're trying to update one particular file's 
> > > > readahead
> > > > state, you can just call fadvise(POSIX_FADV_NORMAL) on it.
> > > >
> > > > If you want to update every open file's ra_pages by writing to sysfs,
> > > > then just no.  We don't do that.
> > > No, What I want to fix is the file within one process's context  keeps
> > > using the initialized value when it is opened and not sync with new
> > > value when bdi->ra_pages changes.
> >
> > So you're saying that
> >
> > echo xxx > /sys/block/dm/queue/read_ahead_kb
> >
> > does not affect presently-open files, and you believe that it should do
> > so?
> >
> > I guess that could be a reasonable thing to want - it's reasonable for
> > a user to expect that writing to a global tunable will take immediate
> > global effect.  I guess.
> >
> > But as Matthew says, it would help if you were to explain why this is
> > needed.  In full detail.  What operational problems is the present
> > implementation causing?
> The real scenario is some system(like android) will turbo read during
> startup via expanding the readahead window and then set it back to
> normal(128kb as usual). However, some files in the system process
> context will keep to be opened since it is opened up and has no chance
> to sync with the updated value as it is almost impossible to change
> the files attached to the inode(processes are unaware of these
> things). we have to fix it from a kernel perspective.

OK, this is a much more useful description of the problem, thank you!

I can think of two possibilities here.  One is that maybe our readahead
heuristics just don't work on modern phone hardware.  Perhaps we need
to ramp up more aggressively by default.

The other is that maybe it really is just a "boost at startup" kind
of situation and so we should support _that_.  Some interface where
we can set a ra_boost, and then do:

if (ra_boost)
newsize *= 2;

in get_init_ra_size().



Re: [GIT] Networking

2020-08-13 Thread pr-tracker-bot
The pull request you sent on Thu, 13 Aug 2020 16:10:57 -0700 (PDT):

> git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git refs/heads/master

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/a1d21081a60dfb7fddf4a38b66d9cef603b317a9

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


Re: [PATCH v4 3/7] genirq: Introduce irq_suspend_one() and irq_resume_one() callbacks

2020-08-13 Thread Doug Anderson
Hi,

On Thu, Aug 13, 2020 at 7:07 PM Thomas Gleixner  wrote:
>
> Doug,
>
> On Thu, Aug 13 2020 at 15:58, Doug Anderson wrote:
> > On Thu, Aug 13, 2020 at 3:09 PM Thomas Gleixner  wrote:
> >> > * If this interrupt fires while the system is suspended then please
> >> > wake the system up.
> >>
> >> Well, that's kinda contradicting itself. If the interrupt is masked then
> >> what is the point? I'm surely missing something subtle here.
> >
> > This is how I've always been told that the API works and there are at
> > least a handful of drivers in the kernel whose suspend routines both
> > enable wakeup and call disable_irq().  Isn't this also documented as
> > of commit f9f21cea3113 ("genirq: Clarify that irq wake state is
> > orthogonal to enable/disable")?
>
> Fair enough. The wording there is unfortunate and I probably should have
> spent more brain cycles before applying it. It suggests that this is a
> pure driver problem. I should have asked some of the questions I asked
> now back then :(

I mean, certainly a driver could be rewritten not to do this.  ...and,
in fact, the easier approach (for just solving my immediate concern)
would be to change cros-ec not to do this.  However, it was my
understanding that what cros-ec was doing was actually just fine and
part of the API to drivers.  This understanding was solidified when
the patch I mentioned landed.  When looking at this before I found
that certainly there are other drivers that do this and it felt better
to implement the proper thing rather than add a hack to cros-ec to
work around the Qualcomm pinctrl driver.

In general the idea here, I think, is that in the "suspend" call of a
driver it might want to disable interrupts so that it doesn't have to
deal with them after the driver has configured things (and adjusted
its internal data structures) for suspend.  However, it might still
want its interrupt to cause a wakeup.  ...so it wants the wakeup to
happen (and its resume call to be made to get everything back in the
right state) and at the end of the resume call it wants to enable its
interrupt handler again.  That seems like a sane design pattern to me,
but maybe I'm crazy.  Yes, I guess the driver could implement the
"noirq" suspend function, but sometimes it's simpler to have a single
suspend function that first leverages interrupts, then disables them
at an exact point it can control, and then finishes adjusting its
state.

I'll also note that the concept that a masked interrupt can "wake you
up" is also not unlike how ARM SoCs work, which is part of what made
me feel like this API was fine.  Specifically if you have interrupts
masked at the CPU level and then enter "WFI" (wait for interrupt) it
will wake up (or come out of idle) from one of those masked
interrupts.


> >> If that's the main problem which is solved in these callbacks, then I
> >> really have to ask why this has not been raised years ago. Why can't
> >> people talk?
> >
> > Not all of us have the big picture that you do to know how things
> > ought to work, I guess.  If nothing else someone looking at this
> > problem would think: "this must be a common problem, let's go see how
> > all the other places do it" and then they find how everyone else is
> > doing it and do it that way.  It requires the grander picture that a
> > maintainer has in order to say: whoa, everyone's copying the same
> > hack--let's come up with a better solution.
>
> That's not the point. I know how these things happen, but I fail to
> understand why nobody ever looks at this and says: OMG, I need to do yet
> another variant of copy of the same thing every other driver
> does. Why is there no infrastructure for that?
>
> Asking that question does not require a maintainer who always encouraged
> people to talk about exactly these kind of things instead of going off
> and creating the gazillionst broken copy of the same thing with yet
> another wart working around core code problems and thereby violating
> layering and introducing bugs which wouldn't exist otherwise.
>
> Spare me all the $corp reasons. I've heard all of them and if not then
> the not yet known reason won't be any more convincing. :)

As per above, if I was simply motivated to hack it to get it done I
would have suggested we just muck with cros_ec.  I certainly do have a
bias for getting things done and getting things landed, but I also try
to pride myself in not saying that we should just accept any old hack.
Perhaps many people posting patches just want any old crap landed, but
I'd like to think I'm not one of them.


> One of the most underutilized strengths of FOSS is that you can go and
> ask someone who has the big picture in his head before you go off and
> waste time on distangling copy, dealing with the resulting obvious
> bugs and then the latent ones which only surface 3 month after the
> product has shipped. Or like in this case figure out that the copy
> road is a dead end and then create something new without seeing the big
> 

drivers/scsi/smartpqi/smartpqi_init.c:2070 pqi_update_scsi_devices() error: we previously assumed 'physdev_list' could be null (see line 2006)

2020-08-13 Thread kernel test robot
tree:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 
master
head:   dddcbc139e96bd18d8c65ef7b7e440f0d32457c2
commit: 5e6a9760f7da4dd86cca43ac6423695d6cb0dff4 scsi: smartpqi: add module 
param for exposure order
date:   12 months ago
config: ia64-randconfig-m031-20200811 (attached as .config)
compiler: ia64-linux-gcc (GCC) 9.3.0

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

New smatch warnings:
drivers/scsi/smartpqi/smartpqi_init.c:2070 pqi_update_scsi_devices() error: we 
previously assumed 'physdev_list' could be null (see line 2006)

Old smatch warnings:
drivers/scsi/smartpqi/smartpqi_init.c:2077 pqi_update_scsi_devices() error: we 
previously assumed 'logdev_list' could be null (see line 2013)
drivers/scsi/smartpqi/smartpqi_init.c:2134 pqi_update_scsi_devices() warn: 
inconsistent indenting
drivers/scsi/smartpqi/smartpqi_init.c:6995 pqi_ctrl_init() warn: impossible 
condition '(ctrl_info->max_outstanding_requests > (~0)) => (0-u32max > u32max)'

vim +/physdev_list +2070 drivers/scsi/smartpqi/smartpqi_init.c

  1977  
  1978  static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info)
  1979  {
  1980  int i;
  1981  int rc;
  1982  LIST_HEAD(new_device_list_head);
  1983  struct report_phys_lun_extended *physdev_list = NULL;
  1984  struct report_log_lun_extended *logdev_list = NULL;
  1985  struct report_phys_lun_extended_entry *phys_lun_ext_entry;
  1986  struct report_log_lun_extended_entry *log_lun_ext_entry;
  1987  struct bmic_identify_physical_device *id_phys = NULL;
  1988  u32 num_physicals;
  1989  u32 num_logicals;
  1990  struct pqi_scsi_dev **new_device_list = NULL;
  1991  struct pqi_scsi_dev *device;
  1992  struct pqi_scsi_dev *next;
  1993  unsigned int num_new_devices;
  1994  unsigned int num_valid_devices;
  1995  bool is_physical_device;
  1996  u8 *scsi3addr;
  1997  unsigned int physical_index;
  1998  unsigned int logical_index;
  1999  static char *out_of_memory_msg =
  2000  "failed to allocate memory, device discovery stopped";
  2001  
  2002  rc = pqi_get_device_lists(ctrl_info, _list, 
_list);
  2003  if (rc)
  2004  goto out;
  2005  
> 2006  if (physdev_list)
  2007  num_physicals =
  2008  
get_unaligned_be32(_list->header.list_length)
  2009  / sizeof(physdev_list->lun_entries[0]);
  2010  else
  2011  num_physicals = 0;
  2012  
  2013  if (logdev_list)
  2014  num_logicals =
  2015  
get_unaligned_be32(_list->header.list_length)
  2016  / sizeof(logdev_list->lun_entries[0]);
  2017  else
  2018  num_logicals = 0;
  2019  
  2020  if (num_physicals) {
  2021  /*
  2022   * We need this buffer for calls to 
pqi_get_physical_disk_info()
  2023   * below.  We allocate it here instead of inside
  2024   * pqi_get_physical_disk_info() because it's a fairly 
large
  2025   * buffer.
  2026   */
  2027  id_phys = kmalloc(sizeof(*id_phys), GFP_KERNEL);
  2028  if (!id_phys) {
  2029  dev_warn(_info->pci_dev->dev, "%s\n",
  2030  out_of_memory_msg);
  2031  rc = -ENOMEM;
  2032  goto out;
  2033  }
  2034  }
  2035  
  2036  num_new_devices = num_physicals + num_logicals;
  2037  
  2038  new_device_list = kmalloc_array(num_new_devices,
  2039  sizeof(*new_device_list),
  2040  GFP_KERNEL);
  2041  if (!new_device_list) {
  2042  dev_warn(_info->pci_dev->dev, "%s\n", 
out_of_memory_msg);
  2043  rc = -ENOMEM;
  2044  goto out;
  2045  }
  2046  
  2047  for (i = 0; i < num_new_devices; i++) {
  2048  device = kzalloc(sizeof(*device), GFP_KERNEL);
  2049  if (!device) {
  2050  dev_warn(_info->pci_dev->dev, "%s\n",
  2051  out_of_memory_msg);
  2052  rc = -ENOMEM;
  2053  goto out;
  2054  }
  2055  list_add_tail(>new_device_list_entry,
  2056  _device_list_head);
  2057  }
  2058  
  2059  device = NULL;
  2060  num_valid_devices = 0;
  2061  physical_index = 0;
  2062  logical_index = 0;
  2063  
  2064  for (i = 0; i < 

linux-next: Tree for Aug 14

2020-08-13 Thread Stephen Rothwell
Hi all,

News: The merge window has opened, so please do not add any v5.10
related material to your linux-next included branches until after the
merge window closes again.

Changes since 20200813:

My fixes tree contains:

  73c7adb54169 ("device_cgroup: Fix RCU list debugging warning")

Linus' tree lost its WARNING.

Non-merge commits (relative to Linus' tree): 939
 1201 files changed, 29318 insertions(+), 10477 deletions(-)



I have created today's linux-next tree at
git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
(patches at http://www.kernel.org/pub/linux/kernel/next/ ).  If you
are tracking the linux-next tree using git, you should not use "git pull"
to do so as that will try to merge the new linux-next release with the
old one.  You should use "git fetch" and checkout or reset to the new
master.

You can see which trees have been included by looking in the Next/Trees
file in the source.  There are also quilt-import.log and merge.log
files in the Next directory.  Between each merge, the tree was built
with a ppc64_defconfig for powerpc, an allmodconfig for x86_64, a
multi_v7_defconfig for arm and a native build of tools/perf. After
the final fixups (if any), I do an x86_64 modules_install followed by
builds for x86_64 allnoconfig, powerpc allnoconfig (32 and 64 bit),
ppc44x_defconfig, allyesconfig and pseries_le_defconfig and i386, sparc
and sparc64 defconfig and htmldocs. And finally, a simple boot test
of the powerpc pseries_le_defconfig kernel in qemu (with and without
kvm enabled).

Below is a summary of the state of the merge.

I am currently merging 327 trees (counting Linus' and 85 trees of bug
fix patches pending for the current merge release).

Stats about the size of the tree over time can be seen at
http://neuling.org/linux-next-size.html .

Status of my local build tests will be at
http://kisskb.ellerman.id.au/linux-next .  If maintainers want to give
advice about cross compilers/configs that work, we are always open to add
more builds.

Thanks to Randy Dunlap for doing many randconfig builds.  And to Paul
Gortmaker for triage and bug fixes.

-- 
Cheers,
Stephen Rothwell

$ git checkout master
$ git reset --hard stable
Merging origin/master (dddcbc139e96 Merge tag 'docs-5.9-2' of 
git://git.lwn.net/linux)
Merging fixes/master (73c7adb54169 device_cgroup: Fix RCU list debugging 
warning)
Merging kbuild-current/fixes (06a81c1c7db9 Merge tag 'arm64-fixes' of 
git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux)
Merging arc-current/for-curr (11ba468877bb Linux 5.8-rc5)
Merging arm-current/fixes (5c6360ee4a0e ARM: 8988/1: mmu: fix crash in EFI 
calls due to p4d typo in create_mapping_late())
Merging arm64-fixes/for-next/fixes (6a7389f0312f MAINTAINERS: Include drivers 
subdirs for ARM PMU PROFILING AND DEBUGGING entry)
Merging arm-soc-fixes/arm/fixes (fe1d899f4212 ARM: dts: keystone-k2g-evm: fix 
rgmii phy-mode for ksz9031 phy)
Merging uniphier-fixes/fixes (48778464bb7d Linux 5.8-rc2)
Merging drivers-memory-fixes/fixes (b3a9e3b9622a Linux 5.8-rc1)
Merging m68k-current/for-linus (382f429bb559 m68k: defconfig: Update defconfigs 
for v5.8-rc3)
Merging powerpc-fixes/fixes (6553fb799f60 powerpc/pkeys: Fix boot failures with 
Nemo board (A-EON AmigaOne X1000))
Merging s390-fixes/fixes (00e4db51259a Merge tag 'perf-tools-2020-08-10' of 
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux)
Merging sparc/master (0a95a6d1a4cd sparc: use for_each_child_of_node() macro)
Merging fscrypt-current/for-stable (2b4eae95c736 fscrypt: don't evict dirty 
inodes after removing key)
Merging net/master (94c7eb54c4b8 random32: add a tracepoint for prandom_u32())
Merging bpf/master (a62f68c172c3 doc: Add link to bpf helpers man page)
Merging ipsec/master (61ee4137b574 ip_vti: Fix unused variable warning)
Merging netfilter/master (2f941622fd88 netfilter: nft_compat: remove flush 
counter optimization)
Merging ipvs/master (7c7ab580db49 net: Convert to use the fallthrough macro)
Merging wireless-drivers/master (1cfd3426ef98 ath10k: Fix NULL pointer 
dereference in AHB device probe)
Merging mac80211/master (9643609423c7 Revert "ipv4: tunnel: fix compilation on 
ARCH=um")
Merging rdma-fixes/for-rc (bcf876870b95 Linux 5.8)
Merging sound-current/for-linus (5a25de6df789 ALSA: echoaudio: Fix potential 
Oops in snd_echo_resume())
Merging sound-asoc-fixes/for-linus (933cc41085d5 Merge remote-tracking branch 
'asoc/for-5.9' into asoc-linus)
Merging regmap-fixes/for-linus (2b0f61e27f75 Merge remote-tracking branch 
'regmap/for-5.8' into regmap-linus)
Merging regulator-fixes/for-linus (75f4d068cb0d Merge remote-tracking branch 
'regulator/for-5.9' into regulator-linus)
Merging spi-fixes/for-linus (3ea884314328 Merge remote-tracking branch 
'spi/for-5.9' into spi-linus)
Merging pci-current/for-linus (b361663c5a40 PCI/ASPM: Disable ASPM on ASMedia 
ASM1083/1085 PCIe-to-PCI bridge)
Mergi

[PATCH v4 16/20] tools: gpio: rename nlines to num_lines

2020-08-13 Thread Kent Gibson
Rename nlines to num_lines to be consistent with other usage for fields
describing the number of entries in an array.

Signed-off-by: Kent Gibson 
---
 tools/gpio/gpio-hammer.c | 26 +-
 tools/gpio/gpio-utils.c  | 20 ++--
 tools/gpio/gpio-utils.h  |  6 +++---
 3 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/tools/gpio/gpio-hammer.c b/tools/gpio/gpio-hammer.c
index 9fd926e8cb52..a2c7577fad5c 100644
--- a/tools/gpio/gpio-hammer.c
+++ b/tools/gpio/gpio-hammer.c
@@ -22,7 +22,7 @@
 #include 
 #include "gpio-utils.h"
 
-int hammer_device(const char *device_name, unsigned int *lines, int nlines,
+int hammer_device(const char *device_name, unsigned int *lines, int num_lines,
  unsigned int loops)
 {
struct gpiohandle_data data;
@@ -33,7 +33,7 @@ int hammer_device(const char *device_name, unsigned int 
*lines, int nlines,
unsigned int iteration = 0;
 
memset(, 0, sizeof(data.values));
-   ret = gpiotools_request_linehandle(device_name, lines, nlines,
+   ret = gpiotools_request_linehandle(device_name, lines, num_lines,
   GPIOHANDLE_REQUEST_OUTPUT, ,
   "gpio-hammer");
if (ret < 0)
@@ -46,15 +46,15 @@ int hammer_device(const char *device_name, unsigned int 
*lines, int nlines,
goto exit_close_error;
 
fprintf(stdout, "Hammer lines [");
-   for (i = 0; i < nlines; i++) {
+   for (i = 0; i < num_lines; i++) {
fprintf(stdout, "%d", lines[i]);
-   if (i != (nlines - 1))
+   if (i != (num_lines - 1))
fprintf(stdout, ", ");
}
fprintf(stdout, "] on %s, initial states: [", device_name);
-   for (i = 0; i < nlines; i++) {
+   for (i = 0; i < num_lines; i++) {
fprintf(stdout, "%d", data.values[i]);
-   if (i != (nlines - 1))
+   if (i != (num_lines - 1))
fprintf(stdout, ", ");
}
fprintf(stdout, "]\n");
@@ -63,7 +63,7 @@ int hammer_device(const char *device_name, unsigned int 
*lines, int nlines,
j = 0;
while (1) {
/* Invert all lines so we blink */
-   for (i = 0; i < nlines; i++)
+   for (i = 0; i < num_lines; i++)
data.values[i] = !data.values[i];
 
ret = gpiotools_set_values(fd, );
@@ -81,9 +81,9 @@ int hammer_device(const char *device_name, unsigned int 
*lines, int nlines,
j = 0;
 
fprintf(stdout, "[");
-   for (i = 0; i < nlines; i++) {
+   for (i = 0; i < num_lines; i++) {
fprintf(stdout, "%d: %d", lines[i], data.values[i]);
-   if (i != (nlines - 1))
+   if (i != (num_lines - 1))
fprintf(stdout, ", ");
}
fprintf(stdout, "]\r");
@@ -121,7 +121,7 @@ int main(int argc, char **argv)
const char *device_name = NULL;
unsigned int lines[GPIOHANDLES_MAX];
unsigned int loops = 0;
-   int nlines;
+   int num_lines;
int c;
int i;
 
@@ -158,11 +158,11 @@ int main(int argc, char **argv)
return -1;
}
 
-   nlines = i;
+   num_lines = i;
 
-   if (!device_name || !nlines) {
+   if (!device_name || !num_lines) {
print_usage();
return -1;
}
-   return hammer_device(device_name, lines, nlines, loops);
+   return hammer_device(device_name, lines, num_lines, loops);
 }
diff --git a/tools/gpio/gpio-utils.c b/tools/gpio/gpio-utils.c
index 16a5d9cb9da2..d527980bcb94 100644
--- a/tools/gpio/gpio-utils.c
+++ b/tools/gpio/gpio-utils.c
@@ -38,7 +38,7 @@
  * such as "gpiochip0"
  * @lines: An array desired lines, specified by offset
  * index for the associated GPIO device.
- * @nline: The number of lines to request.
+ * @num_lines: The number of lines to request.
  * @flag:  The new flag for requsted gpio. Reference
  * "linux/gpio.h" for the meaning of flag.
  * @data:  Default value will be set to gpio when flag is
@@ -56,7 +56,7 @@
  * On failure return the errno.
  */
 int gpiotools_request_linehandle(const char *device_name, unsigned int *lines,
-unsigned int nlines, unsigned int flag,
+unsigned int num_lines, unsigned int flag,
 struct gpiohandle_data *data,
 const char *consumer_label)
 {
@@ -78,12 +78,12 @@ int gpiotools_request_linehandle(const char *device_name, 
unsigned int *lines,
goto exit_free_name;
}
 
-   for (i = 0; i < nlines; i++)
+  

[PATCH v4 19/20] tools: gpio: add multi-line monitoring to gpio-event-mon

2020-08-13 Thread Kent Gibson
Extend gpio-event-mon to support monitoring multiple lines.
This would require multiple lineevent requests to implement using uAPI v1,
but can be performed with a single line request using uAPI v2.

Signed-off-by: Kent Gibson 
---
 tools/gpio/gpio-event-mon.c | 45 -
 1 file changed, 34 insertions(+), 11 deletions(-)

diff --git a/tools/gpio/gpio-event-mon.c b/tools/gpio/gpio-event-mon.c
index d6a831200c18..e50bb107ea3a 100644
--- a/tools/gpio/gpio-event-mon.c
+++ b/tools/gpio/gpio-event-mon.c
@@ -26,7 +26,8 @@
 #include "gpio-utils.h"
 
 int monitor_device(const char *device_name,
-  unsigned int line,
+  unsigned int *lines,
+  unsigned int num_lines,
   struct gpio_v2_line_config *config,
   unsigned int loops)
 {
@@ -47,7 +48,7 @@ int monitor_device(const char *device_name,
goto exit_free_name;
}
 
-   ret = gpiotools_request_line(device_name, , 1, config,
+   ret = gpiotools_request_line(device_name, lines, num_lines, config,
 "gpio-event-mon");
if (ret < 0)
goto exit_device_close;
@@ -55,8 +56,10 @@ int monitor_device(const char *device_name,
lfd = ret;
 
/* Read initial states */
-   values.mask = 1;
+   values.mask = 0;
values.bits = 0;
+   for (i = 0; i < num_lines; i++)
+   gpiotools_set_bit(, i);
ret = gpiotools_get_values(lfd, );
if (ret < 0) {
fprintf(stderr,
@@ -65,9 +68,23 @@ int monitor_device(const char *device_name,
goto exit_line_close;
}
 
-   fprintf(stdout, "Monitoring line %d on %s\n", line, device_name);
-   fprintf(stdout, "Initial line value: %d\n",
-   gpiotools_test_bit(values.bits, 0));
+   if (num_lines == 1) {
+   fprintf(stdout, "Monitoring line %d on %s\n", lines[0], 
device_name);
+   fprintf(stdout, "Initial line value: %d\n",
+   gpiotools_test_bit(values.bits, 0));
+   } else {
+   fprintf(stdout, "Monitoring lines %d", lines[0]);
+   for (i = 1; i < num_lines - 1; i++)
+   fprintf(stdout, ", %d", lines[i]);
+   fprintf(stdout, " and %d on %s\n", lines[i], device_name);
+   fprintf(stdout, "Initial line values: %d",
+   gpiotools_test_bit(values.bits, 0));
+   for (i = 1; i < num_lines - 1; i++)
+   fprintf(stdout, ", %d",
+   gpiotools_test_bit(values.bits, i));
+   fprintf(stdout, " and %d\n",
+   gpiotools_test_bit(values.bits, i));
+   }
 
while (1) {
struct gpio_v2_line_event event;
@@ -126,7 +143,7 @@ void print_usage(void)
fprintf(stderr, "Usage: gpio-event-mon [options]...\n"
"Listen to events on GPIO lines, 0->1 1->0\n"
"  -n   Listen on GPIOs on a named device (must be 
stated)\n"
-   "  -o  Offset to monitor\n"
+   "  -o  Offset of line to monitor (may be repeated)\n"
"  -d Set line as open drain\n"
"  -s Set line as open source\n"
"  -r Listen for rising edges\n"
@@ -146,7 +163,8 @@ void print_usage(void)
 int main(int argc, char **argv)
 {
const char *device_name = NULL;
-   unsigned int line = -1;
+   unsigned int lines[GPIO_V2_LINES_MAX];
+   unsigned int num_lines = 0;
unsigned int loops = 0;
struct gpio_v2_line_config config;
int c;
@@ -162,7 +180,12 @@ int main(int argc, char **argv)
device_name = optarg;
break;
case 'o':
-   line = strtoul(optarg, NULL, 10);
+   if (num_lines >= GPIO_V2_LINES_MAX) {
+   print_usage();
+   return -1;
+   }
+   lines[num_lines] = strtoul(optarg, NULL, 10);
+   num_lines++;
break;
case 'd':
config.flags |= GPIO_V2_LINE_FLAG_OPEN_DRAIN;
@@ -182,7 +205,7 @@ int main(int argc, char **argv)
}
}
 
-   if (!device_name || line == -1) {
+   if (!device_name || num_lines == 0) {
print_usage();
return -1;
}
@@ -191,5 +214,5 @@ int main(int argc, char **argv)
   "falling edges\n");
config.flags |= EDGE_FLAGS;
}
-   return monitor_device(device_name, line, , loops);
+   return monitor_device(device_name, lines, num_lines, , loops);
 }
-- 
2.28.0



[PATCH v4 20/20] tools: gpio: add debounce support to gpio-event-mon

2020-08-13 Thread Kent Gibson
Add support for debouncing monitored lines to gpio-event-mon.

Signed-off-by: Kent Gibson 
---
 tools/gpio/gpio-event-mon.c | 20 +---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/tools/gpio/gpio-event-mon.c b/tools/gpio/gpio-event-mon.c
index e50bb107ea3a..bd5ea3cc6e85 100644
--- a/tools/gpio/gpio-event-mon.c
+++ b/tools/gpio/gpio-event-mon.c
@@ -148,11 +148,12 @@ void print_usage(void)
"  -s Set line as open source\n"
"  -r Listen for rising edges\n"
"  -f Listen for falling edges\n"
+   "  -b  Debounce the line with period n microseconds\n"
" [-c ]Do  loops (optional, infinite loop if not 
stated)\n"
"  -? This helptext\n"
"\n"
"Example:\n"
-   "gpio-event-mon -n gpiochip0 -o 4 -r -f\n"
+   "gpio-event-mon -n gpiochip0 -o 4 -r -f -b 1\n"
);
 }
 
@@ -167,11 +168,12 @@ int main(int argc, char **argv)
unsigned int num_lines = 0;
unsigned int loops = 0;
struct gpio_v2_line_config config;
-   int c;
+   int c, attr, i;
+   unsigned long debounce_period = 0;
 
memset(, 0, sizeof(config));
config.flags = GPIO_V2_LINE_FLAG_INPUT;
-   while ((c = getopt(argc, argv, "c:n:o:dsrf?")) != -1) {
+   while ((c = getopt(argc, argv, "c:n:o:b:dsrf?")) != -1) {
switch (c) {
case 'c':
loops = strtoul(optarg, NULL, 10);
@@ -187,6 +189,9 @@ int main(int argc, char **argv)
lines[num_lines] = strtoul(optarg, NULL, 10);
num_lines++;
break;
+   case 'b':
+   debounce_period = strtoul(optarg, NULL, 10);
+   break;
case 'd':
config.flags |= GPIO_V2_LINE_FLAG_OPEN_DRAIN;
break;
@@ -205,6 +210,15 @@ int main(int argc, char **argv)
}
}
 
+   if (debounce_period) {
+   attr = config.num_attrs;
+   config.num_attrs++;
+   for (i = 0; i < num_lines; i++)
+   gpiotools_set_bit([attr].mask, i);
+   config.attrs[attr].attr.id = GPIO_V2_LINE_ATTR_ID_DEBOUNCE;
+   config.attrs[attr].attr.debounce_period = debounce_period;
+   }
+
if (!device_name || num_lines == 0) {
print_usage();
return -1;
-- 
2.28.0



[PATCH v4 18/20] tools: gpio: port gpio-event-mon to v2 uAPI

2020-08-13 Thread Kent Gibson
Port the gpio-event-mon tool to the latest GPIO uAPI.

Signed-off-by: Kent Gibson 
---
 tools/gpio/gpio-event-mon.c | 91 +++--
 1 file changed, 47 insertions(+), 44 deletions(-)

diff --git a/tools/gpio/gpio-event-mon.c b/tools/gpio/gpio-event-mon.c
index 1a303a81aeef..d6a831200c18 100644
--- a/tools/gpio/gpio-event-mon.c
+++ b/tools/gpio/gpio-event-mon.c
@@ -23,17 +23,16 @@
 #include 
 #include 
 #include 
+#include "gpio-utils.h"
 
 int monitor_device(const char *device_name,
   unsigned int line,
-  uint32_t handleflags,
-  uint32_t eventflags,
+  struct gpio_v2_line_config *config,
   unsigned int loops)
 {
-   struct gpioevent_request req;
-   struct gpiohandle_data data;
+   struct gpio_v2_line_values values;
char *chrdev_name;
-   int fd;
+   int cfd, lfd;
int ret;
int i = 0;
 
@@ -41,44 +40,39 @@ int monitor_device(const char *device_name,
if (ret < 0)
return -ENOMEM;
 
-   fd = open(chrdev_name, 0);
-   if (fd == -1) {
+   cfd = open(chrdev_name, 0);
+   if (cfd == -1) {
ret = -errno;
fprintf(stderr, "Failed to open %s\n", chrdev_name);
goto exit_free_name;
}
 
-   req.lineoffset = line;
-   req.handleflags = handleflags;
-   req.eventflags = eventflags;
-   strcpy(req.consumer_label, "gpio-event-mon");
-
-   ret = ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, );
-   if (ret == -1) {
-   ret = -errno;
-   fprintf(stderr, "Failed to issue GET EVENT "
-   "IOCTL (%d)\n",
-   ret);
-   goto exit_close_error;
-   }
+   ret = gpiotools_request_line(device_name, , 1, config,
+"gpio-event-mon");
+   if (ret < 0)
+   goto exit_device_close;
+   else
+   lfd = ret;
 
/* Read initial states */
-   ret = ioctl(req.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, );
-   if (ret == -1) {
-   ret = -errno;
-   fprintf(stderr, "Failed to issue GPIOHANDLE GET LINE "
-   "VALUES IOCTL (%d)\n",
+   values.mask = 1;
+   values.bits = 0;
+   ret = gpiotools_get_values(lfd, );
+   if (ret < 0) {
+   fprintf(stderr,
+   "Failed to issue GPIO LINE GET VALUES IOCTL (%d)\n",
ret);
-   goto exit_close_error;
+   goto exit_line_close;
}
 
fprintf(stdout, "Monitoring line %d on %s\n", line, device_name);
-   fprintf(stdout, "Initial line value: %d\n", data.values[0]);
+   fprintf(stdout, "Initial line value: %d\n",
+   gpiotools_test_bit(values.bits, 0));
 
while (1) {
-   struct gpioevent_data event;
+   struct gpio_v2_line_event event;
 
-   ret = read(req.fd, , sizeof(event));
+   ret = read(lfd, , sizeof(event));
if (ret == -1) {
if (errno == -EAGAIN) {
fprintf(stderr, "nothing available\n");
@@ -96,12 +90,14 @@ int monitor_device(const char *device_name,
ret = -EIO;
break;
}
-   fprintf(stdout, "GPIO EVENT %llu: ", event.timestamp);
+   fprintf(stdout, "GPIO EVENT at %llu on line %d (%d|%d) ",
+   event.timestamp, event.offset, event.line_seqno,
+   event.seqno);
switch (event.id) {
-   case GPIOEVENT_EVENT_RISING_EDGE:
+   case GPIO_V2_LINE_EVENT_RISING_EDGE:
fprintf(stdout, "rising edge");
break;
-   case GPIOEVENT_EVENT_FALLING_EDGE:
+   case GPIO_V2_LINE_EVENT_FALLING_EDGE:
fprintf(stdout, "falling edge");
break;
default:
@@ -114,8 +110,11 @@ int monitor_device(const char *device_name,
break;
}
 
-exit_close_error:
-   if (close(fd) == -1)
+exit_line_close:
+   if (close(lfd) == -1)
+   perror("Failed to close line file");
+exit_device_close:
+   if (close(cfd) == -1)
perror("Failed to close GPIO character device file");
 exit_free_name:
free(chrdev_name);
@@ -140,15 +139,20 @@ void print_usage(void)
);
 }
 
+#define EDGE_FLAGS \
+   (GPIO_V2_LINE_FLAG_EDGE_RISING | \
+GPIO_V2_LINE_FLAG_EDGE_FALLING)
+
 int main(int argc, char **argv)
 {
const char *device_name = NULL;
unsigned int line = -1;
unsigned int loops = 0;
-   uint32_t handleflags = GPIOHANDLE_REQUEST_INPUT;
-   uint32_t eventflags = 0;
+   struct gpio_v2_line_config config;
int c;
 
+   memset(, 0, 

[PATCH v4 14/20] tools: gpio: port lsgpio to v2 uAPI

2020-08-13 Thread Kent Gibson
Port the lsgpio tool to the latest GPIO uAPI.

Signed-off-by: Kent Gibson 
---
 tools/gpio/lsgpio.c | 60 -
 1 file changed, 38 insertions(+), 22 deletions(-)

diff --git a/tools/gpio/lsgpio.c b/tools/gpio/lsgpio.c
index b08d7a5e779b..deda38244026 100644
--- a/tools/gpio/lsgpio.c
+++ b/tools/gpio/lsgpio.c
@@ -25,57 +25,73 @@
 
 struct gpio_flag {
char *name;
-   unsigned long mask;
+   unsigned long long mask;
 };
 
 struct gpio_flag flagnames[] = {
{
-   .name = "kernel",
-   .mask = GPIOLINE_FLAG_KERNEL,
+   .name = "used",
+   .mask = GPIO_V2_LINE_FLAG_USED,
+   },
+   {
+   .name = "input",
+   .mask = GPIO_V2_LINE_FLAG_INPUT,
},
{
.name = "output",
-   .mask = GPIOLINE_FLAG_IS_OUT,
+   .mask = GPIO_V2_LINE_FLAG_OUTPUT,
},
{
.name = "active-low",
-   .mask = GPIOLINE_FLAG_ACTIVE_LOW,
+   .mask = GPIO_V2_LINE_FLAG_ACTIVE_LOW,
},
{
.name = "open-drain",
-   .mask = GPIOLINE_FLAG_OPEN_DRAIN,
+   .mask = GPIO_V2_LINE_FLAG_OPEN_DRAIN,
},
{
.name = "open-source",
-   .mask = GPIOLINE_FLAG_OPEN_SOURCE,
+   .mask = GPIO_V2_LINE_FLAG_OPEN_SOURCE,
},
{
.name = "pull-up",
-   .mask = GPIOLINE_FLAG_BIAS_PULL_UP,
+   .mask = GPIO_V2_LINE_FLAG_BIAS_PULL_UP,
},
{
.name = "pull-down",
-   .mask = GPIOLINE_FLAG_BIAS_PULL_DOWN,
+   .mask = GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN,
},
{
.name = "bias-disabled",
-   .mask = GPIOLINE_FLAG_BIAS_DISABLE,
+   .mask = GPIO_V2_LINE_FLAG_BIAS_DISABLED,
},
 };
 
-void print_flags(unsigned long flags)
+static void print_attributes(struct gpio_v2_line_info *info)
 {
int i;
-   int printed = 0;
+   const char *field_format = "%s";
 
for (i = 0; i < ARRAY_SIZE(flagnames); i++) {
-   if (flags & flagnames[i].mask) {
-   if (printed)
-   fprintf(stdout, " ");
-   fprintf(stdout, "%s", flagnames[i].name);
-   printed++;
+   if (info->flags & flagnames[i].mask) {
+   fprintf(stdout, field_format, flagnames[i].name);
+   field_format = ", %s";
}
}
+
+   if ((info->flags & GPIO_V2_LINE_FLAG_EDGE_RISING) &&
+   (info->flags & GPIO_V2_LINE_FLAG_EDGE_FALLING))
+   fprintf(stdout, field_format, "both-edges");
+   else if (info->flags & GPIO_V2_LINE_FLAG_EDGE_RISING)
+   fprintf(stdout, field_format, "rising-edge");
+   else if (info->flags & GPIO_V2_LINE_FLAG_EDGE_FALLING)
+   fprintf(stdout, field_format, "falling-edge");
+
+   for (i = 0; i < info->num_attrs; i++) {
+   if (info->attrs[i].id == GPIO_V2_LINE_ATTR_ID_DEBOUNCE)
+   fprintf(stdout, ", debounce_period=%dusec",
+   info->attrs[0].debounce_period);
+   }
 }
 
 int list_device(const char *device_name)
@@ -109,18 +125,18 @@ int list_device(const char *device_name)
 
/* Loop over the lines and print info */
for (i = 0; i < cinfo.lines; i++) {
-   struct gpioline_info linfo;
+   struct gpio_v2_line_info linfo;
 
memset(, 0, sizeof(linfo));
-   linfo.line_offset = i;
+   linfo.offset = i;
 
-   ret = ioctl(fd, GPIO_GET_LINEINFO_IOCTL, );
+   ret = ioctl(fd, GPIO_V2_GET_LINEINFO_IOCTL, );
if (ret == -1) {
ret = -errno;
perror("Failed to issue LINEINFO IOCTL\n");
goto exit_close_error;
}
-   fprintf(stdout, "\tline %2d:", linfo.line_offset);
+   fprintf(stdout, "\tline %2d:", linfo.offset);
if (linfo.name[0])
fprintf(stdout, " \"%s\"", linfo.name);
else
@@ -131,7 +147,7 @@ int list_device(const char *device_name)
fprintf(stdout, " unused");
if (linfo.flags) {
fprintf(stdout, " [");
-   print_flags(linfo.flags);
+   print_attributes();
fprintf(stdout, "]");
}
fprintf(stdout, "\n");
-- 
2.28.0



[PATCH v4 09/20] gpiolib: cdev: support edge detection for uAPI v2

2020-08-13 Thread Kent Gibson
Add support for edge detection to lines requested using
GPIO_V2_GET_LINE_IOCTL.

Signed-off-by: Kent Gibson 
---

The edge_detector implementation is based on the v1 lineevent implementation.

 drivers/gpio/gpiolib-cdev.c | 316 +++-
 drivers/gpio/gpiolib.c  |   2 +
 drivers/gpio/gpiolib.h  |   2 +
 3 files changed, 319 insertions(+), 1 deletion(-)

diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
index 28273f3105d3..1d42a01f5414 100644
--- a/drivers/gpio/gpiolib-cdev.c
+++ b/drivers/gpio/gpiolib-cdev.c
@@ -382,11 +382,43 @@ static int linehandle_create(struct gpio_device *gdev, 
void __user *ip)
 }
 #endif /* CONFIG_GPIO_CDEV_V1 */
 
+/**
+ * struct edge_detector - contains the state of a line edge detector
+ * @line: the corresponding line request
+ * @irq: the interrupt triggered in response to events on this GPIO
+ * @flags: the flags, GPIO_V2_LINE_FLAG_EDGE_RISING and/or
+ * GPIO_V2_LINE_FLAG_EDGE_FALLING, indicating the edge detection applied
+ * @timestamp: cache for the timestamp storing it between hardirq and IRQ
+ * thread, used to bring the timestamp close to the actual event
+ * @seqno: the seqno for the current edge event in the sequence of events
+ * for the corresponding line request. Ths is drawn from the @line.
+ * @line_seqno: the seqno for the current edge event in the sequence of
+ * events for this line.
+ */
+struct edge_detector {
+   struct line *line;
+   unsigned int irq;
+   u64 flags;
+   /*
+* timestamp and seqno are shared by edge_irq_handler() and
+* edge_irq_thread() which are themselves mutually exclusive.
+*/
+   u64 timestamp;
+   u32 seqno;
+   u32 line_seqno;
+};
+
 /**
  * struct line - contains the state of a userspace line request
  * @gdev: the GPIO device the line request pertains to
  * @label: consumer label used to tag descriptors
  * @num_descs: the number of descriptors held in the descs array
+ * @wait: wait queue that handles blocking reads of events
+ * @events: KFIFO for the GPIO events
+ * @seqno: the sequence number for edge events generated on all lines in
+ * this line request.  Note that this is not used when @num_descs is 1, as
+ * the line_seqno is then the same and is cheaper to calculate.
+ * @edets: an array of edge detectors, of size @num_descs
  * @descs: the GPIO descriptors held by this line request, with @num_descs
  * elements.
  */
@@ -394,9 +426,146 @@ struct line {
struct gpio_device *gdev;
const char *label;
u32 num_descs;
+   wait_queue_head_t wait;
+   DECLARE_KFIFO_PTR(events, struct gpio_v2_line_event);
+   atomic_t seqno;
+   struct edge_detector *edets;
struct gpio_desc *descs[];
 };
 
+static inline struct gpio_desc *edge_detector_desc(
+   const struct edge_detector *edet)
+{
+   return edet->line->descs[edet - >line->edets[0]];
+}
+
+static irqreturn_t edge_irq_thread(int irq, void *p)
+{
+   struct edge_detector *edet = p;
+   struct line *line = edet->line;
+   struct gpio_desc *desc = edge_detector_desc(edet);
+   struct gpio_v2_line_event le;
+   int ret;
+
+   /* Do not leak kernel stack to userspace */
+   memset(, 0, sizeof(le));
+
+   /*
+* We may be running from a nested threaded interrupt in which case
+* we didn't get the timestamp from edge_irq_handler().
+*/
+   if (!edet->timestamp) {
+   le.timestamp = ktime_get_ns();
+   if (line->num_descs != 1)
+   edet->seqno = atomic_inc_return(>seqno);
+   } else {
+   le.timestamp = edet->timestamp;
+   }
+   edet->timestamp = 0;
+
+   if (edet->flags == (GPIO_V2_LINE_FLAG_EDGE_RISING |
+   GPIO_V2_LINE_FLAG_EDGE_FALLING)) {
+   int level = gpiod_get_value_cansleep(desc);
+
+   if (level)
+   /* Emit low-to-high event */
+   le.id = GPIO_V2_LINE_EVENT_RISING_EDGE;
+   else
+   /* Emit high-to-low event */
+   le.id = GPIO_V2_LINE_EVENT_FALLING_EDGE;
+   } else if (edet->flags == GPIO_V2_LINE_FLAG_EDGE_RISING) {
+   /* Emit low-to-high event */
+   le.id = GPIO_V2_LINE_EVENT_RISING_EDGE;
+   } else if (edet->flags == GPIO_V2_LINE_FLAG_EDGE_FALLING) {
+   /* Emit high-to-low event */
+   le.id = GPIO_V2_LINE_EVENT_FALLING_EDGE;
+   } else {
+   return IRQ_NONE;
+   }
+   edet->line_seqno++;
+   le.line_seqno = edet->line_seqno;
+   le.seqno = (line->num_descs == 1) ? le.line_seqno : edet->seqno;
+   le.offset = gpio_chip_hwgpio(desc);
+
+   ret = kfifo_in_spinlocked_noirqsave(>events, ,
+   1, >wait.lock);
+   if (ret)
+   wake_up_poll(>wait, EPOLLIN);
+   else
+   

[PATCH v4 11/20] gpiolib: cdev: support GPIO_V2_LINE_SET_VALUES_IOCTL

2020-08-13 Thread Kent Gibson
Add support for the GPIO_V2_LINE_SET_VALUES_IOCTL.

Signed-off-by: Kent Gibson 
---
 drivers/gpio/gpiolib-cdev.c | 67 +
 1 file changed, 67 insertions(+)

diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
index 04472c2b6678..de88b7a5ba0f 100644
--- a/drivers/gpio/gpiolib-cdev.c
+++ b/drivers/gpio/gpiolib-cdev.c
@@ -811,6 +811,71 @@ static long line_get_values(struct line *line, void __user 
*ip)
return 0;
 }
 
+static long line_set_values_locked(struct line *line,
+  struct gpio_v2_line_values *lv)
+{
+   DECLARE_BITMAP(vals, GPIO_V2_LINES_MAX);
+   struct gpio_desc **descs;
+   int ret, i, didx, num_set = 0;
+
+   bitmap_zero(vals, GPIO_V2_LINES_MAX);
+   for (i = 0; i < line->num_descs; i++) {
+   if (lv->mask & BIT_ULL(i)) {
+   if (!test_bit(FLAG_IS_OUT, >descs[i]->flags))
+   return -EPERM;
+   if (lv->bits & BIT_ULL(i))
+   __set_bit(num_set, vals);
+   num_set++;
+   }
+   }
+   if (num_set == 0)
+   return -EINVAL;
+
+   if (num_set == line->num_descs)
+   /* Reuse the array setting function */
+   return gpiod_set_array_value_complex(false,
+true,
+line->num_descs,
+line->descs,
+NULL,
+vals);
+
+   /* build compacted desc array and values */
+   descs = kmalloc_array(num_set, sizeof(*descs), GFP_KERNEL);
+   for (didx = 0, i = 0; i < line->num_descs; i++) {
+   if (lv->mask & BIT_ULL(i)) {
+   descs[didx] = line->descs[i];
+   didx++;
+   }
+   }
+   ret = gpiod_set_array_value_complex(false,
+   true,
+   num_set,
+   descs,
+   NULL,
+   vals);
+
+   kfree(descs);
+   return ret;
+}
+
+static long line_set_values(struct line *line, void __user *ip)
+{
+   struct gpio_v2_line_values lv;
+   int ret;
+
+   if (copy_from_user(, ip, sizeof(lv)))
+   return -EFAULT;
+
+   mutex_lock(>config_mutex);
+
+   ret = line_set_values_locked(line, );
+
+   mutex_unlock(>config_mutex);
+
+   return ret;
+}
+
 static long line_set_config_locked(struct line *line,
   struct gpio_v2_line_config *lc)
 {
@@ -880,6 +945,8 @@ static long line_ioctl(struct file *file, unsigned int cmd,
 
if (cmd == GPIO_V2_LINE_GET_VALUES_IOCTL)
return line_get_values(line, ip);
+   else if (cmd == GPIO_V2_LINE_SET_VALUES_IOCTL)
+   return line_set_values(line, ip);
else if (cmd == GPIO_V2_LINE_SET_CONFIG_IOCTL)
return line_set_config(line, ip);
 
-- 
2.28.0



[PATCH v4 12/20] gpiolib: cdev: support setting debounce

2020-08-13 Thread Kent Gibson
Add support for setting debounce on a line via the GPIO uAPI.
Where debounce is not supported by hardware, a software debounce is
provided.

Signed-off-by: Kent Gibson 
---

The implementation of the software debouncer waits for the line to be
stable for the debounce period before determining if a level change,
and a corresponding edge event, has occurred.  This provides maximum
protection against glitches, but also introduces a debounce_period
latency to edge events.

The software debouncer is integrated with the edge detection as it
utilises the line interrupt, and integration is simpler than getting
the two to interwork.  Where software debounce AND edge detection is
required, the debouncer provides both.

Due to the tight integration between the debouncer and edge detection,
and to avoid particular corner cases, it is not allowed to alter the
debounce value if edge detection is enabled.  Changing the debounce with
edge detection enabled is a very unlikely use case, so it is preferable
to disallow it rather than complicate the code to allow it.
Should the user wish to alter the debounce value in such cases they will
need to release and re-request the line.

Changes for v4:
 - fix handling of mask in line_get_values

Changes for v3:
 - only GPIO_V2 field renaming

Changes for v2:
 - improve documentation on fields shared by threads.
 - use READ_ONCE/WRITE_ONCE for shared fields rather than atomic_t
   which was overkill.

 drivers/gpio/gpiolib-cdev.c | 265 +++-
 drivers/gpio/gpiolib.h  |   4 +
 2 files changed, 263 insertions(+), 6 deletions(-)

diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
index de88b7a5ba0f..77fabf815de8 100644
--- a/drivers/gpio/gpiolib-cdev.c
+++ b/drivers/gpio/gpiolib-cdev.c
@@ -6,6 +6,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -22,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "gpiolib.h"
@@ -395,6 +397,9 @@ static int linehandle_create(struct gpio_device *gdev, void 
__user *ip)
  * for the corresponding line request. Ths is drawn from the @line.
  * @line_seqno: the seqno for the current edge event in the sequence of
  * events for this line.
+ * @work: the worker that implements software debouncing
+ * @sw_debounced: flag indicating if the software debouncer is active
+ * @level: the current debounced physical level of the line
  */
 struct edge_detector {
struct line *line;
@@ -406,7 +411,27 @@ struct edge_detector {
 */
u64 timestamp;
u32 seqno;
+   /*
+* line_seqno is used by either edge_irq_thread() or
+* debounce_work_func() which are themselves mutually exclusive.
+*/
u32 line_seqno;
+   /*
+* -- debouncer specific fields --
+*/
+   struct delayed_work work;
+   /*
+* sw_debounce is shared by line_set_config(), which is the only
+* setter, and line_ioctl(), which can live with a slightly stale
+* value.
+*/
+   unsigned int sw_debounced;
+   /*
+* level is shared by debounce_work_func(), which is the only
+* setter, and line_ioctl() which can live with a slightly stale
+* value.
+*/
+   unsigned int level;
 };
 
 /**
@@ -523,6 +548,10 @@ static int edge_detector_start(struct edge_detector *edet)
int ret, irq, irqflags = 0;
struct gpio_desc *desc;
 
+   if (READ_ONCE(edet->sw_debounced))
+   /* debouncer is setup and will provide edge detection */
+   return 0;
+
desc = edge_detector_desc(edet);
irq = gpiod_to_irq(desc);
 
@@ -554,17 +583,215 @@ static int edge_detector_start(struct edge_detector 
*edet)
return 0;
 }
 
+/*
+ * returns the current debounced logical value.
+ */
+static int debounced_value(struct edge_detector *edet)
+{
+   int value;
+
+   /*
+* minor race - debouncer may be stopped here, so edge_detector_stop
+* must leave the value unchanged so the following will read the level
+* from when the debouncer was last running.
+*/
+   value = READ_ONCE(edet->level);
+
+   if (test_bit(FLAG_ACTIVE_LOW, _detector_desc(edet)->flags))
+   value = !value;
+
+   return value;
+}
+
+static irqreturn_t debounce_irq_handler(int irq, void *p)
+{
+   struct edge_detector *edet = p;
+   struct gpio_desc *desc = edge_detector_desc(edet);
+
+   mod_delayed_work(system_wq,
+>work,
+usecs_to_jiffies(READ_ONCE(desc->debounce_period)));
+
+   return IRQ_HANDLED;
+}
+
+static void debounce_work_func(struct work_struct *work)
+{
+   struct gpio_v2_line_event le;
+   int ret, level;
+   struct edge_detector *edet =
+   container_of(work, struct edge_detector, work.work);
+   struct gpio_desc *desc = edge_detector_desc(edet);
+   struct line *line;
+
+   

[PATCH v4 17/20] tools: gpio: port gpio-hammer to v2 uAPI

2020-08-13 Thread Kent Gibson
Port the gpio-hammer tool to the latest GPIO uAPI.

Signed-off-by: Kent Gibson 
---
 tools/gpio/gpio-hammer.c |  32 +++
 tools/gpio/gpio-utils.c  | 119 ++-
 tools/gpio/gpio-utils.h  |  50 +---
 3 files changed, 128 insertions(+), 73 deletions(-)

diff --git a/tools/gpio/gpio-hammer.c b/tools/gpio/gpio-hammer.c
index a2c7577fad5c..54fdf59dd320 100644
--- a/tools/gpio/gpio-hammer.c
+++ b/tools/gpio/gpio-hammer.c
@@ -25,23 +25,30 @@
 int hammer_device(const char *device_name, unsigned int *lines, int num_lines,
  unsigned int loops)
 {
-   struct gpiohandle_data data;
+   struct gpio_v2_line_values values;
+   struct gpio_v2_line_config config;
char swirr[] = "-\\|/";
int fd;
int ret;
int i, j;
unsigned int iteration = 0;
 
-   memset(, 0, sizeof(data.values));
-   ret = gpiotools_request_linehandle(device_name, lines, num_lines,
-  GPIOHANDLE_REQUEST_OUTPUT, ,
-  "gpio-hammer");
+   memset(, 0, sizeof(config));
+   config.flags = GPIO_V2_LINE_FLAG_OUTPUT;
+
+   ret = gpiotools_request_line(device_name, lines, num_lines,
+, "gpio-hammer");
if (ret < 0)
goto exit_error;
else
fd = ret;
 
-   ret = gpiotools_get_values(fd, );
+   values.mask = 0;
+   values.bits = 0;
+   for (i = 0; i < num_lines; i++)
+   gpiotools_set_bit(, i);
+
+   ret = gpiotools_get_values(fd, );
if (ret < 0)
goto exit_close_error;
 
@@ -53,7 +60,7 @@ int hammer_device(const char *device_name, unsigned int 
*lines, int num_lines,
}
fprintf(stdout, "] on %s, initial states: [", device_name);
for (i = 0; i < num_lines; i++) {
-   fprintf(stdout, "%d", data.values[i]);
+   fprintf(stdout, "%d", gpiotools_test_bit(values.bits, i));
if (i != (num_lines - 1))
fprintf(stdout, ", ");
}
@@ -64,14 +71,14 @@ int hammer_device(const char *device_name, unsigned int 
*lines, int num_lines,
while (1) {
/* Invert all lines so we blink */
for (i = 0; i < num_lines; i++)
-   data.values[i] = !data.values[i];
+   gpiotools_change_bit(, i);
 
-   ret = gpiotools_set_values(fd, );
+   ret = gpiotools_set_values(fd, );
if (ret < 0)
goto exit_close_error;
 
/* Re-read values to get status */
-   ret = gpiotools_get_values(fd, );
+   ret = gpiotools_get_values(fd, );
if (ret < 0)
goto exit_close_error;
 
@@ -82,7 +89,8 @@ int hammer_device(const char *device_name, unsigned int 
*lines, int num_lines,
 
fprintf(stdout, "[");
for (i = 0; i < num_lines; i++) {
-   fprintf(stdout, "%d: %d", lines[i], data.values[i]);
+   fprintf(stdout, "%d: %d", lines[i],
+   gpiotools_test_bit(values.bits, i));
if (i != (num_lines - 1))
fprintf(stdout, ", ");
}
@@ -97,7 +105,7 @@ int hammer_device(const char *device_name, unsigned int 
*lines, int num_lines,
ret = 0;
 
 exit_close_error:
-   gpiotools_release_linehandle(fd);
+   gpiotools_release_line(fd);
 exit_error:
return ret;
 }
diff --git a/tools/gpio/gpio-utils.c b/tools/gpio/gpio-utils.c
index d527980bcb94..68edc1a329e2 100644
--- a/tools/gpio/gpio-utils.c
+++ b/tools/gpio/gpio-utils.c
@@ -33,34 +33,32 @@
  * release these lines.
  */
 /**
- * gpiotools_request_linehandle() - request gpio lines in a gpiochip
+ * gpiotools_request_line() - request gpio lines in a gpiochip
  * @device_name:   The name of gpiochip without prefix "/dev/",
  * such as "gpiochip0"
  * @lines: An array desired lines, specified by offset
  * index for the associated GPIO device.
  * @num_lines: The number of lines to request.
- * @flag:  The new flag for requsted gpio. Reference
- * "linux/gpio.h" for the meaning of flag.
- * @data:  Default value will be set to gpio when flag is
- * GPIOHANDLE_REQUEST_OUTPUT.
- * @consumer_label:The name of consumer, such as "sysfs",
+ * @config:The new config for requested gpio. Reference
+ * "linux/gpio.h" for config details.
+ * @consumer:  The name of consumer, such as "sysfs",
  * "powerkey". This is useful for other users to
  * know who is using.
  *
  * Request gpio lines through the ioctl provided by chardev. User
  * could call 

[PATCH v4 15/20] tools: gpio: port gpio-watch to v2 uAPI

2020-08-13 Thread Kent Gibson
Port the gpio-watch tool to the latest GPIO uAPI.

Signed-off-by: Kent Gibson 
---
 tools/gpio/gpio-watch.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/tools/gpio/gpio-watch.c b/tools/gpio/gpio-watch.c
index 5cea24fddfa7..6f048350a27e 100644
--- a/tools/gpio/gpio-watch.c
+++ b/tools/gpio/gpio-watch.c
@@ -21,8 +21,8 @@
 
 int main(int argc, char **argv)
 {
-   struct gpioline_info_changed chg;
-   struct gpioline_info req;
+   struct gpio_v2_line_info_changed chg;
+   struct gpio_v2_line_info req;
struct pollfd pfd;
int fd, i, j, ret;
char *event, *end;
@@ -40,11 +40,11 @@ int main(int argc, char **argv)
for (i = 0, j = 2; i < argc - 2; i++, j++) {
memset(, 0, sizeof(req));
 
-   req.line_offset = strtoul(argv[j], , 0);
+   req.offset = strtoul(argv[j], , 0);
if (*end != '\0')
goto err_usage;
 
-   ret = ioctl(fd, GPIO_GET_LINEINFO_WATCH_IOCTL, );
+   ret = ioctl(fd, GPIO_V2_GET_LINEINFO_WATCH_IOCTL, );
if (ret) {
perror("unable to set up line watch");
return EXIT_FAILURE;
@@ -71,13 +71,13 @@ int main(int argc, char **argv)
}
 
switch (chg.event_type) {
-   case GPIOLINE_CHANGED_REQUESTED:
+   case GPIO_V2_LINE_CHANGED_REQUESTED:
event = "requested";
break;
-   case GPIOLINE_CHANGED_RELEASED:
+   case GPIO_V2_LINE_CHANGED_RELEASED:
event = "released";
break;
-   case GPIOLINE_CHANGED_CONFIG:
+   case GPIO_V2_LINE_CHANGED_CONFIG:
event = "config changed";
break;
default:
@@ -87,7 +87,7 @@ int main(int argc, char **argv)
}
 
printf("line %u: %s at %llu\n",
-  chg.info.line_offset, event, chg.timestamp);
+  chg.info.offset, event, chg.timestamp);
}
}
 
-- 
2.28.0



[PATCH v4 10/20] gpiolib: cdev: support GPIO_V2_LINE_SET_CONFIG_IOCTL

2020-08-13 Thread Kent Gibson
Add support for GPIO_V2_LINE_SET_CONFIG_IOCTL, the uAPI v2
line set config ioctl.

Signed-off-by: Kent Gibson 
---
 drivers/gpio/gpiolib-cdev.c | 92 +
 1 file changed, 92 insertions(+)

diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
index 1d42a01f5414..04472c2b6678 100644
--- a/drivers/gpio/gpiolib-cdev.c
+++ b/drivers/gpio/gpiolib-cdev.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -418,6 +419,8 @@ struct edge_detector {
  * @seqno: the sequence number for edge events generated on all lines in
  * this line request.  Note that this is not used when @num_descs is 1, as
  * the line_seqno is then the same and is cheaper to calculate.
+ * @config_mutex: mutex for serializing ioctl() calls to ensure consistency
+ * of configuration, particularly multi-step accesses to desc flags.
  * @edets: an array of edge detectors, of size @num_descs
  * @descs: the GPIO descriptors held by this line request, with @num_descs
  * elements.
@@ -429,6 +432,7 @@ struct line {
wait_queue_head_t wait;
DECLARE_KFIFO_PTR(events, struct gpio_v2_line_event);
atomic_t seqno;
+   struct mutex config_mutex;
struct edge_detector *edets;
struct gpio_desc *descs[];
 };
@@ -703,6 +707,30 @@ static int gpio_v2_line_config_validate(struct 
gpio_v2_line_config *lc,
return 0;
 }
 
+static int gpio_v2_line_config_change_validate(struct line *line,
+  struct gpio_v2_line_config *lc)
+{
+   int i;
+   u64 flags;
+   struct gpio_desc *desc;
+
+   for (i = 0; i < line->num_descs; i++) {
+   desc = line->descs[i];
+   flags = gpio_v2_line_config_flags(lc, i);
+   /* disallow edge detection changes */
+   if (line->edets[i].flags != (flags & GPIO_V2_LINE_EDGE_FLAGS))
+   return -EINVAL;
+
+   if (line->edets[i].flags) {
+   /* disallow polarity changes */
+   if (test_bit(FLAG_ACTIVE_LOW, >flags) !=
+   ((flags & GPIO_V2_LINE_FLAG_ACTIVE_LOW) != 0))
+   return -EINVAL;
+   }
+   }
+   return 0;
+}
+
 static void gpio_v2_line_config_flags_to_desc_flags(u64 flags,
unsigned long *flagsp)
 {
@@ -783,6 +811,67 @@ static long line_get_values(struct line *line, void __user 
*ip)
return 0;
 }
 
+static long line_set_config_locked(struct line *line,
+  struct gpio_v2_line_config *lc)
+{
+   struct gpio_desc *desc;
+   int i, ret;
+   u64 flags;
+
+   ret = gpio_v2_line_config_change_validate(line, lc);
+   if (ret)
+   return ret;
+
+   for (i = 0; i < line->num_descs; i++) {
+   desc = line->descs[i];
+   flags = gpio_v2_line_config_flags(lc, i);
+
+   gpio_v2_line_config_flags_to_desc_flags(flags, >flags);
+   /*
+* Lines have to be requested explicitly for input
+* or output, else the line will be treated "as is".
+*/
+   if (flags & GPIO_V2_LINE_FLAG_OUTPUT) {
+   int val = gpio_v2_line_config_output_value(lc, i);
+
+   edge_detector_stop(>edets[i]);
+   ret = gpiod_direction_output(desc, val);
+   if (ret)
+   return ret;
+   } else if (flags & GPIO_V2_LINE_FLAG_INPUT) {
+   ret = gpiod_direction_input(desc);
+   if (ret)
+   return ret;
+   }
+
+   blocking_notifier_call_chain(>gdev->notifier,
+GPIO_V2_LINE_CHANGED_CONFIG,
+desc);
+   }
+   return 0;
+}
+
+static long line_set_config(struct line *line, void __user *ip)
+{
+   struct gpio_v2_line_config lc;
+   int ret;
+
+   if (copy_from_user(, ip, sizeof(lc)))
+   return -EFAULT;
+
+   ret = gpio_v2_line_config_validate(, line->num_descs);
+   if (ret)
+   return ret;
+
+   mutex_lock(>config_mutex);
+
+   ret = line_set_config_locked(line, );
+
+   mutex_unlock(>config_mutex);
+
+   return ret;
+}
+
 static long line_ioctl(struct file *file, unsigned int cmd,
   unsigned long arg)
 {
@@ -791,6 +880,8 @@ static long line_ioctl(struct file *file, unsigned int cmd,
 
if (cmd == GPIO_V2_LINE_GET_VALUES_IOCTL)
return line_get_values(line, ip);
+   else if (cmd == GPIO_V2_LINE_SET_CONFIG_IOCTL)
+   return line_set_config(line, ip);
 
return -EINVAL;
 }
@@ -964,6 +1055,7 @@ static int line_create(struct gpio_device *gdev, void 
__user 

[PATCH v4 13/20] gpio: uapi: document uAPI v1 as deprecated

2020-08-13 Thread Kent Gibson
Update uAPI documentation to deprecate v1 structs and ioctls.

Signed-off-by: Kent Gibson 
---
 include/uapi/linux/gpio.h | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/include/uapi/linux/gpio.h b/include/uapi/linux/gpio.h
index 0eb1f53b47e0..4af67415d73e 100644
--- a/include/uapi/linux/gpio.h
+++ b/include/uapi/linux/gpio.h
@@ -274,6 +274,9 @@ struct gpio_v2_line_event {
 
 /*
  *  ABI v1
+ *
+ * This version of the ABI is deprecated and will be removed in the future.
+ * Use the latest version of the ABI, defined above, instead.
  */
 
 /* Informational flags */
@@ -297,6 +300,9 @@ struct gpio_v2_line_event {
  * @consumer: a functional name for the consumer of this GPIO line as set by
  * whatever is using it, will be empty if there is no current user but may
  * also be empty if the consumer doesn't set this up
+ *
+ * This struct is part of ABI v1 and is deprecated.
+ * Use struct gpio_v2_line_info instead.
  */
 struct gpioline_info {
__u32 line_offset;
@@ -328,6 +334,9 @@ enum {
  * guarantee there are no implicit holes between it and subsequent members.
  * The 20-byte padding at the end makes sure we don't add any implicit padding
  * at the end of the structure on 64-bit architectures.
+ *
+ * This struct is part of ABI v1 and is deprecated.
+ * Use struct gpio_v2_line_info_changed instead.
  */
 struct gpioline_info_changed {
struct gpioline_info info;
@@ -367,6 +376,9 @@ struct gpioline_info_changed {
  * @fd: if successful this field will contain a valid anonymous file handle
  * after a GPIO_GET_LINEHANDLE_IOCTL operation, zero or negative value
  * means error
+ *
+ * This struct is part of ABI v1 and is deprecated.
+ * Use struct gpio_v2_line_request instead.
  */
 struct gpiohandle_request {
__u32 lineoffsets[GPIOHANDLES_MAX];
@@ -386,6 +398,9 @@ struct gpiohandle_request {
  * this specifies the default output value, should be 0 (low) or
  * 1 (high), anything else than 0 or 1 will be interpreted as 1 (high)
  * @padding: reserved for future use and should be zero filled
+ *
+ * This struct is part of ABI v1 and is deprecated.
+ * Use struct gpio_v2_line_config instead.
  */
 struct gpiohandle_config {
__u32 flags;
@@ -398,6 +413,9 @@ struct gpiohandle_config {
  * @values: when getting the state of lines this contains the current
  * state of a line, when setting the state of lines these should contain
  * the desired target state
+ *
+ * This struct is part of ABI v1 and is deprecated.
+ * Use struct gpio_v2_line_values instead.
  */
 struct gpiohandle_data {
__u8 values[GPIOHANDLES_MAX];
@@ -421,6 +439,9 @@ struct gpiohandle_data {
  * @fd: if successful this field will contain a valid anonymous file handle
  * after a GPIO_GET_LINEEVENT_IOCTL operation, zero or negative value
  * means error
+ *
+ * This struct is part of ABI v1 and is deprecated.
+ * Use struct gpio_v2_line_request instead.
  */
 struct gpioevent_request {
__u32 lineoffset;
@@ -440,6 +461,9 @@ struct gpioevent_request {
  * struct gpioevent_data - The actual event being pushed to userspace
  * @timestamp: best estimate of time of event occurrence, in nanoseconds
  * @id: event identifier
+ *
+ * This struct is part of ABI v1 and is deprecated.
+ * Use struct gpio_v2_line_event instead.
  */
 struct gpioevent_data {
__u64 timestamp;
@@ -464,6 +488,8 @@ struct gpioevent_data {
 
 /*
  * v1 ioctl()s
+ *
+ * These ioctl()s are deprecated.  Use the v2 equivalent instead.
  */
 #define GPIO_GET_LINEINFO_IOCTL _IOWR(0xB4, 0x02, struct gpioline_info)
 #define GPIO_GET_LINEHANDLE_IOCTL _IOWR(0xB4, 0x03, struct gpiohandle_request)
-- 
2.28.0



[PATCH v4 08/20] gpiolib: cdev: support GPIO_V2_GET_LINEINFO_IOCTL and GPIO_V2_GET_LINEINFO_WATCH_IOCTL

2020-08-13 Thread Kent Gibson
Add support for GPIO_V2_GET_LINEINFO_IOCTL and
GPIO_V2_GET_LINEINFO_WATCH_IOCTL.

Signed-off-by: Kent Gibson 
---

The core of this change is the event kfifo switching to contain
struct gpioline_info_changed_v2, instead of v1 as v2 is richer.

The two uAPI versions are mostly independent - other than where they both
provide line info changes via reads on the chip fd.  As the info change
structs differ between v1 and v2, the infowatch implementation tracks which
version of the infowatch ioctl, either GPIO_GET_LINEINFO_WATCH_IOCTL or
GPIO_V2_GET_LINEINFO_WATCH_IOCTL, initiates the initial watch and returns
the corresponding info change struct to the read.  The version supported
on that fd locks to that version on the first watch request, so subsequent
watches from that process must use the same uAPI version.

Changes for v4:
 - replace strncpy with memcpy in gpio_v2_line_info_to_v1

 drivers/gpio/gpiolib-cdev.c | 194 +++-
 1 file changed, 167 insertions(+), 27 deletions(-)

diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
index 8671e04ff989..28273f3105d3 100644
--- a/drivers/gpio/gpiolib-cdev.c
+++ b/drivers/gpio/gpiolib-cdev.c
@@ -162,7 +162,8 @@ static long linehandle_set_config(struct linehandle_state 
*lh,
}
 
blocking_notifier_call_chain(>gdev->notifier,
-GPIOLINE_CHANGED_CONFIG, desc);
+GPIO_V2_LINE_CHANGED_CONFIG,
+desc);
}
return 0;
 }
@@ -334,7 +335,7 @@ static int linehandle_create(struct gpio_device *gdev, void 
__user *ip)
}
 
blocking_notifier_call_chain(>gdev->notifier,
-GPIOLINE_CHANGED_REQUESTED, desc);
+GPIO_V2_LINE_CHANGED_REQUESTED, 
desc);
 
dev_dbg(>dev, "registered chardev handle for line %d\n",
offset);
@@ -716,7 +717,7 @@ static int line_create(struct gpio_device *gdev, void 
__user *ip)
}
 
blocking_notifier_call_chain(>gdev->notifier,
-GPIOLINE_CHANGED_REQUESTED, desc);
+GPIO_V2_LINE_CHANGED_REQUESTED, 
desc);
 
dev_dbg(>dev, "registered chardev handle for line %d\n",
offset);
@@ -1065,7 +1066,7 @@ static int lineevent_create(struct gpio_device *gdev, 
void __user *ip)
goto out_free_le;
 
blocking_notifier_call_chain(>gdev->notifier,
-GPIOLINE_CHANGED_REQUESTED, desc);
+GPIO_V2_LINE_CHANGED_REQUESTED, desc);
 
irq = gpiod_to_irq(desc);
if (irq <= 0) {
@@ -1132,17 +1133,59 @@ static int lineevent_create(struct gpio_device *gdev, 
void __user *ip)
return ret;
 }
 
+static void gpio_v2_line_info_to_v1(struct gpio_v2_line_info *info_v2,
+   struct gpioline_info *info_v1)
+{
+   int flagsv2 = info_v2->flags;
+
+   memcpy(info_v1->name, info_v2->name, sizeof(info_v1->name));
+   memcpy(info_v1->consumer, info_v2->consumer,
+  sizeof(info_v1->consumer));
+   info_v1->line_offset = info_v2->offset;
+   info_v1->flags = 0;
+
+   if (flagsv2 & GPIO_V2_LINE_FLAG_USED)
+   info_v1->flags |= GPIOLINE_FLAG_KERNEL;
+
+   if (flagsv2 & GPIO_V2_LINE_FLAG_OUTPUT)
+   info_v1->flags |= GPIOLINE_FLAG_IS_OUT;
+
+   if (flagsv2 & GPIO_V2_LINE_FLAG_ACTIVE_LOW)
+   info_v1->flags |= GPIOLINE_FLAG_ACTIVE_LOW;
+
+   if (flagsv2 & GPIO_V2_LINE_FLAG_OPEN_DRAIN)
+   info_v1->flags |= GPIOLINE_FLAG_OPEN_DRAIN;
+   if (flagsv2 & GPIO_V2_LINE_FLAG_OPEN_SOURCE)
+   info_v1->flags |= GPIOLINE_FLAG_OPEN_SOURCE;
+
+   if (flagsv2 & GPIO_V2_LINE_FLAG_BIAS_PULL_UP)
+   info_v1->flags |= GPIOLINE_FLAG_BIAS_PULL_UP;
+   if (flagsv2 & GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN)
+   info_v1->flags |= GPIOLINE_FLAG_BIAS_PULL_DOWN;
+   if (flagsv2 & GPIO_V2_LINE_FLAG_BIAS_DISABLED)
+   info_v1->flags |= GPIOLINE_FLAG_BIAS_DISABLE;
+}
+
+static void gpio_v2_line_info_changed_to_v1(
+   struct gpio_v2_line_info_changed *lic_v2,
+   struct gpioline_info_changed *lic_v1)
+{
+   gpio_v2_line_info_to_v1(_v2->info, _v1->info);
+   lic_v1->timestamp = lic_v2->timestamp;
+   lic_v1->event_type = lic_v2->event_type;
+}
+
 #endif /* CONFIG_GPIO_CDEV_V1 */
 
 static void gpio_desc_to_lineinfo(struct gpio_desc *desc,
- struct gpioline_info *info)
+ struct gpio_v2_line_info *info)
 {
struct gpio_chip *gc = desc->gdev->chip;
bool ok_for_pinctrl;
unsigned long flags;
 

[PATCH v4 06/20] gpiolib: add build option for CDEV v1 ABI

2020-08-13 Thread Kent Gibson
Add a build option to allow the removal of the CDEV v1 ABI.

Suggested-by: Bartosz Golaszewski 
Signed-off-by: Kent Gibson 
---

This patch is before the v2 implementation, and is non-functional until
that patch, as some parts of that patch would be written slightly
differently if removing v1 was not considered.
Adding this patch after that would necessitate revisiting the v2 changes,
so this ordering results in two simpler patches.

 drivers/gpio/Kconfig | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 8e409b9c33dc..0c62e35cf3a6 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -82,6 +82,18 @@ config GPIO_CDEV
 
  If unsure, say Y.
 
+config GPIO_CDEV_V1
+   bool "Support GPIO ABI Version 1"
+   default y
+   depends on GPIO_CDEV
+   help
+ Say Y here to support version 1 of the GPIO CDEV ABI.
+
+ This ABI version is deprecated and will be removed in the future.
+ Please use the latest ABI for new developments.
+
+ If unsure, say Y.
+
 config GPIO_GENERIC
depends on HAS_IOMEM # Only for IOMEM drivers
tristate
-- 
2.28.0



[PATCH v4 07/20] gpiolib: cdev: support GPIO_V2_GET_LINE_IOCTL and GPIO_V2_LINE_GET_VALUES_IOCTL

2020-08-13 Thread Kent Gibson
Add support for requesting lines using the GPIO_V2_GET_LINE_IOCTL, and
returning their current values using GPIO_V2_LINE_GET_VALUES_IOCTL.

Signed-off-by: Kent Gibson 
---

The struct line implementation is based on the v1 struct linehandle
implementation.

The line_ioctl() is a simple wrapper around line_get_values() here, but
will be extended with other ioctls in subsequent patches.

Changes for v4:
 - fix handling of mask in line_get_values

 drivers/gpio/gpiolib-cdev.c | 413 
 1 file changed, 413 insertions(+)

diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
index 8b012879fe3f..8671e04ff989 100644
--- a/drivers/gpio/gpiolib-cdev.c
+++ b/drivers/gpio/gpiolib-cdev.c
@@ -1,7 +1,9 @@
 // SPDX-License-Identifier: GPL-2.0
 
 #include 
+#include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -34,6 +36,7 @@
  * GPIO line handle management
  */
 
+#ifdef CONFIG_GPIO_CDEV_V1
 /**
  * struct linehandle_state - contains the state of a userspace handle
  * @gdev: the GPIO device the handle pertains to
@@ -376,6 +379,390 @@ static int linehandle_create(struct gpio_device *gdev, 
void __user *ip)
linehandle_free(lh);
return ret;
 }
+#endif /* CONFIG_GPIO_CDEV_V1 */
+
+/**
+ * struct line - contains the state of a userspace line request
+ * @gdev: the GPIO device the line request pertains to
+ * @label: consumer label used to tag descriptors
+ * @num_descs: the number of descriptors held in the descs array
+ * @descs: the GPIO descriptors held by this line request, with @num_descs
+ * elements.
+ */
+struct line {
+   struct gpio_device *gdev;
+   const char *label;
+   u32 num_descs;
+   struct gpio_desc *descs[];
+};
+
+#define GPIO_V2_LINE_BIAS_FLAGS \
+   (GPIO_V2_LINE_FLAG_BIAS_PULL_UP | \
+GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN | \
+GPIO_V2_LINE_FLAG_BIAS_DISABLED)
+
+#define GPIO_V2_LINE_DIRECTION_FLAGS \
+   (GPIO_V2_LINE_FLAG_INPUT | \
+GPIO_V2_LINE_FLAG_OUTPUT)
+
+#define GPIO_V2_LINE_DRIVE_FLAGS \
+   (GPIO_V2_LINE_FLAG_OPEN_DRAIN | \
+GPIO_V2_LINE_FLAG_OPEN_SOURCE)
+
+#define GPIO_V2_LINE_VALID_FLAGS \
+   (GPIO_V2_LINE_FLAG_ACTIVE_LOW | \
+GPIO_V2_LINE_DIRECTION_FLAGS | \
+GPIO_V2_LINE_DRIVE_FLAGS | \
+GPIO_V2_LINE_BIAS_FLAGS)
+
+static u64 gpio_v2_line_config_flags(struct gpio_v2_line_config *lc,
+int line_idx)
+{
+   int i;
+   u64 mask = BIT_ULL(line_idx);
+
+   for (i = 0; i < lc->num_attrs; i++) {
+   if ((lc->attrs[i].attr.id == GPIO_V2_LINE_ATTR_ID_FLAGS) &&
+   (lc->attrs[i].mask & mask))
+   return lc->attrs[i].attr.flags;
+   }
+   return lc->flags;
+}
+
+static int gpio_v2_line_config_output_value(struct gpio_v2_line_config *lc,
+   int line_idx)
+{
+   int i;
+   u64 mask = BIT_ULL(line_idx);
+
+   for (i = 0; i < lc->num_attrs; i++) {
+   if ((lc->attrs[i].attr.id == 
GPIO_V2_LINE_ATTR_ID_OUTPUT_VALUES) &&
+   (lc->attrs[i].mask & mask))
+   return !!(lc->attrs[i].attr.values & mask);
+   }
+   return 0;
+}
+
+static int gpio_v2_line_flags_validate(u64 flags)
+{
+   /* Return an error if an unknown flag is set */
+   if (flags & ~GPIO_V2_LINE_VALID_FLAGS)
+   return -EINVAL;
+
+   /*
+* Do not allow both INPUT & OUTPUT flags to be set as they are
+* contradictory.
+*/
+   if ((flags & GPIO_V2_LINE_FLAG_INPUT) &&
+   (flags & GPIO_V2_LINE_FLAG_OUTPUT))
+   return -EINVAL;
+
+   /*
+* Do not allow OPEN_SOURCE & OPEN_DRAIN flags in a single request. If
+* the hardware actually supports enabling both at the same time the
+* electrical result would be disastrous.
+*/
+   if ((flags & GPIO_V2_LINE_FLAG_OPEN_DRAIN) &&
+   (flags & GPIO_V2_LINE_FLAG_OPEN_SOURCE))
+   return -EINVAL;
+
+   /* Drive requires explicit output direction. */
+   if ((flags & GPIO_V2_LINE_DRIVE_FLAGS) &&
+   !(flags & GPIO_V2_LINE_FLAG_OUTPUT))
+   return -EINVAL;
+
+   /* Bias requies explicit direction. */
+   if ((flags & GPIO_V2_LINE_BIAS_FLAGS) &&
+   !(flags & GPIO_V2_LINE_DIRECTION_FLAGS))
+   return -EINVAL;
+
+   /* Only one bias flag can be set. */
+   if (((flags & GPIO_V2_LINE_FLAG_BIAS_DISABLED) &&
+(flags & (GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN |
+  GPIO_V2_LINE_FLAG_BIAS_PULL_UP))) ||
+   ((flags & GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN) &&
+(flags & GPIO_V2_LINE_FLAG_BIAS_PULL_UP)))
+   return -EINVAL;
+
+   return 0;
+}
+
+static int gpio_v2_line_config_validate(struct gpio_v2_line_config *lc,
+   int num_lines)
+{
+   int i, ret;
+   u64 

Re: [PATCH] bootconfig: Fix off-by-one in xbc_node_compose_key_after()

2020-08-13 Thread Steven Rostedt
On Thu, 13 Aug 2020 19:38:18 -0700
Andrew Morton  wrote:

> On Thu, 13 Aug 2020 18:30:50 -0400 Steven Rostedt  wrote:
> 
> > From: Steven Rostedt (VMware) 
> > 
> > While reviewing some patches for bootconfig, I noticed the following
> > code in xbc_node_compose_key_after():
> > 
> > ret = snprintf(buf, size, "%s%s", xbc_node_get_data(node),
> >depth ? "." : "");
> > if (ret < 0)
> > return ret;
> > if (ret > size) {
> > size = 0;
> > } else {
> > size -= ret;
> > buf += ret;
> > }
> > 
> > But snprintf() returns the number of bytes that would be written, not
> > the number of bytes that are written (ignoring the nul terminator).
> > This means that if the number of non null bytes written were to equal
> > size, then the nul byte, which snprintf() always adds, will overwrite
> > that last byte.
> > 
> > ret = snprintf(buf, 5, "hello");
> > printf("buf = '%s'\n", buf);
> > printf("ret = %d\n", ret);
> > 
> > produces:
> > 
> > buf = 'hell'
> > ret = 5
> > 
> > The string was truncated without ret being greater than 5.
> > Test (ret >= size) for overwrite.  
> 
> What are the end-user visible effects of the bug?  IOW, why cc:stable?
> 

Hmm, looking at it at a wider view, it may not be an issue. The tools
code calls this code, and I looked to see if it was possible to corrupt
the buffer by an incorrect size. But now that I'm looking at the else
part of the section, it may not be a problem as it may act the same.

That is, ret == size will make size = 0 with the size -= ret, and we
get the same result.

OK, you can drop the patch. Thanks for the review!

Although, there's no error message if the buffer is not big enough to
hold the fields.

Masami?

-- Steve


[PATCH v4 03/20] gpio: uapi: define GPIO_MAX_NAME_SIZE for array sizes

2020-08-13 Thread Kent Gibson
Replace constant array sizes with a macro constant to clarify the source
of array sizes, provide a place to document any constraints on the size,
and to simplify array sizing in userspace if constructing structs
from their composite fields.

Signed-off-by: Kent Gibson 
---
 include/uapi/linux/gpio.h | 17 +++--
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/include/uapi/linux/gpio.h b/include/uapi/linux/gpio.h
index 9c27cecf406f..285cc10355b2 100644
--- a/include/uapi/linux/gpio.h
+++ b/include/uapi/linux/gpio.h
@@ -14,6 +14,11 @@
 #include 
 #include 
 
+/*
+ * The maximum size of name and label arrays.
+ */
+#define GPIO_MAX_NAME_SIZE 32
+
 /**
  * struct gpiochip_info - Information about a certain GPIO chip
  * @name: the Linux kernel name of this GPIO chip
@@ -22,8 +27,8 @@
  * @lines: number of GPIO lines on this chip
  */
 struct gpiochip_info {
-   char name[32];
-   char label[32];
+   char name[GPIO_MAX_NAME_SIZE];
+   char label[GPIO_MAX_NAME_SIZE];
__u32 lines;
 };
 
@@ -52,8 +57,8 @@ struct gpiochip_info {
 struct gpioline_info {
__u32 line_offset;
__u32 flags;
-   char name[32];
-   char consumer[32];
+   char name[GPIO_MAX_NAME_SIZE];
+   char consumer[GPIO_MAX_NAME_SIZE];
 };
 
 /* Maximum number of requested handles */
@@ -123,7 +128,7 @@ struct gpiohandle_request {
__u32 lineoffsets[GPIOHANDLES_MAX];
__u32 flags;
__u8 default_values[GPIOHANDLES_MAX];
-   char consumer_label[32];
+   char consumer_label[GPIO_MAX_NAME_SIZE];
__u32 lines;
int fd;
 };
@@ -182,7 +187,7 @@ struct gpioevent_request {
__u32 lineoffset;
__u32 handleflags;
__u32 eventflags;
-   char consumer_label[32];
+   char consumer_label[GPIO_MAX_NAME_SIZE];
int fd;
 };
 
-- 
2.28.0



[PATCH v4 05/20] gpiolib: make cdev a build option

2020-08-13 Thread Kent Gibson
Make the gpiolib-cdev module a build option.  This allows the CDEV
interface to be removed from the kernel to reduce kernel size in
applications where is it not required, and provides the parent for
other other CDEV interface specific build options to follow.

Suggested-by: Bartosz Golaszewski 
Signed-off-by: Kent Gibson 
---
 drivers/gpio/Kconfig| 17 +++--
 drivers/gpio/Makefile   |  2 +-
 drivers/gpio/gpiolib-cdev.h | 15 +++
 3 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 8030fd91a3cc..8e409b9c33dc 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -66,8 +66,21 @@ config GPIO_SYSFS
 
  This ABI is deprecated. If you want to use GPIO from userspace,
  use the character device /dev/gpiochipN with the appropriate
- ioctl() operations instead. The character device is always
- available.
+ ioctl() operations instead.
+
+config GPIO_CDEV
+   bool
+   prompt "Character device (/dev/gpiochipN) support" if EXPERT
+   default y
+   help
+ Say Y here to add the character device /dev/gpiochipN interface
+ for GPIOs. The character device allows userspace to control GPIOs
+ using ioctl() operations.
+
+ Only say N if you are sure that the GPIO character device is not
+ required.
+
+ If unsure, say Y.
 
 config GPIO_GENERIC
depends on HAS_IOMEM # Only for IOMEM drivers
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 4f9abff4f2dc..7c24c8d77068 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -7,8 +7,8 @@ obj-$(CONFIG_GPIOLIB)   += gpiolib.o
 obj-$(CONFIG_GPIOLIB)  += gpiolib-devres.o
 obj-$(CONFIG_GPIOLIB)  += gpiolib-legacy.o
 obj-$(CONFIG_GPIOLIB)  += gpiolib-devprop.o
-obj-$(CONFIG_GPIOLIB)  += gpiolib-cdev.o
 obj-$(CONFIG_OF_GPIO)  += gpiolib-of.o
+obj-$(CONFIG_GPIO_CDEV)+= gpiolib-cdev.o
 obj-$(CONFIG_GPIO_SYSFS)   += gpiolib-sysfs.o
 obj-$(CONFIG_GPIO_ACPI)+= gpiolib-acpi.o
 
diff --git a/drivers/gpio/gpiolib-cdev.h b/drivers/gpio/gpiolib-cdev.h
index 973578e7ad10..19a4e3d57120 100644
--- a/drivers/gpio/gpiolib-cdev.h
+++ b/drivers/gpio/gpiolib-cdev.h
@@ -5,7 +5,22 @@
 
 #include 
 
+#ifdef CONFIG_GPIO_CDEV
+
 int gpiolib_cdev_register(struct gpio_device *gdev, dev_t devt);
 void gpiolib_cdev_unregister(struct gpio_device *gdev);
 
+#else
+
+static inline int gpiolib_cdev_register(struct gpio_device *gdev, dev_t devt)
+{
+   return 0;
+}
+
+static inline void gpiolib_cdev_unregister(struct gpio_device *gdev)
+{
+}
+
+#endif /* CONFIG_GPIO_CDEV */
+
 #endif /* GPIOLIB_CDEV_H */
-- 
2.28.0



[PATCH v4 04/20] gpio: uapi: define uAPI v2

2020-08-13 Thread Kent Gibson
Add a new version of the uAPI to address existing 32/64-bit alignment
issues, add support for debounce and event sequence numbers, allow
requested lines with different configurations, and provide some future
proofing by adding padding reserved for future use.

The alignment issue relates to the gpioevent_data, which packs to different
sizes on 32-bit and 64-bit platforms. That creates problems for 32-bit apps
running on 64-bit kernels.  uAPI v2 addresses that particular issue, and
the problem more generally, by adding pad fields that explicitly pad
structs out to 64-bit boundaries, so they will pack to the same size now,
and even if some of the reserved padding is used for __u64 fields in the
future.

The new structs have been analysed with pahole to ensure that they
are sized as expected and contain no implicit padding.

The lack of future proofing in v1 makes it impossible to, for example,
add the debounce feature that is included in v2.
The future proofing is addressed by providing configurable attributes in
line config and reserved padding in all structs for future features.
Specifically, the line request, config, info, info_changed and event
structs receive updated versions and new ioctls.

As the majority of the structs and ioctls were being replaced, it is
opportune to rework some of the other aspects of the uAPI:

v1 has three different flags fields, each with their own separate
bit definitions.  In v2 that is collapsed to one - gpio_v2_line_flag.

The handle and event requests are merged into a single request, the line
request, as the two requests were mostly the same other than the edge
detection provided by event requests.  As a byproduct, the v2 uAPI allows
for multiple lines producing edge events on the same line handle.
This is a new capability as v1 only supports a single line in an event
request.

As a consequence, there are now only two types of file handle to be
concerned with, the chip and the line, and it is clearer which ioctls
apply to which type of handle.

There is also some minor renaming of fields for consistency compared to
their v1 counterparts, e.g. offset rather than lineoffset or line_offset,
and consumer rather than consumer_label.

Additionally, v1 GPIOHANDLES_MAX becomes GPIO_V2_LINES_MAX in v2 for
clarity, and the gpiohandle_data __u8 array becomes a bitmap in
gpio_v2_line_values.

The v2 uAPI is mostly a reorganisation and extension of v1, so userspace
code, particularly libgpiod, should readily port to it.

Signed-off-by: Kent Gibson 
---

Changes for v4:
 - clarify bitmap width in GPIO_V2_LINES_MAX description

Changes for v3:
 - relocated commentary into commit description
 - hard limit max requested lines to 64 so bitmaps always fit in a single
   u64.
 - prefix all v2 symbols with GPIO_V2
 - 64-bit flag values to ULL
 - use __aligned_u64 to ensure 64-bit fields are 64-bit aligned
 - support masked get values, as per set values.

Changes for v2:
 - lower case V1 and V2, except in capitalized names
 - hyphenate 32/64-bit
 - rename bitmap field to bits
 - drop PAD_SIZE consts in favour of hard coded numbers
 - sort includes
 - change config flags to __u64
 - increase padding of gpioline_event
 - relocate GPIOLINE_CHANGED enum into v2 section (is common with v1)
 - rework config to collapse direction, drive, bias and edge enums back
   into flags and add optional attributes that can be associated with a
   subset of the requested lines.

Changes for v1 (since the RFC):
 - document the constraints on array sizes to maintain 32/64 alignment
 - add sequence numbers to gpioline_event
 - use bitmap for values instead of array of __u8
 - gpioline_info_v2 contains gpioline_config instead of its composite fields
 - provide constants for all array sizes, especially padding
 - renamed "GPIOLINE_FLAG_V2_KERNEL" to "GPIOLINE_FLAG_V2_USED"
 - renamed "default_values" to "values"
 - made gpioline_direction zero based
 - document clock used in gpioline_event timestamp
 - add event_buffer_size to gpioline_request
 - rename debounce to debounce_period
 - rename lines to num_lines

 include/uapi/linux/gpio.h | 273 +-
 1 file changed, 266 insertions(+), 7 deletions(-)

diff --git a/include/uapi/linux/gpio.h b/include/uapi/linux/gpio.h
index 285cc10355b2..0eb1f53b47e0 100644
--- a/include/uapi/linux/gpio.h
+++ b/include/uapi/linux/gpio.h
@@ -16,6 +16,8 @@
 
 /*
  * The maximum size of name and label arrays.
+ *
+ * Must be a multiple of 8 to ensure 32/64-bit alignment of structs.
  */
 #define GPIO_MAX_NAME_SIZE 32
 
@@ -32,6 +34,248 @@ struct gpiochip_info {
__u32 lines;
 };
 
+/*
+ * Maximum number of requested lines.
+ *
+ * Must be no greater than 64, as bitmaps are restricted here to 64-bits
+ * for simplicity, and a multiple of 2 to ensure 32/64-bit alignment of
+ * structs.
+ */
+#define GPIO_V2_LINES_MAX 64
+
+/*
+ * The maximum number of configuration attributes associated with a line
+ * request.
+ */
+#define 

[PATCH v4 02/20] gpiolib: cdev: replace strncpy with strscpy

2020-08-13 Thread Kent Gibson
Replace usage of strncpy with strscpy to remove -Wstringop-truncation
warnings.

The structs being populated are zeroed, to prevent stack leakage as
they are returned to userspace, so strscpy performs the equivalent
function without the warnings.

Reported-by: kernel test robot 
Signed-off-by: Kent Gibson 
---

The memset in gpio_desc_to_lineinfo(), in conjunction with the strscpy,
is necessary as strncpy zeroed pads the remainder of the destination.
It is also guarantees that the info cannot contain kernel stack that could
get leaked to userspace.  This is useful here, but is even more important
for the v2 info that this function is changed to generate in a subsequent
patch as that struct contains padding and attribute arrays that need to be
initialised.

 drivers/gpio/gpiolib-cdev.c | 23 +++
 1 file changed, 7 insertions(+), 16 deletions(-)

diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
index e95e3eab9867..8b012879fe3f 100644
--- a/drivers/gpio/gpiolib-cdev.c
+++ b/drivers/gpio/gpiolib-cdev.c
@@ -752,6 +752,7 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc,
bool ok_for_pinctrl;
unsigned long flags;
 
+   memset(info, 0, sizeof(*info));
info->line_offset = gpio_chip_hwgpio(desc);
/*
 * This function takes a mutex so we must check this before taking
@@ -765,19 +766,11 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc,
 
spin_lock_irqsave(_lock, flags);
 
-   if (desc->name) {
-   strncpy(info->name, desc->name, sizeof(info->name));
-   info->name[sizeof(info->name) - 1] = '\0';
-   } else {
-   info->name[0] = '\0';
-   }
+   if (desc->name)
+   strscpy(info->name, desc->name, sizeof(info->name));
 
-   if (desc->label) {
-   strncpy(info->consumer, desc->label, sizeof(info->consumer));
-   info->consumer[sizeof(info->consumer) - 1] = '\0';
-   } else {
-   info->consumer[0] = '\0';
-   }
+   if (desc->label)
+   strscpy(info->consumer, desc->label, sizeof(info->consumer));
 
/*
 * Userspace only need to know that the kernel is using this GPIO so
@@ -841,12 +834,10 @@ static long gpio_ioctl(struct file *file, unsigned int 
cmd, unsigned long arg)
 
memset(, 0, sizeof(chipinfo));
 
-   strncpy(chipinfo.name, dev_name(>dev),
+   strscpy(chipinfo.name, dev_name(>dev),
sizeof(chipinfo.name));
-   chipinfo.name[sizeof(chipinfo.name)-1] = '\0';
-   strncpy(chipinfo.label, gdev->label,
+   strscpy(chipinfo.label, gdev->label,
sizeof(chipinfo.label));
-   chipinfo.label[sizeof(chipinfo.label)-1] = '\0';
chipinfo.lines = gdev->ngpio;
if (copy_to_user(ip, , sizeof(chipinfo)))
return -EFAULT;
-- 
2.28.0



[PATCH v3] nvmem: core: add sanity check in nvmem_device_read()

2020-08-13 Thread Bingbu Cao
nvmem device read/write could be called directly once nvmem
device registered, the sanity check should be done before each
nvmem_reg_read/write().

Signed-off-by: Bingbu Cao 
---
 drivers/nvmem/core.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 927eb5f6003f..09ad5a06efee 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -69,6 +69,9 @@ static BLOCKING_NOTIFIER_HEAD(nvmem_notifier);
 static int nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
  void *val, size_t bytes)
 {
+   if (bytes + offset > nvmem->size)
+   return -EINVAL;
+
if (nvmem->reg_read)
return nvmem->reg_read(nvmem->priv, offset, val, bytes);
 
@@ -80,6 +83,9 @@ static int nvmem_reg_write(struct nvmem_device *nvmem, 
unsigned int offset,
 {
int ret;
 
+   if (bytes + offset > nvmem->size)
+   return -EINVAL;
+
if (nvmem->reg_write) {
gpiod_set_value_cansleep(nvmem->wp_gpio, 0);
ret = nvmem->reg_write(nvmem->priv, offset, val, bytes);
-- 
2.7.4



[PATCH v4 01/20] gpiolib: cdev: desc_to_lineinfo should set info offset

2020-08-13 Thread Kent Gibson
Set the value of the line info offset in desc_to_lineinfo, rather than
relying on it being passed in the info.  This makes the function behave
as you would expect from the name - it generates the line info
corresponding to a given GPIO desc.

Signed-off-by: Kent Gibson 
---

There are some instances where this results in the offset being set when
it is already set in the info, but I think this is clearer especially
considering that, as part of the replacement of strncpy with strscpy and
to to ensure kernel stack cannot be leaked to userspace, the info is
zeroed in a subsequent patch.

 drivers/gpio/gpiolib-cdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
index e6c9b78adfc2..e95e3eab9867 100644
--- a/drivers/gpio/gpiolib-cdev.c
+++ b/drivers/gpio/gpiolib-cdev.c
@@ -752,6 +752,7 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc,
bool ok_for_pinctrl;
unsigned long flags;
 
+   info->line_offset = gpio_chip_hwgpio(desc);
/*
 * This function takes a mutex so we must check this before taking
 * the spinlock.
@@ -933,7 +934,6 @@ static int lineinfo_changed_notify(struct notifier_block 
*nb,
return NOTIFY_DONE;
 
memset(, 0, sizeof(chg));
-   chg.info.line_offset = gpio_chip_hwgpio(desc);
chg.event_type = action;
chg.timestamp = ktime_get_ns();
gpio_desc_to_lineinfo(desc, );
-- 
2.28.0



[PATCH v2] sched: print fields name when do sched_show_task

2020-08-13 Thread Libing Zhou
Current sysrq(t) output task fields name are not aligned with
actual task fields value, e.g.:

kernel: sysrq: Show State
kernel:  taskPC stack   pid father
kernel: systemd S12456 1  0 0x
kernel: Call Trace:
kernel: ? __schedule+0x240/0x740

To make it more readable, print fields name together with task fields
value in same line, remove separate fields name print, new format looks
like:

kernel: sysrq: Show State
kernel: task:systemd state:S stack:12920 pid:1 ppid: 0 
flags:0x
kernel: Call Trace:
kernel: __schedule+0x282/0x620

Signed-off-by: Libing Zhou 
---
v2:
Quote the new format as well in the changelog per Ingo suggested.

 kernel/sched/core.c | 15 ---
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index e15543cb8481..0ad554cb0bbb 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -6069,10 +6069,10 @@ void sched_show_task(struct task_struct *p)
if (!try_get_task_stack(p))
return;
 
-   printk(KERN_INFO "%-15.15s %c", p->comm, task_state_to_char(p));
+   pr_info("task:%-15.15s state:%c", p->comm, task_state_to_char(p));
 
if (p->state == TASK_RUNNING)
-   printk(KERN_CONT "  running task");
+   pr_cont("  running task");
 #ifdef CONFIG_DEBUG_STACK_USAGE
free = stack_not_used(p);
 #endif
@@ -6081,8 +6081,8 @@ void sched_show_task(struct task_struct *p)
if (pid_alive(p))
ppid = task_pid_nr(rcu_dereference(p->real_parent));
rcu_read_unlock();
-   printk(KERN_CONT "%5lu %5d %6d 0x%08lx\n", free,
-   task_pid_nr(p), ppid,
+   pr_cont(" stack:%5lu pid:%5d ppid:%6d flags:0x%08lx\n",
+   free, task_pid_nr(p), ppid,
(unsigned long)task_thread_info(p)->flags);
 
print_worker_info(KERN_INFO, p);
@@ -6117,13 +6117,6 @@ void show_state_filter(unsigned long state_filter)
 {
struct task_struct *g, *p;
 
-#if BITS_PER_LONG == 32
-   printk(KERN_INFO
-   "  taskPC stack   pid father\n");
-#else
-   printk(KERN_INFO
-   "  taskPC stack   pid father\n");
-#endif
rcu_read_lock();
for_each_process_thread(g, p) {
/*
-- 
2.22.0



[PATCH v4 00/20] gpio: cdev: add uAPI v2

2020-08-13 Thread Kent Gibson
This patchset defines and implements adds a new version of the
GPIO CDEV uAPI to address existing 32/64-bit alignment issues, add
support for debounce, event sequence numbers, and allowing for requested
lines with different configurations.
It provides some future proofing by adding optional configuration fields
and padding reserved for future use.

The series can be partitioned into two sets; the first eleven
contain the v2 uAPI implementation, and the final seven port
the GPIO tools to the v2 uAPI and extend them to use new uAPI features.

The more complicated patches include their own commentary where
appropriate.

Cheers,
Kent.

Changes for v4:
 - bitmap width clarification in gpiod.h (patch 04)
 - fix info offset initialisation bug (patch 08 and inserting patch 01)
 - replace strncpy with strscpy to remove compiler warnings
   (patch 08 and inserting patch 02)
 - fix mask handling in line_get_values (patch 07)

Changes for v3:
 - disabling the character device from the build requires EXPERT
 - uAPI revisions (see patch 02)
 - replace padding_not_zeroed with calls to memchr_inv
 - don't use bitops on 64-bit flags as that doesn't work on BE-32
 - accept first attribute matching a line in gpio_v2_line_config.attrs
   rather than the last
 - rework lsgpio port to uAPI v2 as flags reverted to v1 like layout
   (since patch v2)
 - swapped patches 17 and 18 to apply debounce to multiple monitored
   lines

Changes for v2:
 - split out cleanup patches into a separate series.
 - split implementation patch into a patch for each ioctl or major feature.
 - split tool port patch into a patch per tool.
 - rework uAPI to allow requested lines with different configurations.


Kent Gibson (20):
  gpiolib: cdev: desc_to_lineinfo should set info offset
  gpiolib: cdev: replace strncpy with strscpy
  gpio: uapi: define GPIO_MAX_NAME_SIZE for array sizes
  gpio: uapi: define uAPI v2
  gpiolib: make cdev a build option
  gpiolib: add build option for CDEV v1 ABI
  gpiolib: cdev: support GPIO_V2_GET_LINE_IOCTL and
GPIO_V2_LINE_GET_VALUES_IOCTL
  gpiolib: cdev: support GPIO_V2_GET_LINEINFO_IOCTL and
GPIO_V2_GET_LINEINFO_WATCH_IOCTL
  gpiolib: cdev: support edge detection for uAPI v2
  gpiolib: cdev: support GPIO_V2_LINE_SET_CONFIG_IOCTL
  gpiolib: cdev: support GPIO_V2_LINE_SET_VALUES_IOCTL
  gpiolib: cdev: support setting debounce
  gpio: uapi: document uAPI v1 as deprecated
  tools: gpio: port lsgpio to v2 uAPI
  tools: gpio: port gpio-watch to v2 uAPI
  tools: gpio: rename nlines to num_lines
  tools: gpio: port gpio-hammer to v2 uAPI
  tools: gpio: port gpio-event-mon to v2 uAPI
  tools: gpio: add multi-line monitoring to gpio-event-mon
  tools: gpio: add debounce support to gpio-event-mon

 drivers/gpio/Kconfig|   29 +-
 drivers/gpio/Makefile   |2 +-
 drivers/gpio/gpiolib-cdev.c | 1354 +--
 drivers/gpio/gpiolib-cdev.h |   15 +
 drivers/gpio/gpiolib.c  |2 +
 drivers/gpio/gpiolib.h  |6 +
 include/uapi/linux/gpio.h   |  316 +++-
 tools/gpio/gpio-event-mon.c |  146 ++--
 tools/gpio/gpio-hammer.c|   56 +-
 tools/gpio/gpio-utils.c |  127 ++--
 tools/gpio/gpio-utils.h |   50 +-
 tools/gpio/gpio-watch.c |   16 +-
 tools/gpio/lsgpio.c |   60 +-
 13 files changed, 1949 insertions(+), 230 deletions(-)


base-commit: 22cc422070d9a9a399f8a70b89f1b852945444cb
-- 
2.28.0



[PATCH] MIPS: Loongson: Set CONFIG_FRAME_WARN=2048 in loongson3_defconfig to fix build warning

2020-08-13 Thread Tiezhu Yang
After commit 70b838292bef ("MIPS: Update default config file for
Loongson-3"), CONFIG_VHOST_SCSI and CONFIG_VHOST are set when use
loongson3_defconfig, and then there exists the following two build
warnings related with these two configs, set CONFIG_FRAME_WARN=2048
in loongson3_defconfig to fix it.

  CC [M]  drivers/vhost/scsi.o
drivers/vhost/scsi.c: In function ‘vhost_scsi_flush’:
drivers/vhost/scsi.c:1374:1: warning: the frame size of 1040 bytes is larger 
than 1024 bytes [-Wframe-larger-than=]
 }
 ^
  LD [M]  drivers/vhost/vhost_scsi.o
  CC [M]  drivers/vhost/vsock.o
  LD [M]  drivers/vhost/vhost_vsock.o
  CC [M]  drivers/vhost/vhost.o
drivers/vhost/vhost.c: In function ‘log_used’:
drivers/vhost/vhost.c:1896:1: warning: the frame size of 1040 bytes is larger 
than 1024 bytes [-Wframe-larger-than=]
 }
 ^

Fixes: 70b838292bef ("MIPS: Update default config file for Loongson-3")
Signed-off-by: Tiezhu Yang 
---
 arch/mips/configs/loongson3_defconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/configs/loongson3_defconfig 
b/arch/mips/configs/loongson3_defconfig
index a65b08d..2b356d9 100644
--- a/arch/mips/configs/loongson3_defconfig
+++ b/arch/mips/configs/loongson3_defconfig
@@ -403,7 +403,7 @@ CONFIG_CRYPTO_TEA=m
 CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_PRINTK_TIME=y
-CONFIG_FRAME_WARN=1024
+CONFIG_FRAME_WARN=2048
 CONFIG_STRIP_ASM_SYMS=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_SCHED_DEBUG is not set
-- 
2.1.0



Re: BUG: unable to handle kernel paging request in fl_dump_key

2020-08-13 Thread syzbot
syzbot has bisected this issue to:

commit a51486266c3ba8e035a47fa96df67f274fe0c7d0
Author: Jiri Pirko 
Date:   Sat Jun 15 09:03:49 2019 +

net: sched: remove NET_CLS_IND config option

bisection log:  https://syzkaller.appspot.com/x/bisect.txt?x=1746350990
start commit:   1ca0fafd tcp: md5: allow changing MD5 keys in all socket s..
git tree:   net
final oops: https://syzkaller.appspot.com/x/report.txt?x=14c6350990
console output: https://syzkaller.appspot.com/x/log.txt?x=10c6350990
kernel config:  https://syzkaller.appspot.com/x/.config?x=bf3aec367b9ab569
dashboard link: https://syzkaller.appspot.com/bug?extid=9c1be56e9317b795e874
syz repro:  https://syzkaller.appspot.com/x/repro.syz?x=1062a40b10

Reported-by: syzbot+9c1be56e9317b795e...@syzkaller.appspotmail.com
Fixes: a51486266c3b ("net: sched: remove NET_CLS_IND config option")

For information about bisection process see: https://goo.gl/tpsmEJ#bisection


Re: [PATCH v7] scsi: ufs: Quiesce all scsi devices before shutdown

2020-08-13 Thread Bart Van Assche
On 2020-08-13 01:55, Stanley Chu wrote:
> I tried many ways to come out the final solution. Currently two options
> are considered,
> 
> == Option 1 ==
>   pm_runtime_get_sync(hba->dev);
> 
>   shost_for_each_device(sdev, hba->host) {
>   scsi_autopm_get_device(sdev);
>   if (sdev == hba->sdev_ufs_device)
>   scsi_device_quiesce(sdev);
>   else
>   scsi_remove_device(sdev);
>   }
> 
>   ret = ufshcd_suspend(hba, UFS_SHUTDOWN_PM);
> 
>   scsi_remove_device(hba->sdev_ufs_device);
> 
> Note. Using scsi_autopm_get_device() instead of pm_runtime_disable()
> is to prevent noisy message by below checking,
> 
>   WARN_ON_ONCE(sdev->quiesced_by && sdev->quiesced_by != current);
> 
> in
> https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/scsi/scsi_lib.c#n2515
> 
> This warning shows up if we try to quiesce a runtime-suspended SCSI
> device. This is possible during our new shutdown flow. Using
> scsi_autopm_get_device() to resume all SCSI devices first can prevent
> it.
> 
> In addition, normally sd_shutdown() would be executed prior than
> ufshcd_shutdown(). If scsi_remove_device() is invoked by
> ufshcd_shutdown(), sd_shutdown() will be executed again for a SCSI disk
> by
> 
> [  131.398977]  sd_shutdown+0x44/0x118
> [  131.399416]  sd_remove+0x5c/0xc4
> [  131.399824]  device_release_driver_internal+0x1c4/0x2e4
> [  131.400481]  device_release_driver+0x18/0x24
> [  131.401018]  bus_remove_device+0x108/0x134
> [  131.401533]  device_del+0x2dc/0x630
> [  131.401973]  __scsi_remove_device+0xc0/0x174
> [  131.402510]  scsi_remove_device+0x30/0x48
> [  131.403014]  ufshcd_shutdown+0xc8/0x138
> 
> In this case, we could see SYNCHRONIZE_CACHE command will be sent to the
> same SCSI device twice. This is kind of wired during shutdown flow.
> 
> Moreover, in consideration of performance of ufshcd_shutdown(), Option 1
> obviously degrades the latency a lot by scsi_remove_device(). Please see
> the "Performance Measurement" data below.
> 
> Compared Option 2, this way is simpler and also effective. This way may
> be a better compromise.
> 
> == Option 2  ==
>   pm_runtime_get_sync(hba->dev);
> 
>   shost_for_each_device(sdev, hba->host) {
>   scsi_autopm_get_device(sdev);
>   scsi_device_quiesce(sdev);
>   }
> 
> == Performance Measurement ==
> As-Is: < 5 ms
> Option 1: 850 ms
> Option 2: 60 ms
> 
> What would you prefer? Or would you have any further suggestions?

Hi Stanley,

Thanks for the detailed report and also for having shared timing information.

The approach of option 2 seems wrong to me because the SCSI devices are not
removed. My concern is that option (2) could cause the sd driver to send SYNC
and/or STOP commands to the device after its PCIe resources have been freed,
resulting in a crash.

Please take a look at the output of the following command:

$ git grep -nHA10 'struct pci_driver.* = {$' */scsi |
  sed -e 's/-/:/' -e 's/-/:/' |
  grep ':[[:blank:]]*\.remove'

It seems to me that other SCSI LLDs do at least the following in their PCIe
removal callback:

1. Call scsi_remove_host()
2. Call scsi_host_put()
3. Call pci_disable_device()

Would that approach work for UFS? Would offlining the UFS LUNs (SDEV_OFFLINE)
before calling the above functions make SCSI host removal faster? See also
scsi_prep_state_check().

Thanks,

Bart.


fsl_espi errors on v5.7.15

2020-08-13 Thread Chris Packham
Hi,

I'm seeing a problem with accessing spi-nor after upgrading a T2081 
based system to linux v5.7.15

For this board u-boot and the u-boot environment live on spi-nor.

When I use fw_setenv from userspace I get the following kernel logs

# fw_setenv foo=1
fsl_espi ffe11.spi: Transfer done but SPIE_DON isn't set!
fsl_espi ffe11.spi: Transfer done but SPIE_DON isn't set!
fsl_espi ffe11.spi: Transfer done but SPIE_DON isn't set!
fsl_espi ffe11.spi: Transfer done but SPIE_DON isn't set!
fsl_espi ffe11.spi: Transfer done but SPIE_DON isn't set!
fsl_espi ffe11.spi: Transfer done but SPIE_DON isn't set!
fsl_espi ffe11.spi: Transfer done but SPIE_DON isn't set!
fsl_espi ffe11.spi: Transfer done but SPIE_DON isn't set!
fsl_espi ffe11.spi: Transfer done but SPIE_DON isn't set!
fsl_espi ffe11.spi: Transfer done but SPIE_DON isn't set!
fsl_espi ffe11.spi: Transfer done but SPIE_DON isn't set!
fsl_espi ffe11.spi: Transfer done but SPIE_DON isn't set!
fsl_espi ffe11.spi: Transfer done but SPIE_DON isn't set!
fsl_espi ffe11.spi: Transfer done but SPIE_DON isn't set!
fsl_espi ffe11.spi: Transfer done but rx/tx fifo's aren't empty!
fsl_espi ffe11.spi: SPIE_RXCNT = 1, SPIE_TXCNT = 32
fsl_espi ffe11.spi: Transfer done but rx/tx fifo's aren't empty!
fsl_espi ffe11.spi: SPIE_RXCNT = 1, SPIE_TXCNT = 32
fsl_espi ffe11.spi: Transfer done but rx/tx fifo's aren't empty!
fsl_espi ffe11.spi: SPIE_RXCNT = 1, SPIE_TXCNT = 32
...

If I run fw_printenv (before getting it into a bad state) it is able to 
display the content of the boards u-boot environment.

If been unsuccessful in producing a setup for bisecting the issue. I do 
know the issue doesn't occur on the old 4.4.x based kernel but that's 
probably not much help.

Any pointers on what the issue (and/or solution) might be.

Thanks,
Chris


Re: [PATCH] mm : update ra->ra_pages if it's NOT equal to bdi->ra_pages

2020-08-13 Thread Zhaoyang Huang
On Fri, Aug 14, 2020 at 10:33 AM Andrew Morton
 wrote:
>
> On Fri, 14 Aug 2020 10:20:11 +0800 Zhaoyang Huang  
> wrote:
>
> > On Fri, Aug 14, 2020 at 10:07 AM Matthew Wilcox  wrote:
> > >
> > > On Fri, Aug 14, 2020 at 02:43:55AM +0100, Matthew Wilcox wrote:
> > > > On Fri, Aug 14, 2020 at 09:30:11AM +0800, Zhaoyang Huang wrote:
> > > > > file->f_ra->ra_pages will remain the initialized value since it 
> > > > > opend, which may
> > > > > be NOT equal to bdi->ra_pages as the latter one is updated 
> > > > > somehow(etc,
> > > > > echo xxx > /sys/block/dm/queue/read_ahead_kb).So sync ra->ra_pages to 
> > > > > the
> > > > > updated value when sync read.
> > > >
> > > > It still ignores the work done by shrink_readahead_size_eio()
> > > > and fadvise(POSIX_FADV_SEQUENTIAL).
> > >
> > > ... by the way, if you're trying to update one particular file's readahead
> > > state, you can just call fadvise(POSIX_FADV_NORMAL) on it.
> > >
> > > If you want to update every open file's ra_pages by writing to sysfs,
> > > then just no.  We don't do that.
> > No, What I want to fix is the file within one process's context  keeps
> > using the initialized value when it is opened and not sync with new
> > value when bdi->ra_pages changes.
>
> So you're saying that
>
> echo xxx > /sys/block/dm/queue/read_ahead_kb
>
> does not affect presently-open files, and you believe that it should do
> so?
>
> I guess that could be a reasonable thing to want - it's reasonable for
> a user to expect that writing to a global tunable will take immediate
> global effect.  I guess.
>
> But as Matthew says, it would help if you were to explain why this is
> needed.  In full detail.  What operational problems is the present
> implementation causing?
The real scenario is some system(like android) will turbo read during
startup via expanding the readahead window and then set it back to
normal(128kb as usual). However, some files in the system process
context will keep to be opened since it is opened up and has no chance
to sync with the updated value as it is almost impossible to change
the files attached to the inode(processes are unaware of these
things). we have to fix it from a kernel perspective.


[PATCH 16/19] drm/msm/a6xx: Add support for per-instance pagetables

2020-08-13 Thread Rob Clark
From: Jordan Crouse 

Add support for using per-instance pagetables if all the dependencies are
available.

Signed-off-by: Jordan Crouse 
Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 70 +++
 drivers/gpu/drm/msm/adreno/a6xx_gpu.h |  1 +
 drivers/gpu/drm/msm/msm_ringbuffer.h  |  1 +
 3 files changed, 72 insertions(+)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 5eabb0109577..9653ac9b3cb8 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -81,6 +81,56 @@ static void get_stats_counter(struct msm_ringbuffer *ring, 
u32 counter,
OUT_RING(ring, upper_32_bits(iova));
 }
 
+static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu,
+   struct msm_ringbuffer *ring, struct msm_file_private *ctx)
+{
+   phys_addr_t ttbr;
+   u32 asid;
+   u64 memptr = rbmemptr(ring, ttbr0);
+
+   if (ctx == a6xx_gpu->cur_ctx)
+   return;
+
+   if (msm_iommu_pagetable_params(ctx->aspace->mmu, , ))
+   return;
+
+   /* Execute the table update */
+   OUT_PKT7(ring, CP_SMMU_TABLE_UPDATE, 4);
+   OUT_RING(ring, CP_SMMU_TABLE_UPDATE_0_TTBR0_LO(lower_32_bits(ttbr)));
+
+   /*
+* For now ignore the asid since the smmu driver uses a TLBIASID to
+* flush the TLB when we use iommu_flush_tlb_all() and the smmu driver
+* isn't aware that the asid changed.  Instead, keep the default asid
+* (0, same as the context bank) to make sure the TLB is properly
+* flushed.
+*/
+   OUT_RING(ring,
+   CP_SMMU_TABLE_UPDATE_1_TTBR0_HI(upper_32_bits(ttbr)) |
+   CP_SMMU_TABLE_UPDATE_1_ASID(0));
+   OUT_RING(ring, CP_SMMU_TABLE_UPDATE_2_CONTEXTIDR(0));
+   OUT_RING(ring, CP_SMMU_TABLE_UPDATE_3_CONTEXTBANK(0));
+
+   /*
+* Write the new TTBR0 to the memstore. This is good for debugging.
+*/
+   OUT_PKT7(ring, CP_MEM_WRITE, 4);
+   OUT_RING(ring, CP_MEM_WRITE_0_ADDR_LO(lower_32_bits(memptr)));
+   OUT_RING(ring, CP_MEM_WRITE_1_ADDR_HI(upper_32_bits(memptr)));
+   OUT_RING(ring, lower_32_bits(ttbr));
+   OUT_RING(ring, (0 << 16) | upper_32_bits(ttbr));
+
+   /*
+* And finally, trigger a uche flush to be sure there isn't anything
+* lingering in that part of the GPU
+*/
+
+   OUT_PKT7(ring, CP_EVENT_WRITE, 1);
+   OUT_RING(ring, 0x31);
+
+   a6xx_gpu->cur_ctx = ctx;
+}
+
 static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
 {
unsigned int index = submit->seqno % MSM_GPU_SUBMIT_STATS_COUNT;
@@ -90,6 +140,8 @@ static void a6xx_submit(struct msm_gpu *gpu, struct 
msm_gem_submit *submit)
struct msm_ringbuffer *ring = submit->ring;
unsigned int i;
 
+   a6xx_set_pagetable(a6xx_gpu, ring, submit->queue->ctx);
+
get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP_0_LO,
rbmemptr_stats(ring, index, cpcycles_start));
 
@@ -696,6 +748,8 @@ static int a6xx_hw_init(struct msm_gpu *gpu)
/* Always come up on rb 0 */
a6xx_gpu->cur_ring = gpu->rb[0];
 
+   a6xx_gpu->cur_ctx = NULL;
+
/* Enable the SQE_to start the CP engine */
gpu_write(gpu, REG_A6XX_CP_SQE_CNTL, 1);
 
@@ -1008,6 +1062,21 @@ static unsigned long a6xx_gpu_busy(struct msm_gpu *gpu)
return (unsigned long)busy_time;
 }
 
+static struct msm_gem_address_space *
+a6xx_create_private_address_space(struct msm_gpu *gpu)
+{
+   struct msm_gem_address_space *aspace = NULL;
+   struct msm_mmu *mmu;
+
+   mmu = msm_iommu_pagetable_create(gpu->aspace->mmu);
+
+   if (!IS_ERR(mmu))
+   aspace = msm_gem_address_space_create(mmu,
+   "gpu", 0x1ULL, 0x1ULL);
+
+   return aspace;
+}
+
 static const struct adreno_gpu_funcs funcs = {
.base = {
.get_param = adreno_get_param,
@@ -1031,6 +1100,7 @@ static const struct adreno_gpu_funcs funcs = {
.gpu_state_put = a6xx_gpu_state_put,
 #endif
.create_address_space = adreno_iommu_create_address_space,
+   .create_private_address_space = 
a6xx_create_private_address_space,
},
.get_timestamp = a6xx_get_timestamp,
 };
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
index 03ba60d5b07f..da22d7549d9b 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
@@ -19,6 +19,7 @@ struct a6xx_gpu {
uint64_t sqe_iova;
 
struct msm_ringbuffer *cur_ring;
+   struct msm_file_private *cur_ctx;
 
struct a6xx_gmu gmu;
 };
diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.h 
b/drivers/gpu/drm/msm/msm_ringbuffer.h
index 7764373d0ed2..0987d6bf848c 100644
--- a/drivers/gpu/drm/msm/msm_ringbuffer.h
+++ b/drivers/gpu/drm/msm/msm_ringbuffer.h
@@ -31,6 +31,7 @@ 

[PATCH 17/19] arm: dts: qcom: sm845: Set the compatible string for the GPU SMMU

2020-08-13 Thread Rob Clark
From: Jordan Crouse 

Set the qcom,adreno-smmu compatible string for the GPU SMMU to enable
split pagetables and per-instance pagetables for drm/msm.

Signed-off-by: Jordan Crouse 
Signed-off-by: Rob Clark 
---
 arch/arm64/boot/dts/qcom/sdm845.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi 
b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 2884577dcb77..6a9adaa401a9 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -4058,7 +4058,7 @@ opp-25700 {
};
 
adreno_smmu: iommu@504 {
-   compatible = "qcom,sdm845-smmu-v2", "qcom,smmu-v2";
+   compatible = "qcom,adreno-smmu", "qcom,smmu-v2";
reg = <0 0x504 0 0x1>;
#iommu-cells = <1>;
#global-interrupts = <2>;
-- 
2.26.2



[PATCH 15/19] drm/msm: Add support for private address space instances

2020-08-13 Thread Rob Clark
From: Jordan Crouse 

Add support for allocating private address space instances. Targets that
support per-context pagetables should implement their own function to
allocate private address spaces.

The default will return a pointer to the global address space.

Signed-off-by: Jordan Crouse 
Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/msm/msm_drv.c | 13 +++--
 drivers/gpu/drm/msm/msm_drv.h |  5 +
 drivers/gpu/drm/msm/msm_gem_vma.c |  9 +
 drivers/gpu/drm/msm/msm_gpu.c | 22 ++
 drivers/gpu/drm/msm/msm_gpu.h |  5 +
 5 files changed, 48 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 01845a3b8d52..8e70d220bba8 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -597,7 +597,7 @@ static int context_init(struct drm_device *dev, struct 
drm_file *file)
kref_init(>ref);
msm_submitqueue_init(dev, ctx);
 
-   ctx->aspace = priv->gpu ? priv->gpu->aspace : NULL;
+   ctx->aspace = msm_gpu_create_private_address_space(priv->gpu);
file->driver_priv = ctx;
 
return 0;
@@ -780,18 +780,19 @@ static int msm_ioctl_gem_cpu_fini(struct drm_device *dev, 
void *data,
 }
 
 static int msm_ioctl_gem_info_iova(struct drm_device *dev,
-   struct drm_gem_object *obj, uint64_t *iova)
+   struct drm_file *file, struct drm_gem_object *obj,
+   uint64_t *iova)
 {
-   struct msm_drm_private *priv = dev->dev_private;
+   struct msm_file_private *ctx = file->driver_priv;
 
-   if (!priv->gpu)
+   if (!ctx->aspace)
return -EINVAL;
 
/*
 * Don't pin the memory here - just get an address so that userspace can
 * be productive
 */
-   return msm_gem_get_iova(obj, priv->gpu->aspace, iova);
+   return msm_gem_get_iova(obj, ctx->aspace, iova);
 }
 
 static int msm_ioctl_gem_info(struct drm_device *dev, void *data,
@@ -830,7 +831,7 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void 
*data,
args->value = msm_gem_mmap_offset(obj);
break;
case MSM_INFO_GET_IOVA:
-   ret = msm_ioctl_gem_info_iova(dev, obj, >value);
+   ret = msm_ioctl_gem_info_iova(dev, file, obj, >value);
break;
case MSM_INFO_SET_NAME:
/* length check should leave room for terminating null: */
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 4561bfb5e745..2ca9c3c03845 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -249,6 +249,10 @@ int msm_gem_map_vma(struct msm_gem_address_space *aspace,
 void msm_gem_close_vma(struct msm_gem_address_space *aspace,
struct msm_gem_vma *vma);
 
+
+struct msm_gem_address_space *
+msm_gem_address_space_get(struct msm_gem_address_space *aspace);
+
 void msm_gem_address_space_put(struct msm_gem_address_space *aspace);
 
 struct msm_gem_address_space *
@@ -434,6 +438,7 @@ static inline void __msm_file_private_destroy(struct kref 
*kref)
struct msm_file_private *ctx = container_of(kref,
struct msm_file_private, ref);
 
+   msm_gem_address_space_put(ctx->aspace);
kfree(ctx);
 }
 
diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c 
b/drivers/gpu/drm/msm/msm_gem_vma.c
index 5f6a11211b64..29cc1305cf37 100644
--- a/drivers/gpu/drm/msm/msm_gem_vma.c
+++ b/drivers/gpu/drm/msm/msm_gem_vma.c
@@ -27,6 +27,15 @@ void msm_gem_address_space_put(struct msm_gem_address_space 
*aspace)
kref_put(>kref, msm_gem_address_space_destroy);
 }
 
+struct msm_gem_address_space *
+msm_gem_address_space_get(struct msm_gem_address_space *aspace)
+{
+   if (!IS_ERR_OR_NULL(aspace))
+   kref_get(>kref);
+
+   return aspace;
+}
+
 /* Actually unmap memory for the vma */
 void msm_gem_purge_vma(struct msm_gem_address_space *aspace,
struct msm_gem_vma *vma)
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index e1a3cbe25a0c..951850804d77 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -823,6 +823,28 @@ static int get_clocks(struct platform_device *pdev, struct 
msm_gpu *gpu)
return 0;
 }
 
+/* Return a new address space for a msm_drm_private instance */
+struct msm_gem_address_space *
+msm_gpu_create_private_address_space(struct msm_gpu *gpu)
+{
+   struct msm_gem_address_space *aspace = NULL;
+
+   if (!gpu)
+   return NULL;
+
+   /*
+* If the target doesn't support private address spaces then return
+* the global one
+*/
+   if (gpu->funcs->create_private_address_space)
+   aspace = gpu->funcs->create_private_address_space(gpu);
+
+   if (IS_ERR_OR_NULL(aspace))
+   aspace = msm_gem_address_space_get(gpu->aspace);
+
+   return aspace;
+}
+
 int msm_gpu_init(struct 

[PATCH 13/19] drm/msm: Set the global virtual address range from the IOMMU domain

2020-08-13 Thread Rob Clark
From: Jordan Crouse 

Use the aperture settings from the IOMMU domain to set up the virtual
address range for the GPU. This allows us to transparently deal with
IOMMU side features (like split pagetables).

Signed-off-by: Jordan Crouse 
Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/msm/adreno/adreno_gpu.c | 13 +++--
 drivers/gpu/drm/msm/msm_iommu.c |  7 +++
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c 
b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 533a34b4cce2..34e6242c1767 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -192,9 +192,18 @@ adreno_iommu_create_address_space(struct msm_gpu *gpu,
struct iommu_domain *iommu = iommu_domain_alloc(_bus_type);
struct msm_mmu *mmu = msm_iommu_new(>dev, iommu);
struct msm_gem_address_space *aspace;
+   u64 start, size;
 
-   aspace = msm_gem_address_space_create(mmu, "gpu", SZ_16M,
-   0x - SZ_16M);
+   /*
+* Use the aperture start or SZ_16M, whichever is greater. This will
+* ensure that we align with the allocated pagetable range while still
+* allowing room in the lower 32 bits for GMEM and whatnot
+*/
+   start = max_t(u64, SZ_16M, iommu->geometry.aperture_start);
+   size = iommu->geometry.aperture_end - start + 1;
+
+   aspace = msm_gem_address_space_create(mmu, "gpu",
+   start & GENMASK(48, 0), size);
 
if (IS_ERR(aspace) && !IS_ERR(mmu))
mmu->funcs->destroy(mmu);
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index 3a381a9674c9..1b6635504069 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -36,6 +36,10 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
struct msm_iommu *iommu = to_msm_iommu(mmu);
size_t ret;
 
+   /* The arm-smmu driver expects the addresses to be sign extended */
+   if (iova & BIT_ULL(48))
+   iova |= GENMASK_ULL(63, 49);
+
ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot);
WARN_ON(!ret);
 
@@ -46,6 +50,9 @@ static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t 
iova, size_t len)
 {
struct msm_iommu *iommu = to_msm_iommu(mmu);
 
+   if (iova & BIT_ULL(48))
+   iova |= GENMASK_ULL(63, 49);
+
iommu_unmap(iommu->domain, iova, len);
 
return 0;
-- 
2.26.2



[PATCH 14/19] drm/msm: Add support to create a local pagetable

2020-08-13 Thread Rob Clark
From: Jordan Crouse 

Add support to create a io-pgtable for use by targets that support
per-instance pagetables. In order to support per-instance pagetables the
GPU SMMU device needs to have the qcom,adreno-smmu compatible string and
split pagetables enabled.

Signed-off-by: Jordan Crouse 
Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/msm/msm_gpummu.c |   2 +-
 drivers/gpu/drm/msm/msm_iommu.c  | 199 ++-
 drivers/gpu/drm/msm/msm_mmu.h|  16 ++-
 3 files changed, 214 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gpummu.c b/drivers/gpu/drm/msm/msm_gpummu.c
index 310a31b05faa..aab121f4beb7 100644
--- a/drivers/gpu/drm/msm/msm_gpummu.c
+++ b/drivers/gpu/drm/msm/msm_gpummu.c
@@ -102,7 +102,7 @@ struct msm_mmu *msm_gpummu_new(struct device *dev, struct 
msm_gpu *gpu)
}
 
gpummu->gpu = gpu;
-   msm_mmu_init(>base, dev, );
+   msm_mmu_init(>base, dev, , MSM_MMU_GPUMMU);
 
return >base;
 }
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index 1b6635504069..697cc0a059d6 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -4,15 +4,210 @@
  * Author: Rob Clark 
  */
 
+#include 
+#include 
 #include "msm_drv.h"
 #include "msm_mmu.h"
 
 struct msm_iommu {
struct msm_mmu base;
struct iommu_domain *domain;
+   atomic_t pagetables;
 };
+
 #define to_msm_iommu(x) container_of(x, struct msm_iommu, base)
 
+struct msm_iommu_pagetable {
+   struct msm_mmu base;
+   struct msm_mmu *parent;
+   struct io_pgtable_ops *pgtbl_ops;
+   phys_addr_t ttbr;
+   u32 asid;
+};
+static struct msm_iommu_pagetable *to_pagetable(struct msm_mmu *mmu)
+{
+   return container_of(mmu, struct msm_iommu_pagetable, base);
+}
+
+static int msm_iommu_pagetable_unmap(struct msm_mmu *mmu, u64 iova,
+   size_t size)
+{
+   struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
+   struct io_pgtable_ops *ops = pagetable->pgtbl_ops;
+   size_t unmapped = 0;
+
+   /* Unmap the block one page at a time */
+   while (size) {
+   unmapped += ops->unmap(ops, iova, 4096, NULL);
+   iova += 4096;
+   size -= 4096;
+   }
+
+   iommu_flush_tlb_all(to_msm_iommu(pagetable->parent)->domain);
+
+   return (unmapped == size) ? 0 : -EINVAL;
+}
+
+static int msm_iommu_pagetable_map(struct msm_mmu *mmu, u64 iova,
+   struct sg_table *sgt, size_t len, int prot)
+{
+   struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
+   struct io_pgtable_ops *ops = pagetable->pgtbl_ops;
+   struct scatterlist *sg;
+   size_t mapped = 0;
+   u64 addr = iova;
+   unsigned int i;
+
+   for_each_sg(sgt->sgl, sg, sgt->nents, i) {
+   size_t size = sg->length;
+   phys_addr_t phys = sg_phys(sg);
+
+   /* Map the block one page at a time */
+   while (size) {
+   if (ops->map(ops, addr, phys, 4096, prot, GFP_KERNEL)) {
+   msm_iommu_pagetable_unmap(mmu, iova, mapped);
+   return -EINVAL;
+   }
+
+   phys += 4096;
+   addr += 4096;
+   size -= 4096;
+   mapped += 4096;
+   }
+   }
+
+   return 0;
+}
+
+static void msm_iommu_pagetable_destroy(struct msm_mmu *mmu)
+{
+   struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
+   struct msm_iommu *iommu = to_msm_iommu(pagetable->parent);
+   struct adreno_smmu_priv *adreno_smmu =
+   dev_get_drvdata(pagetable->parent->dev);
+
+   /*
+* If this is the last attached pagetable for the parent,
+* disable TTBR0 in the arm-smmu driver
+*/
+   if (atomic_dec_return(>pagetables) == 0)
+   adreno_smmu->set_ttbr0_cfg(adreno_smmu->cookie, NULL);
+
+   free_io_pgtable_ops(pagetable->pgtbl_ops);
+   kfree(pagetable);
+}
+
+int msm_iommu_pagetable_params(struct msm_mmu *mmu,
+   phys_addr_t *ttbr, int *asid)
+{
+   struct msm_iommu_pagetable *pagetable;
+
+   if (mmu->type != MSM_MMU_IOMMU_PAGETABLE)
+   return -EINVAL;
+
+   pagetable = to_pagetable(mmu);
+
+   if (ttbr)
+   *ttbr = pagetable->ttbr;
+
+   if (asid)
+   *asid = pagetable->asid;
+
+   return 0;
+}
+
+static const struct msm_mmu_funcs pagetable_funcs = {
+   .map = msm_iommu_pagetable_map,
+   .unmap = msm_iommu_pagetable_unmap,
+   .destroy = msm_iommu_pagetable_destroy,
+};
+
+static void msm_iommu_tlb_flush_all(void *cookie)
+{
+}
+
+static void msm_iommu_tlb_flush_walk(unsigned long iova, size_t size,
+   size_t granule, void *cookie)
+{
+}
+
+static void msm_iommu_tlb_add_page(struct iommu_iotlb_gather *gather,
+   unsigned 

[PATCH 18/19] iommu/arm-smmu: add a way for implementations to influence SCTLR

2020-08-13 Thread Rob Clark
From: Rob Clark 

For the Adreno GPU's SMMU, we want SCTLR.HUPCF set to ensure that
pending translations are not terminated on iova fault.  Otherwise
a terminated CP read could hang the GPU by returning invalid
command-stream data.

Signed-off-by: Rob Clark 
---
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 6 ++
 drivers/iommu/arm/arm-smmu/arm-smmu.c  | 3 +++
 drivers/iommu/arm/arm-smmu/arm-smmu.h  | 3 +++
 3 files changed, 12 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index 5640d9960610..2aa6249050ff 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -127,6 +127,12 @@ static int qcom_adreno_smmu_init_context(struct 
arm_smmu_domain *smmu_domain,
(smmu_domain->cfg.fmt == ARM_SMMU_CTX_FMT_AARCH64))
pgtbl_cfg->quirks |= IO_PGTABLE_QUIRK_ARM_TTBR1;
 
+   /*
+* On the GPU device we want to process subsequent transactions after a
+* fault to keep the GPU from hanging
+*/
+   smmu_domain->cfg.sctlr_set |= ARM_SMMU_SCTLR_HUPCF;
+
/*
 * Initialize private interface with GPU:
 */
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index e63a480d7f71..bbec5793faf8 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -617,6 +617,9 @@ void arm_smmu_write_context_bank(struct arm_smmu_device 
*smmu, int idx)
if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
reg |= ARM_SMMU_SCTLR_E;
 
+   reg |= cfg->sctlr_set;
+   reg &= ~cfg->sctlr_clr;
+
arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_SCTLR, reg);
 }
 
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h 
b/drivers/iommu/arm/arm-smmu/arm-smmu.h
index cd75a33967bb..2df3a70a8a41 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
@@ -144,6 +144,7 @@ enum arm_smmu_cbar_type {
 #define ARM_SMMU_CB_SCTLR  0x0
 #define ARM_SMMU_SCTLR_S1_ASIDPNE  BIT(12)
 #define ARM_SMMU_SCTLR_CFCFG   BIT(7)
+#define ARM_SMMU_SCTLR_HUPCF   BIT(8)
 #define ARM_SMMU_SCTLR_CFIEBIT(6)
 #define ARM_SMMU_SCTLR_CFREBIT(5)
 #define ARM_SMMU_SCTLR_E   BIT(4)
@@ -341,6 +342,8 @@ struct arm_smmu_cfg {
u16 asid;
u16 vmid;
};
+   u32 sctlr_set;/* extra bits to set in 
SCTLR */
+   u32 sctlr_clr;/* bits to mask in SCTLR 
*/
enum arm_smmu_cbar_type cbar;
enum arm_smmu_context_fmt   fmt;
 };
-- 
2.26.2



[PATCH 12/19] drm/msm: Drop context arg to gpu->submit()

2020-08-13 Thread Rob Clark
From: Jordan Crouse 

Now that we can get the ctx from the submitqueue, the extra arg is
redundant.

Signed-off-by: Jordan Crouse 
[split out of previous patch to reduce churny noise]
Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/msm/adreno/a5xx_gpu.c   | 12 +---
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c   |  5 ++---
 drivers/gpu/drm/msm/adreno/adreno_gpu.c |  5 ++---
 drivers/gpu/drm/msm/adreno/adreno_gpu.h |  3 +--
 drivers/gpu/drm/msm/msm_gem_submit.c|  2 +-
 drivers/gpu/drm/msm/msm_gpu.c   |  9 -
 drivers/gpu/drm/msm/msm_gpu.h   |  6 ++
 7 files changed, 17 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index 9e63a190642c..eff2439ea57b 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -43,8 +43,7 @@ static void a5xx_flush(struct msm_gpu *gpu, struct 
msm_ringbuffer *ring)
gpu_write(gpu, REG_A5XX_CP_RB_WPTR, wptr);
 }
 
-static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit 
*submit,
-   struct msm_file_private *ctx)
+static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit 
*submit)
 {
struct msm_drm_private *priv = gpu->dev->dev_private;
struct msm_ringbuffer *ring = submit->ring;
@@ -57,7 +56,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct 
msm_gem_submit *submit
case MSM_SUBMIT_CMD_IB_TARGET_BUF:
break;
case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
-   if (priv->lastctx == ctx)
+   if (priv->lastctx == submit->queue->ctx)
break;
/* fall-thru */
case MSM_SUBMIT_CMD_BUF:
@@ -103,8 +102,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct 
msm_gem_submit *submit
msm_gpu_retire(gpu);
 }
 
-static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
-   struct msm_file_private *ctx)
+static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
 {
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
@@ -114,7 +112,7 @@ static void a5xx_submit(struct msm_gpu *gpu, struct 
msm_gem_submit *submit,
 
if (IS_ENABLED(CONFIG_DRM_MSM_GPU_SUDO) && submit->in_rb) {
priv->lastctx = NULL;
-   a5xx_submit_in_rb(gpu, submit, ctx);
+   a5xx_submit_in_rb(gpu, submit);
return;
}
 
@@ -148,7 +146,7 @@ static void a5xx_submit(struct msm_gpu *gpu, struct 
msm_gem_submit *submit,
case MSM_SUBMIT_CMD_IB_TARGET_BUF:
break;
case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
-   if (priv->lastctx == ctx)
+   if (priv->lastctx == submit->queue->ctx)
break;
/* fall-thru */
case MSM_SUBMIT_CMD_BUF:
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index c5a3e4d4c007..5eabb0109577 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -81,8 +81,7 @@ static void get_stats_counter(struct msm_ringbuffer *ring, 
u32 counter,
OUT_RING(ring, upper_32_bits(iova));
 }
 
-static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
-   struct msm_file_private *ctx)
+static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
 {
unsigned int index = submit->seqno % MSM_GPU_SUBMIT_STATS_COUNT;
struct msm_drm_private *priv = gpu->dev->dev_private;
@@ -115,7 +114,7 @@ static void a6xx_submit(struct msm_gpu *gpu, struct 
msm_gem_submit *submit,
case MSM_SUBMIT_CMD_IB_TARGET_BUF:
break;
case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
-   if (priv->lastctx == ctx)
+   if (priv->lastctx == submit->queue->ctx)
break;
/* fall-thru */
case MSM_SUBMIT_CMD_BUF:
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c 
b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index d2dbb6968cba..533a34b4cce2 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -457,8 +457,7 @@ void adreno_recover(struct msm_gpu *gpu)
}
 }
 
-void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
-   struct msm_file_private *ctx)
+void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
 {
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
struct msm_drm_private *priv = gpu->dev->dev_private;
@@ -472,7 +471,7 @@ void adreno_submit(struct msm_gpu *gpu, struct 
msm_gem_submit *submit,
break;
case 

[PATCH 19/19] drm/msm: show process names in gem_describe

2020-08-13 Thread Rob Clark
From: Rob Clark 

In $debugfs/gem we already show any vma(s) associated with an object.
Also show process names if the vma's address space is a per-process
address space.

Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/msm/msm_drv.c |  2 +-
 drivers/gpu/drm/msm/msm_gem.c | 25 +
 drivers/gpu/drm/msm/msm_gem.h |  5 +
 drivers/gpu/drm/msm/msm_gem_vma.c |  1 +
 drivers/gpu/drm/msm/msm_gpu.c |  8 +---
 drivers/gpu/drm/msm/msm_gpu.h |  2 +-
 6 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 8e70d220bba8..8d5c4f98c332 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -597,7 +597,7 @@ static int context_init(struct drm_device *dev, struct 
drm_file *file)
kref_init(>ref);
msm_submitqueue_init(dev, ctx);
 
-   ctx->aspace = msm_gpu_create_private_address_space(priv->gpu);
+   ctx->aspace = msm_gpu_create_private_address_space(priv->gpu, current);
file->driver_priv = ctx;
 
return 0;
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 3cb7aeb93fd3..76a6c5271e57 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -842,11 +842,28 @@ void msm_gem_describe(struct drm_gem_object *obj, struct 
seq_file *m)
 
seq_puts(m, "  vmas:");
 
-   list_for_each_entry(vma, _obj->vmas, list)
-   seq_printf(m, " [%s: %08llx,%s,inuse=%d]",
-   vma->aspace != NULL ? vma->aspace->name : NULL,
-   vma->iova, vma->mapped ? "mapped" : "unmapped",
+   list_for_each_entry(vma, _obj->vmas, list) {
+   const char *name, *comm;
+   if (vma->aspace) {
+   struct msm_gem_address_space *aspace = 
vma->aspace;
+   struct task_struct *task =
+   get_pid_task(aspace->pid, PIDTYPE_PID);
+   if (task) {
+   comm = kstrdup(task->comm, GFP_KERNEL);
+   } else {
+   comm = NULL;
+   }
+   name = aspace->name;
+   } else {
+   name = comm = NULL;
+   }
+   seq_printf(m, " [%s%s%s: aspace=%p, 
%08llx,%s,inuse=%d]",
+   name, comm ? ":" : "", comm ? comm : "",
+   vma->aspace, vma->iova,
+   vma->mapped ? "mapped" : "unmapped",
vma->inuse);
+   kfree(comm);
+   }
 
seq_puts(m, "\n");
}
diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h
index 9c573c4269cb..7b1c7a5f8eef 100644
--- a/drivers/gpu/drm/msm/msm_gem.h
+++ b/drivers/gpu/drm/msm/msm_gem.h
@@ -24,6 +24,11 @@ struct msm_gem_address_space {
spinlock_t lock; /* Protects drm_mm node allocation/removal */
struct msm_mmu *mmu;
struct kref kref;
+
+   /* For address spaces associated with a specific process, this
+* will be non-NULL:
+*/
+   struct pid *pid;
 };
 
 struct msm_gem_vma {
diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c 
b/drivers/gpu/drm/msm/msm_gem_vma.c
index 29cc1305cf37..80a8a266d68f 100644
--- a/drivers/gpu/drm/msm/msm_gem_vma.c
+++ b/drivers/gpu/drm/msm/msm_gem_vma.c
@@ -17,6 +17,7 @@ msm_gem_address_space_destroy(struct kref *kref)
drm_mm_takedown(>mm);
if (aspace->mmu)
aspace->mmu->funcs->destroy(aspace->mmu);
+   put_pid(aspace->pid);
kfree(aspace);
 }
 
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 951850804d77..ac8961187a73 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -825,10 +825,9 @@ static int get_clocks(struct platform_device *pdev, struct 
msm_gpu *gpu)
 
 /* Return a new address space for a msm_drm_private instance */
 struct msm_gem_address_space *
-msm_gpu_create_private_address_space(struct msm_gpu *gpu)
+msm_gpu_create_private_address_space(struct msm_gpu *gpu, struct task_struct 
*task)
 {
struct msm_gem_address_space *aspace = NULL;
-
if (!gpu)
return NULL;
 
@@ -836,8 +835,11 @@ msm_gpu_create_private_address_space(struct msm_gpu *gpu)
 * If the target doesn't support private address spaces then return
 * the global one
 */
-   if (gpu->funcs->create_private_address_space)
+   if (gpu->funcs->create_private_address_space) {
aspace = gpu->funcs->create_private_address_space(gpu);
+   if (!IS_ERR(aspace))
+   aspace->pid = 

[PATCH 08/19] iommu/arm-smmu: constify some helpers

2020-08-13 Thread Rob Clark
From: Rob Clark 

Sprinkle a few `const`s where helpers don't need write access.

Signed-off-by: Rob Clark 
---
 drivers/iommu/arm/arm-smmu/arm-smmu.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h 
b/drivers/iommu/arm/arm-smmu/arm-smmu.h
index 59ff3fc5c6c8..27c8fc50 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
@@ -377,7 +377,7 @@ struct arm_smmu_master_cfg {
s16 smendx[];
 };
 
-static inline u32 arm_smmu_lpae_tcr(struct io_pgtable_cfg *cfg)
+static inline u32 arm_smmu_lpae_tcr(const struct io_pgtable_cfg *cfg)
 {
u32 tcr = FIELD_PREP(ARM_SMMU_TCR_TG0, cfg->arm_lpae_s1_cfg.tcr.tg) |
FIELD_PREP(ARM_SMMU_TCR_SH0, cfg->arm_lpae_s1_cfg.tcr.sh) |
@@ -398,13 +398,13 @@ static inline u32 arm_smmu_lpae_tcr(struct io_pgtable_cfg 
*cfg)
return tcr;
 }
 
-static inline u32 arm_smmu_lpae_tcr2(struct io_pgtable_cfg *cfg)
+static inline u32 arm_smmu_lpae_tcr2(const struct io_pgtable_cfg *cfg)
 {
return FIELD_PREP(ARM_SMMU_TCR2_PASIZE, cfg->arm_lpae_s1_cfg.tcr.ips) |
   FIELD_PREP(ARM_SMMU_TCR2_SEP, ARM_SMMU_TCR2_SEP_UPSTREAM);
 }
 
-static inline u32 arm_smmu_lpae_vtcr(struct io_pgtable_cfg *cfg)
+static inline u32 arm_smmu_lpae_vtcr(const struct io_pgtable_cfg *cfg)
 {
return ARM_SMMU_VTCR_RES1 |
   FIELD_PREP(ARM_SMMU_VTCR_PS, cfg->arm_lpae_s2_cfg.vtcr.ps) |
-- 
2.26.2



[PATCH 09/19] iommu/arm-smmu-qcom: Add implementation for the adreno GPU SMMU

2020-08-13 Thread Rob Clark
From: Jordan Crouse 

Add a special implementation for the SMMU attached to most Adreno GPU
target triggered from the qcom,adreno-smmu compatible string.

The new Adreno SMMU implementation will enable split pagetables
(TTBR1) for the domain attached to the GPU device (SID 0) and
hard code it context bank 0 so the GPU hardware can implement
per-instance pagetables.

Co-developed-by: Rob Clark 
Signed-off-by: Jordan Crouse 
Signed-off-by: Rob Clark 
---
 drivers/iommu/arm/arm-smmu/arm-smmu-impl.c |   3 +
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 149 -
 drivers/iommu/arm/arm-smmu/arm-smmu.h  |   1 +
 3 files changed, 151 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
index 88f17cc33023..d199b4bff15d 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
@@ -223,6 +223,9 @@ struct arm_smmu_device *arm_smmu_impl_init(struct 
arm_smmu_device *smmu)
of_device_is_compatible(np, "qcom,sm8250-smmu-500"))
return qcom_smmu_impl_init(smmu);
 
+   if (of_device_is_compatible(smmu->dev->of_node, "qcom,adreno-smmu"))
+   return qcom_adreno_smmu_impl_init(smmu);
+
if (of_device_is_compatible(np, "marvell,ap806-smmu-500"))
smmu->impl = _mmu500_impl;
 
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index be4318044f96..5640d9960610 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -3,6 +3,7 @@
  * Copyright (c) 2019, The Linux Foundation. All rights reserved.
  */
 
+#include 
 #include 
 #include 
 
@@ -12,6 +13,132 @@ struct qcom_smmu {
struct arm_smmu_device smmu;
 };
 
+#define QCOM_ADRENO_SMMU_GPU_SID 0
+
+static bool qcom_adreno_smmu_is_gpu_device(struct device *dev)
+{
+   struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+   int i;
+
+   /*
+* The GPU will always use SID 0 so that is a handy way to uniquely
+* identify it and configure it for per-instance pagetables
+*/
+   for (i = 0; i < fwspec->num_ids; i++) {
+   u16 sid = FIELD_GET(ARM_SMMU_SMR_ID, fwspec->ids[i]);
+
+   if (sid == QCOM_ADRENO_SMMU_GPU_SID)
+   return true;
+   }
+
+   return false;
+}
+
+static const struct io_pgtable_cfg *qcom_adreno_smmu_get_ttbr1_cfg(
+   const void *cookie)
+{
+   struct arm_smmu_domain *smmu_domain = (void *)cookie;
+   struct io_pgtable *pgtable =
+   io_pgtable_ops_to_pgtable(smmu_domain->pgtbl_ops);
+   return >cfg;
+}
+
+/*
+ * Local implementation to configure TTBR0 with the specified pagetable config.
+ * The GPU driver will call this to enable TTBR0 when per-instance pagetables
+ * are active
+ */
+
+static int qcom_adreno_smmu_set_ttbr0_cfg(const void *cookie,
+   const struct io_pgtable_cfg *pgtbl_cfg)
+{
+   struct arm_smmu_domain *smmu_domain = (void *)cookie;
+   struct io_pgtable *pgtable = 
io_pgtable_ops_to_pgtable(smmu_domain->pgtbl_ops);
+   struct arm_smmu_cfg *cfg = _domain->cfg;
+   struct arm_smmu_cb *cb = _domain->smmu->cbs[cfg->cbndx];
+
+   /* The domain must have split pagetables already enabled */
+   if (cb->tcr[0] & ARM_SMMU_TCR_EPD1)
+   return -EINVAL;
+
+   /* If the pagetable config is NULL, disable TTBR0 */
+   if (!pgtbl_cfg) {
+   /* Do nothing if it is already disabled */
+   if ((cb->tcr[0] & ARM_SMMU_TCR_EPD0))
+   return -EINVAL;
+
+   /* Set TCR to the original configuration */
+   cb->tcr[0] = arm_smmu_lpae_tcr(>cfg);
+   cb->ttbr[0] = FIELD_PREP(ARM_SMMU_TTBRn_ASID, cb->cfg->asid);
+   } else {
+   u32 tcr = cb->tcr[0];
+
+   /* Don't call this again if TTBR0 is already enabled */
+   if (!(cb->tcr[0] & ARM_SMMU_TCR_EPD0))
+   return -EINVAL;
+
+   tcr |= arm_smmu_lpae_tcr(pgtbl_cfg);
+   tcr &= ~(ARM_SMMU_TCR_EPD0 | ARM_SMMU_TCR_EPD1);
+
+   cb->tcr[0] = tcr;
+   cb->ttbr[0] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr;
+   cb->ttbr[0] |= FIELD_PREP(ARM_SMMU_TTBRn_ASID, cb->cfg->asid);
+   }
+
+   arm_smmu_write_context_bank(smmu_domain->smmu, cb->cfg->cbndx);
+
+   return 0;
+}
+
+static int qcom_adreno_smmu_alloc_context_bank(struct arm_smmu_domain 
*smmu_domain,
+   struct device *dev, int start, int count)
+{
+   struct arm_smmu_device *smmu = smmu_domain->smmu;
+
+   /*
+* Assign context bank 0 to the GPU device so the GPU hardware can
+* switch pagetables
+*/
+   if (qcom_adreno_smmu_is_gpu_device(dev)) {
+   start = 0;
+   count = 1;
+   } else {
+   start 

[PATCH 02/19] iommu/arm-smmu: Pass io-pgtable config to implementation specific function

2020-08-13 Thread Rob Clark
From: Jordan Crouse 

Construct the io-pgtable config before calling the implementation specific
init_context function and pass it so the implementation specific function
can get a chance to change it before the io-pgtable is created.

Signed-off-by: Jordan Crouse 
Signed-off-by: Rob Clark 
---
 drivers/iommu/arm/arm-smmu/arm-smmu-impl.c |  3 ++-
 drivers/iommu/arm/arm-smmu/arm-smmu.c  | 11 ++-
 drivers/iommu/arm/arm-smmu/arm-smmu.h  |  3 ++-
 3 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
index f4ff124a1967..a9861dcd0884 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
@@ -68,7 +68,8 @@ static int cavium_cfg_probe(struct arm_smmu_device *smmu)
return 0;
 }
 
-static int cavium_init_context(struct arm_smmu_domain *smmu_domain)
+static int cavium_init_context(struct arm_smmu_domain *smmu_domain,
+   struct io_pgtable_cfg *pgtbl_cfg)
 {
struct cavium_smmu *cs = container_of(smmu_domain->smmu,
  struct cavium_smmu, smmu);
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 09c42af9f31e..37d8d49299b4 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -795,11 +795,6 @@ static int arm_smmu_init_domain_context(struct 
iommu_domain *domain,
cfg->asid = cfg->cbndx;
 
smmu_domain->smmu = smmu;
-   if (smmu->impl && smmu->impl->init_context) {
-   ret = smmu->impl->init_context(smmu_domain);
-   if (ret)
-   goto out_unlock;
-   }
 
pgtbl_cfg = (struct io_pgtable_cfg) {
.pgsize_bitmap  = smmu->pgsize_bitmap,
@@ -810,6 +805,12 @@ static int arm_smmu_init_domain_context(struct 
iommu_domain *domain,
.iommu_dev  = smmu->dev,
};
 
+   if (smmu->impl && smmu->impl->init_context) {
+   ret = smmu->impl->init_context(smmu_domain, _cfg);
+   if (ret)
+   goto out_clear_smmu;
+   }
+
if (smmu_domain->non_strict)
pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT;
 
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h 
b/drivers/iommu/arm/arm-smmu/arm-smmu.h
index d890a4a968e8..83294516ac08 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
@@ -386,7 +386,8 @@ struct arm_smmu_impl {
u64 val);
int (*cfg_probe)(struct arm_smmu_device *smmu);
int (*reset)(struct arm_smmu_device *smmu);
-   int (*init_context)(struct arm_smmu_domain *smmu_domain);
+   int (*init_context)(struct arm_smmu_domain *smmu_domain,
+   struct io_pgtable_cfg *cfg);
void (*tlb_sync)(struct arm_smmu_device *smmu, int page, int sync,
 int status);
int (*def_domain_type)(struct device *dev);
-- 
2.26.2



[PATCH 11/19] drm/msm: Add a context pointer to the submitqueue

2020-08-13 Thread Rob Clark
From: Jordan Crouse 

Each submitqueue is attached to a context. Add a pointer to the
context to the submitqueue at create time and refcount it so
that it stays around through the life of the queue.

Co-developed-by: Rob Clark 
Signed-off-by: Jordan Crouse 
Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/msm/msm_drv.c |  3 ++-
 drivers/gpu/drm/msm/msm_drv.h | 20 
 drivers/gpu/drm/msm/msm_gem.h |  1 +
 drivers/gpu/drm/msm/msm_gem_submit.c  |  6 +++---
 drivers/gpu/drm/msm/msm_gpu.h |  1 +
 drivers/gpu/drm/msm/msm_submitqueue.c |  3 +++
 6 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 7d641c7e3514..01845a3b8d52 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -594,6 +594,7 @@ static int context_init(struct drm_device *dev, struct 
drm_file *file)
if (!ctx)
return -ENOMEM;
 
+   kref_init(>ref);
msm_submitqueue_init(dev, ctx);
 
ctx->aspace = priv->gpu ? priv->gpu->aspace : NULL;
@@ -615,7 +616,7 @@ static int msm_open(struct drm_device *dev, struct drm_file 
*file)
 static void context_close(struct msm_file_private *ctx)
 {
msm_submitqueue_close(ctx);
-   kfree(ctx);
+   msm_file_private_put(ctx);
 }
 
 static void msm_postclose(struct drm_device *dev, struct drm_file *file)
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index af259b0573ea..4561bfb5e745 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -57,6 +57,7 @@ struct msm_file_private {
struct list_head submitqueues;
int queueid;
struct msm_gem_address_space *aspace;
+   struct kref ref;
 };
 
 enum msm_mdp_plane_property {
@@ -428,6 +429,25 @@ void msm_submitqueue_close(struct msm_file_private *ctx);
 
 void msm_submitqueue_destroy(struct kref *kref);
 
+static inline void __msm_file_private_destroy(struct kref *kref)
+{
+   struct msm_file_private *ctx = container_of(kref,
+   struct msm_file_private, ref);
+
+   kfree(ctx);
+}
+
+static inline void msm_file_private_put(struct msm_file_private *ctx)
+{
+   kref_put(>ref, __msm_file_private_destroy);
+}
+
+static inline struct msm_file_private *msm_file_private_get(
+   struct msm_file_private *ctx)
+{
+   kref_get(>ref);
+   return ctx;
+}
 
 #define DBG(fmt, ...) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
 #define VERB(fmt, ...) if (0) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h
index 972490b14ba5..9c573c4269cb 100644
--- a/drivers/gpu/drm/msm/msm_gem.h
+++ b/drivers/gpu/drm/msm/msm_gem.h
@@ -142,6 +142,7 @@ struct msm_gem_submit {
bool valid; /* true if no cmdstream patching needed */
bool in_rb; /* "sudo" mode, copy cmds into RB */
struct msm_ringbuffer *ring;
+   struct msm_file_private *ctx;
unsigned int nr_cmds;
unsigned int nr_bos;
u32 ident; /* A "identifier" for the submit for logging */
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c 
b/drivers/gpu/drm/msm/msm_gem_submit.c
index 8cb9aa15ff90..1464b04d25d3 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -27,7 +27,7 @@
 #define BO_PINNED   0x2000
 
 static struct msm_gem_submit *submit_create(struct drm_device *dev,
-   struct msm_gpu *gpu, struct msm_gem_address_space *aspace,
+   struct msm_gpu *gpu,
struct msm_gpu_submitqueue *queue, uint32_t nr_bos,
uint32_t nr_cmds)
 {
@@ -43,7 +43,7 @@ static struct msm_gem_submit *submit_create(struct drm_device 
*dev,
return NULL;
 
submit->dev = dev;
-   submit->aspace = aspace;
+   submit->aspace = queue->ctx->aspace;
submit->gpu = gpu;
submit->fence = NULL;
submit->cmd = (void *)>bos[nr_bos];
@@ -677,7 +677,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
}
}
 
-   submit = submit_create(dev, gpu, ctx->aspace, queue, args->nr_bos,
+   submit = submit_create(dev, gpu, queue, args->nr_bos,
args->nr_cmds);
if (!submit) {
ret = -ENOMEM;
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index f91b141add75..97c527e98391 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -190,6 +190,7 @@ struct msm_gpu_submitqueue {
u32 flags;
u32 prio;
int faults;
+   struct msm_file_private *ctx;
struct list_head node;
struct kref ref;
 };
diff --git a/drivers/gpu/drm/msm/msm_submitqueue.c 
b/drivers/gpu/drm/msm/msm_submitqueue.c
index 90c9d84e6155..c3d206105d28 100644
--- a/drivers/gpu/drm/msm/msm_submitqueue.c
+++ b/drivers/gpu/drm/msm/msm_submitqueue.c
@@ -12,6 +12,8 @@ void 

[PATCH 03/19] iommu/arm-smmu: Add support for split pagetables

2020-08-13 Thread Rob Clark
From: Jordan Crouse 

Enable TTBR1 for a context bank if IO_PGTABLE_QUIRK_ARM_TTBR1 is selected
by the io-pgtable configuration.

Signed-off-by: Jordan Crouse 
Signed-off-by: Rob Clark 
---
 drivers/iommu/arm/arm-smmu/arm-smmu.c | 21 -
 drivers/iommu/arm/arm-smmu/arm-smmu.h | 25 +++--
 2 files changed, 35 insertions(+), 11 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 37d8d49299b4..976d43a7f2ff 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -552,11 +552,15 @@ static void arm_smmu_init_context_bank(struct 
arm_smmu_domain *smmu_domain,
cb->ttbr[0] = pgtbl_cfg->arm_v7s_cfg.ttbr;
cb->ttbr[1] = 0;
} else {
-   cb->ttbr[0] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr;
-   cb->ttbr[0] |= FIELD_PREP(ARM_SMMU_TTBRn_ASID,
- cfg->asid);
+   cb->ttbr[0] = FIELD_PREP(ARM_SMMU_TTBRn_ASID,
+   cfg->asid);
cb->ttbr[1] = FIELD_PREP(ARM_SMMU_TTBRn_ASID,
-cfg->asid);
+   cfg->asid);
+
+   if (pgtbl_cfg->quirks & IO_PGTABLE_QUIRK_ARM_TTBR1)
+   cb->ttbr[1] |= pgtbl_cfg->arm_lpae_s1_cfg.ttbr;
+   else
+   cb->ttbr[0] |= pgtbl_cfg->arm_lpae_s1_cfg.ttbr;
}
} else {
cb->ttbr[0] = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
@@ -822,7 +826,14 @@ static int arm_smmu_init_domain_context(struct 
iommu_domain *domain,
 
/* Update the domain's page sizes to reflect the page table format */
domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
-   domain->geometry.aperture_end = (1UL << ias) - 1;
+
+   if (pgtbl_cfg.quirks & IO_PGTABLE_QUIRK_ARM_TTBR1) {
+   domain->geometry.aperture_start = ~0UL << ias;
+   domain->geometry.aperture_end = ~0UL;
+   } else {
+   domain->geometry.aperture_end = (1UL << ias) - 1;
+   }
+
domain->geometry.force_aperture = true;
 
/* Initialise the context bank with our page table cfg */
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h 
b/drivers/iommu/arm/arm-smmu/arm-smmu.h
index 83294516ac08..f3e456893f28 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
@@ -169,10 +169,12 @@ enum arm_smmu_cbar_type {
 #define ARM_SMMU_CB_TCR0x30
 #define ARM_SMMU_TCR_EAE   BIT(31)
 #define ARM_SMMU_TCR_EPD1  BIT(23)
+#define ARM_SMMU_TCR_A1BIT(22)
 #define ARM_SMMU_TCR_TG0   GENMASK(15, 14)
 #define ARM_SMMU_TCR_SH0   GENMASK(13, 12)
 #define ARM_SMMU_TCR_ORGN0 GENMASK(11, 10)
 #define ARM_SMMU_TCR_IRGN0 GENMASK(9, 8)
+#define ARM_SMMU_TCR_EPD0  BIT(7)
 #define ARM_SMMU_TCR_T0SZ  GENMASK(5, 0)
 
 #define ARM_SMMU_VTCR_RES1 BIT(31)
@@ -350,12 +352,23 @@ struct arm_smmu_domain {
 
 static inline u32 arm_smmu_lpae_tcr(struct io_pgtable_cfg *cfg)
 {
-   return ARM_SMMU_TCR_EPD1 |
-  FIELD_PREP(ARM_SMMU_TCR_TG0, cfg->arm_lpae_s1_cfg.tcr.tg) |
-  FIELD_PREP(ARM_SMMU_TCR_SH0, cfg->arm_lpae_s1_cfg.tcr.sh) |
-  FIELD_PREP(ARM_SMMU_TCR_ORGN0, cfg->arm_lpae_s1_cfg.tcr.orgn) |
-  FIELD_PREP(ARM_SMMU_TCR_IRGN0, cfg->arm_lpae_s1_cfg.tcr.irgn) |
-  FIELD_PREP(ARM_SMMU_TCR_T0SZ, cfg->arm_lpae_s1_cfg.tcr.tsz);
+   u32 tcr = FIELD_PREP(ARM_SMMU_TCR_TG0, cfg->arm_lpae_s1_cfg.tcr.tg) |
+   FIELD_PREP(ARM_SMMU_TCR_SH0, cfg->arm_lpae_s1_cfg.tcr.sh) |
+   FIELD_PREP(ARM_SMMU_TCR_ORGN0, cfg->arm_lpae_s1_cfg.tcr.orgn) |
+   FIELD_PREP(ARM_SMMU_TCR_IRGN0, cfg->arm_lpae_s1_cfg.tcr.irgn) |
+   FIELD_PREP(ARM_SMMU_TCR_T0SZ, cfg->arm_lpae_s1_cfg.tcr.tsz);
+
+   /*
+   * When TTBR1 is selected shift the TCR fields by 16 bits and disable
+   * translation in TTBR0
+   */
+   if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_TTBR1) {
+   tcr = (tcr << 16) & ~ARM_SMMU_TCR_A1;
+   tcr |= ARM_SMMU_TCR_EPD0;
+   } else
+   tcr |= ARM_SMMU_TCR_EPD1;
+
+   return tcr;
 }
 
 static inline u32 arm_smmu_lpae_tcr2(struct io_pgtable_cfg *cfg)
-- 
2.26.2



[PATCH 05/19] iommu: add private interface for adreno-smmu

2020-08-13 Thread Rob Clark
From: Rob Clark 

This interface will be used for drm/msm to coordinate with the
qcom_adreno_smmu_impl to enable/disable TTBR0 translation.

Once TTBR0 translation is enabled, the GPU's CP (Command Processor)
will directly switch TTBR0 pgtables (and do the necessary TLB inv)
synchronized to the GPU's operation.  But help from the SMMU driver
is needed to initially bootstrap TTBR0 translation, which cannot be
done from the GPU.

Since this is a very special case, a private interface is used to
avoid adding highly driver specific things to the public iommu
interface.

Signed-off-by: Rob Clark 
---
 include/linux/adreno-smmu-priv.h | 36 
 1 file changed, 36 insertions(+)
 create mode 100644 include/linux/adreno-smmu-priv.h

diff --git a/include/linux/adreno-smmu-priv.h b/include/linux/adreno-smmu-priv.h
new file mode 100644
index ..a889f28afb42
--- /dev/null
+++ b/include/linux/adreno-smmu-priv.h
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 Google, Inc
+ */
+
+#ifndef __ADRENO_SMMU_PRIV_H
+#define __ADRENO_SMMU_PRIV_H
+
+#include 
+
+/**
+ * struct adreno_smmu_priv - private interface between adreno-smmu and GPU
+ *
+ * @cookie:An opque token provided by adreno-smmu and passed
+ * back into the callbacks
+ * @get_ttbr1_cfg: Get the TTBR1 config for the GPUs context-bank
+ * @set_ttbr0_cfg: Set the TTBR0 config for the GPUs context bank.  A
+ * NULL config disables TTBR0 translation, otherwise
+ * TTBR0 translation is enabled with the specified cfg
+ *
+ * The GPU driver (drm/msm) and adreno-smmu work together for controlling
+ * the GPU's SMMU instance.  This is by necessity, as the GPU is directly
+ * updating the SMMU for context switches, while on the other hand we do
+ * not want to duplicate all of the initial setup logic from arm-smmu.
+ *
+ * This private interface is used for the two drivers to coordinate.  The
+ * cookie and callback functions are populated when the GPU driver attaches
+ * it's domain.
+ */
+struct adreno_smmu_priv {
+const void *cookie;
+const struct io_pgtable_cfg *(*get_ttbr1_cfg)(const void *cookie);
+int (*set_ttbr0_cfg)(const void *cookie, const struct io_pgtable_cfg *cfg);
+};
+
+#endif /* __ADRENO_SMMU_PRIV_H */
\ No newline at end of file
-- 
2.26.2



[PATCH 06/19] drm/msm/gpu: add dev_to_gpu() helper

2020-08-13 Thread Rob Clark
From: Rob Clark 

In a later patch, the drvdata will not directly be 'struct msm_gpu *',
so add a helper to reduce the churn.

Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/msm/adreno/adreno_device.c | 10 --
 drivers/gpu/drm/msm/msm_gpu.c  |  6 +++---
 drivers/gpu/drm/msm/msm_gpu.h  |  5 +
 3 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c 
b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 9eeb46bf2a5d..26664e1b30c0 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -282,7 +282,7 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev)
int ret;
 
if (pdev)
-   gpu = platform_get_drvdata(pdev);
+   gpu = dev_to_gpu(>dev);
 
if (!gpu) {
dev_err_once(dev->dev, "no GPU device was found\n");
@@ -425,7 +425,7 @@ static int adreno_bind(struct device *dev, struct device 
*master, void *data)
 static void adreno_unbind(struct device *dev, struct device *master,
void *data)
 {
-   struct msm_gpu *gpu = dev_get_drvdata(dev);
+   struct msm_gpu *gpu = dev_to_gpu(dev);
 
pm_runtime_force_suspend(dev);
gpu->funcs->destroy(gpu);
@@ -490,16 +490,14 @@ static const struct of_device_id dt_match[] = {
 #ifdef CONFIG_PM
 static int adreno_resume(struct device *dev)
 {
-   struct platform_device *pdev = to_platform_device(dev);
-   struct msm_gpu *gpu = platform_get_drvdata(pdev);
+   struct msm_gpu *gpu = dev_to_gpu(dev);
 
return gpu->funcs->pm_resume(gpu);
 }
 
 static int adreno_suspend(struct device *dev)
 {
-   struct platform_device *pdev = to_platform_device(dev);
-   struct msm_gpu *gpu = platform_get_drvdata(pdev);
+   struct msm_gpu *gpu = dev_to_gpu(dev);
 
return gpu->funcs->pm_suspend(gpu);
 }
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index d5645472b25d..6aa9e04e52e7 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -24,7 +24,7 @@
 static int msm_devfreq_target(struct device *dev, unsigned long *freq,
u32 flags)
 {
-   struct msm_gpu *gpu = platform_get_drvdata(to_platform_device(dev));
+   struct msm_gpu *gpu = dev_to_gpu(dev);
struct dev_pm_opp *opp;
 
opp = devfreq_recommended_opp(dev, freq, flags);
@@ -45,7 +45,7 @@ static int msm_devfreq_target(struct device *dev, unsigned 
long *freq,
 static int msm_devfreq_get_dev_status(struct device *dev,
struct devfreq_dev_status *status)
 {
-   struct msm_gpu *gpu = platform_get_drvdata(to_platform_device(dev));
+   struct msm_gpu *gpu = dev_to_gpu(dev);
ktime_t time;
 
if (gpu->funcs->gpu_get_freq)
@@ -64,7 +64,7 @@ static int msm_devfreq_get_dev_status(struct device *dev,
 
 static int msm_devfreq_get_cur_freq(struct device *dev, unsigned long *freq)
 {
-   struct msm_gpu *gpu = platform_get_drvdata(to_platform_device(dev));
+   struct msm_gpu *gpu = dev_to_gpu(dev);
 
if (gpu->funcs->gpu_get_freq)
*freq = gpu->funcs->gpu_get_freq(gpu);
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index 0db117a7339b..8bda7beaed4b 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -141,6 +141,11 @@ struct msm_gpu {
struct msm_gpu_state *crashstate;
 };
 
+static inline struct msm_gpu *dev_to_gpu(struct device *dev)
+{
+   return dev_get_drvdata(dev);
+}
+
 /* It turns out that all targets use the same ringbuffer size */
 #define MSM_GPU_RINGBUFFER_SZ SZ_32K
 #define MSM_GPU_RINGBUFFER_BLKSIZE 32
-- 
2.26.2



[PATCH 10/19] dt-bindings: arm-smmu: Add compatible string for Adreno GPU SMMU

2020-08-13 Thread Rob Clark
From: Jordan Crouse 

Every Qcom Adreno GPU has an embedded SMMU for its own use. These
devices depend on unique features such as split pagetables,
different stall/halt requirements and other settings. Identify them
with a compatible string so that they can be identified in the
arm-smmu implementation specific code.

Signed-off-by: Jordan Crouse 
Reviewed-by: Rob Herring 
Signed-off-by: Rob Clark 
---
 Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 4 
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml 
b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
index 503160a7b9a0..5ec5d0d691f6 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
@@ -40,6 +40,10 @@ properties:
   - qcom,sm8150-smmu-500
   - qcom,sm8250-smmu-500
   - const: arm,mmu-500
+  - description: Qcom Adreno GPUs implementing "arm,smmu-v2"
+items:
+  - const: qcom,adreno-smmu
+  - const: qcom,smmu-v2
   - description: Marvell SoCs implementing "arm,mmu-500"
 items:
   - const: marvell,ap806-smmu-500
-- 
2.26.2



[PATCH 07/19] drm/msm: set adreno_smmu as gpu's drvdata

2020-08-13 Thread Rob Clark
From: Rob Clark 

This will be populated by adreno-smmu, to provide a way for coordinating
enabling/disabling TTBR0 translation.

Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/msm/adreno/adreno_device.c | 2 --
 drivers/gpu/drm/msm/msm_gpu.c  | 2 +-
 drivers/gpu/drm/msm/msm_gpu.h  | 6 +-
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c 
b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 26664e1b30c0..58e03b20e1c7 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -417,8 +417,6 @@ static int adreno_bind(struct device *dev, struct device 
*master, void *data)
return PTR_ERR(gpu);
}
 
-   dev_set_drvdata(dev, gpu);
-
return 0;
 }
 
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 6aa9e04e52e7..806eb0957280 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -892,7 +892,7 @@ int msm_gpu_init(struct drm_device *drm, struct 
platform_device *pdev,
gpu->gpu_cx = NULL;
 
gpu->pdev = pdev;
-   platform_set_drvdata(pdev, gpu);
+   platform_set_drvdata(pdev, >adreno_smmu);
 
msm_devfreq_init(gpu);
 
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index 8bda7beaed4b..f91b141add75 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -7,6 +7,7 @@
 #ifndef __MSM_GPU_H__
 #define __MSM_GPU_H__
 
+#include 
 #include 
 #include 
 #include 
@@ -73,6 +74,8 @@ struct msm_gpu {
struct platform_device *pdev;
const struct msm_gpu_funcs *funcs;
 
+   struct adreno_smmu_priv adreno_smmu;
+
/* performance counters (hw & sw): */
spinlock_t perf_lock;
bool perfcntr_active;
@@ -143,7 +146,8 @@ struct msm_gpu {
 
 static inline struct msm_gpu *dev_to_gpu(struct device *dev)
 {
-   return dev_get_drvdata(dev);
+   struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(dev);
+   return container_of(adreno_smmu, struct msm_gpu, adreno_smmu);
 }
 
 /* It turns out that all targets use the same ringbuffer size */
-- 
2.26.2



[PATCH 04/19] iommu/arm-smmu: Prepare for the adreno-smmu implementation

2020-08-13 Thread Rob Clark
From: Jordan Crouse 

Do a bit of prep work to add the upcoming adreno-smmu implementation.

Add an hook to allow the implementation to choose which context banks
to allocate.

Move some of the common structs to arm-smmu.h in anticipation of them
being used by the implementations and update some of the existing hooks
to pass more information that the implementation will need.

These modifications will be used by the upcoming Adreno SMMU
implementation to identify the GPU device and properly configure it
for pagetable switching.

Co-developed-by: Rob Clark 
Signed-off-by: Jordan Crouse 
Signed-off-by: Rob Clark 
---
 drivers/iommu/arm/arm-smmu/arm-smmu-impl.c |  2 +-
 drivers/iommu/arm/arm-smmu/arm-smmu.c  | 69 ++
 drivers/iommu/arm/arm-smmu/arm-smmu.h  | 51 +++-
 3 files changed, 68 insertions(+), 54 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
index a9861dcd0884..88f17cc33023 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
@@ -69,7 +69,7 @@ static int cavium_cfg_probe(struct arm_smmu_device *smmu)
 }
 
 static int cavium_init_context(struct arm_smmu_domain *smmu_domain,
-   struct io_pgtable_cfg *pgtbl_cfg)
+   struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
 {
struct cavium_smmu *cs = container_of(smmu_domain->smmu,
  struct cavium_smmu, smmu);
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 976d43a7f2ff..e63a480d7f71 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -65,41 +65,10 @@ module_param(disable_bypass, bool, S_IRUGO);
 MODULE_PARM_DESC(disable_bypass,
"Disable bypass streams such that incoming transactions from devices 
that are not attached to an iommu domain will report an abort back to the 
device and will not be allowed to pass through the SMMU.");
 
-struct arm_smmu_s2cr {
-   struct iommu_group  *group;
-   int count;
-   enum arm_smmu_s2cr_type type;
-   enum arm_smmu_s2cr_privcfg  privcfg;
-   u8  cbndx;
-};
-
 #define s2cr_init_val (struct arm_smmu_s2cr){  \
.type = disable_bypass ? S2CR_TYPE_FAULT : S2CR_TYPE_BYPASS,\
 }
 
-struct arm_smmu_smr {
-   u16 mask;
-   u16 id;
-   boolvalid;
-};
-
-struct arm_smmu_cb {
-   u64 ttbr[2];
-   u32 tcr[2];
-   u32 mair[2];
-   struct arm_smmu_cfg *cfg;
-};
-
-struct arm_smmu_master_cfg {
-   struct arm_smmu_device  *smmu;
-   s16 smendx[];
-};
-#define INVALID_SMENDX -1
-#define cfg_smendx(cfg, fw, i) \
-   (i >= fw->num_ids ? INVALID_SMENDX : cfg->smendx[i])
-#define for_each_cfg_sme(cfg, fw, i, idx) \
-   for (i = 0; idx = cfg_smendx(cfg, fw, i), i < fw->num_ids; ++i)
-
 static bool using_legacy_binding, using_generic_binding;
 
 static inline int arm_smmu_rpm_get(struct arm_smmu_device *smmu)
@@ -234,19 +203,6 @@ static int arm_smmu_register_legacy_master(struct device 
*dev,
 }
 #endif /* CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS */
 
-static int __arm_smmu_alloc_bitmap(unsigned long *map, int start, int end)
-{
-   int idx;
-
-   do {
-   idx = find_next_zero_bit(map, end, start);
-   if (idx == end)
-   return -ENOSPC;
-   } while (test_and_set_bit(idx, map));
-
-   return idx;
-}
-
 static void __arm_smmu_free_bitmap(unsigned long *map, int idx)
 {
clear_bit(idx, map);
@@ -578,7 +534,7 @@ static void arm_smmu_init_context_bank(struct 
arm_smmu_domain *smmu_domain,
}
 }
 
-static void arm_smmu_write_context_bank(struct arm_smmu_device *smmu, int idx)
+void arm_smmu_write_context_bank(struct arm_smmu_device *smmu, int idx)
 {
u32 reg;
bool stage1;
@@ -665,7 +621,8 @@ static void arm_smmu_write_context_bank(struct 
arm_smmu_device *smmu, int idx)
 }
 
 static int arm_smmu_init_domain_context(struct iommu_domain *domain,
-   struct arm_smmu_device *smmu)
+   struct arm_smmu_device *smmu,
+   struct device *dev)
 {
int irq, start, ret = 0;
unsigned long ias, oas;
@@ -780,10 +737,20 @@ static int arm_smmu_init_domain_context(struct 
iommu_domain *domain,
ret = -EINVAL;
goto out_unlock;
}
-   ret = __arm_smmu_alloc_bitmap(smmu->context_map, start,
+
+   smmu_domain->smmu = smmu;
+
+   if (smmu->impl && smmu->impl->alloc_context_bank)
+ 

[PATCH 01/19] drm/msm: remove dangling submitqueue references

2020-08-13 Thread Rob Clark
From: Rob Clark 

Currently it doesn't matter, since we free the ctx immediately.  But
when we start refcnt'ing the ctx, we don't want old dangling list
entries to hang around.

Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/msm/msm_submitqueue.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/msm_submitqueue.c 
b/drivers/gpu/drm/msm/msm_submitqueue.c
index a1d94be7883a..90c9d84e6155 100644
--- a/drivers/gpu/drm/msm/msm_submitqueue.c
+++ b/drivers/gpu/drm/msm/msm_submitqueue.c
@@ -49,8 +49,10 @@ void msm_submitqueue_close(struct msm_file_private *ctx)
 * No lock needed in close and there won't
 * be any more user ioctls coming our way
 */
-   list_for_each_entry_safe(entry, tmp, >submitqueues, node)
+   list_for_each_entry_safe(entry, tmp, >submitqueues, node) {
+   list_del(>node);
msm_submitqueue_put(entry);
+   }
 }
 
 int msm_submitqueue_create(struct drm_device *drm, struct msm_file_private 
*ctx,
-- 
2.26.2



[PATCH v2] MIPS: ftrace: Remove redundant #ifdef CONFIG_DYNAMIC_FTRACE

2020-08-13 Thread Zejiang Tang
There exists redundant #ifdef CONFIG_DYNAMIC_FTRACE in ftrace.c, remove it.

Signed-off-by: Zejiang Tang 
Reviewed-by: Steven Rostedt (VMware) 
---
 arch/mips/kernel/ftrace.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c
index 2625232..f57e68f 100644
--- a/arch/mips/kernel/ftrace.c
+++ b/arch/mips/kernel/ftrace.c
@@ -37,10 +37,6 @@ void arch_ftrace_update_code(int command)
ftrace_modify_all_code(command);
 }
 
-#endif
-
-#ifdef CONFIG_DYNAMIC_FTRACE
-
 #define JAL 0x0c00 /* jump & link: ip --> ra, jump to target */
 #define ADDR_MASK 0x03ff   /*  op_code|addr : 31...26|25 0 */
 #define JUMP_RANGE_MASK ((1UL << 28) - 1)
-- 
2.1.0



[PATCH V2] vfio dma_map/unmap: optimized for hugetlbfs pages

2020-08-13 Thread Ming Mao
In the original process of pinning/unpinning pages for VFIO-devices,
to make sure the pages are contiguous, we have to check them one by one.
As a result, dma_map/unmap could spend a long time.
Using the hugetlb pages, we can avoid this problem.
All pages in hugetlb pages are contiguous.And the hugetlb
page should not be split.So we can delete the for loops and use
some operations(such as atomic_add,page_ref_add) instead.

Signed-off-by: Ming Mao 
---
 drivers/vfio/vfio_iommu_type1.c | 233 +++-
 1 file changed, 230 insertions(+), 3 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index 5e556ac91..8957013c1 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -415,6 +415,46 @@ static int put_pfn(unsigned long pfn, int prot)
return 0;
 }
 
+/*
+ * put pfns for a hugetlb page
+ * @start:the PAGE_SIZE-page we start to put,can be any page in this hugetlb 
page
+ * @npage:the number of PAGE_SIZE-pages need to put
+ * @prot:IOMMU_READ/WRITE
+ */
+static int hugetlb_put_pfn(unsigned long start, unsigned int npage, int prot)
+{
+   struct page *page;
+   struct page *head;
+
+   if (!npage || !pfn_valid(start))
+   return 0;
+
+   page = pfn_to_page(start);
+   if (!page || !PageHuge(page))
+   return 0;
+   head = compound_head(page);
+   /*
+* The last page should be in this hugetlb page.
+* The number of putting pages should be equal to the number
+* of getting pages.So the hugepage pinned refcount and the normal
+* page refcount can not be smaller than npage.
+*/
+   if ((head != compound_head(pfn_to_page(start + npage - 1)))
+   || (page_ref_count(head) < npage)
+   || (compound_pincount(page) < npage))
+   return 0;
+
+   if ((prot & IOMMU_WRITE) && !PageDirty(page))
+   set_page_dirty_lock(page);
+
+   atomic_sub(npage, compound_pincount_ptr(head));
+   if (page_ref_sub_and_test(head, npage))
+   __put_page(head);
+
+   mod_node_page_state(page_pgdat(head), NR_FOLL_PIN_RELEASED, npage);
+   return 1;
+}
+
 static int follow_fault_pfn(struct vm_area_struct *vma, struct mm_struct *mm,
unsigned long vaddr, unsigned long *pfn,
bool write_fault)
@@ -479,6 +519,105 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned 
long vaddr,
return ret;
 }
 
+static bool is_hugetlbpage(unsigned long pfn)
+{
+   struct page *page;
+
+   if (!pfn_valid(pfn))
+   return false;
+
+   page = pfn_to_page(pfn);
+   /* only check for hugetlb pages */
+   if (!page || !PageHuge(page))
+   return false;
+
+   return true;
+}
+
+/*
+ * get the number of residual PAGE_SIZE-pages in a hugetlb page
+ * (including the page which pointed by this address)
+ * @address: we count residual pages from this address to the end of
+ * a hugetlb page
+ * @order: the order of the same hugetlb page
+ */
+static long
+hugetlb_get_residual_pages(unsigned long address, unsigned int order)
+{
+   unsigned long hugetlb_npage;
+   unsigned long hugetlb_mask;
+
+   if (!order)
+   return -1;
+
+   hugetlb_npage = _AC(1, UL) << order;
+   hugetlb_mask = (hugetlb_npage << PAGE_SHIFT) - 1;
+   address = ALIGN_DOWN(address, PAGE_SIZE);
+
+   /*
+* Since we count the page pointed by this address, the number of
+* residual PAGE_SIZE-pages is greater than or equal to 1.
+*/
+   return hugetlb_npage - ((address & hugetlb_mask) >> PAGE_SHIFT);
+}
+
+static unsigned int
+hugetlb_page_get_externally_pinned_num(struct vfio_dma *dma,
+   unsigned long start,
+   unsigned long npage)
+{
+   struct vfio_pfn *vpfn;
+   struct rb_node *node;
+   unsigned long end = start + npage - 1;
+   unsigned int num = 0;
+
+   if (!dma || !npage)
+   return 0;
+
+   /* If we find a page in dma->pfn_list, this page has been pinned 
externally */
+   for (node = rb_first(>pfn_list); node; node = rb_next(node)) {
+   vpfn = rb_entry(node, struct vfio_pfn, node);
+   if ((vpfn->pfn >= start) && (vpfn->pfn <= end))
+   num++;
+   }
+
+   return num;
+}
+
+static long hugetlb_page_vaddr_get_pfn(unsigned long vaddr, long npage,
+   unsigned long pfn)
+{
+   long hugetlb_residual_npage;
+   long contiguous_npage;
+   struct page *head = compound_head(pfn_to_page(pfn));
+
+   /*
+* If pfn is valid,
+* hugetlb_residual_npage is greater than or equal to 1.
+*/
+   hugetlb_residual_npage = hugetlb_get_residual_pages(vaddr,
+   compound_order(head));
+   if 

Re: [PATCH] bootconfig: Fix off-by-one in xbc_node_compose_key_after()

2020-08-13 Thread Andrew Morton
On Thu, 13 Aug 2020 18:30:50 -0400 Steven Rostedt  wrote:

> From: Steven Rostedt (VMware) 
> 
> While reviewing some patches for bootconfig, I noticed the following
> code in xbc_node_compose_key_after():
> 
>   ret = snprintf(buf, size, "%s%s", xbc_node_get_data(node),
>  depth ? "." : "");
>   if (ret < 0)
>   return ret;
>   if (ret > size) {
>   size = 0;
>   } else {
>   size -= ret;
>   buf += ret;
>   }
> 
> But snprintf() returns the number of bytes that would be written, not
> the number of bytes that are written (ignoring the nul terminator).
> This means that if the number of non null bytes written were to equal
> size, then the nul byte, which snprintf() always adds, will overwrite
> that last byte.
> 
>   ret = snprintf(buf, 5, "hello");
>   printf("buf = '%s'\n", buf);
>   printf("ret = %d\n", ret);
> 
> produces:
> 
>   buf = 'hell'
>   ret = 5
> 
> The string was truncated without ret being greater than 5.
> Test (ret >= size) for overwrite.

What are the end-user visible effects of the bug?  IOW, why cc:stable?




Re: [RFC 6/7] KVM: X86: Expose PKS to guest and userspace

2020-08-13 Thread Chenyi Qiang




On 8/14/2020 3:04 AM, Jim Mattson wrote:

On Fri, Aug 7, 2020 at 1:47 AM Chenyi Qiang  wrote:


Existence of PKS is enumerated via CPUID.(EAX=7H,ECX=0):ECX[31]. It is
enabled by setting CR4.PKS when long mode is active. PKS is only
implemented when EPT is enabled and requires the support of VM_{ENTRY,
EXIT}_LOAD_IA32_PKRS currently.

Signed-off-by: Chenyi Qiang 



@@ -967,7 +969,8 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
  {
 unsigned long old_cr4 = kvm_read_cr4(vcpu);
 unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE |
-  X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_PKE;
+  X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_PKE |
+  X86_CR4_PKS;


This list already seems overly long, but I don't think CR4.PKS belongs
here. In volume 3 of the SDM, section 4.4.1, it says:

- If PAE paging would be in use following an execution of MOV to CR0
or MOV to CR4 (see Section 4.1.1) and the instruction is modifying any
of CR0.CD, CR0.NW, CR0.PG, CR4.PAE, CR4.PGE, CR4.PSE, or CR4.SMEP;
then the PDPTEs are loaded from the address in CR3.

CR4.PKS is not in the list of CR4 bits that result in a PDPTE load.
Since it has no effect on PAE paging, I would be surprised if it did
result in a PDPTE load.



Oh, My mistake.


 if (kvm_valid_cr4(vcpu, cr4))
 return 1;
@@ -1202,7 +1205,7 @@ static const u32 msrs_to_save_all[] = {
 MSR_IA32_RTIT_ADDR1_A, MSR_IA32_RTIT_ADDR1_B,
 MSR_IA32_RTIT_ADDR2_A, MSR_IA32_RTIT_ADDR2_B,
 MSR_IA32_RTIT_ADDR3_A, MSR_IA32_RTIT_ADDR3_B,
-   MSR_IA32_UMWAIT_CONTROL,
+   MSR_IA32_UMWAIT_CONTROL, MSR_IA32_PKRS,


Should MSR_IA32_PKRS be added to the switch statement in
kvm_init_msr_list()? Something like...

case MSR_IA32_PKRS:
 if (!kvm_cpu_cap_has(X86_FEATURE_PKRS))
 continue;
 break;



Yes, this should be added.


  1   2   3   4   5   6   7   8   9   10   >