Re: [PATCH v3] dt-binding: leds: Document leds-multi-gpio bindings

2021-03-23 Thread Alexander Dahl
Hello Hermes,

> Hermes Zhang  hat am 24.03.2021 03:48 geschrieben:
> 
>  
> From: Hermes Zhang 
> 
> Document the device tree bindings of the multiple GPIOs LED driver
> Documentation/devicetree/bindings/leds/leds-multi-gpio.yaml.
> 
> Signed-off-by: Hermes Zhang 
> ---
> 
> Notes:
> Add maxItems

What about the other part of the series? I think you should send both patches 
together with an introduction message on both. If you only change one patch for 
a new version spin of the series, just send the other one unchanged.

(It makes no sense to merge the binding as long as the driver is not merged, 
otherwise you would end up with a binding without driver. So keeping them 
together should help reviewers and maintainers.)

Greets
Alex

> 
>  .../bindings/leds/leds-multi-gpio.yaml| 50 +++
>  1 file changed, 50 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/leds/leds-multi-gpio.yaml
> 
> diff --git a/Documentation/devicetree/bindings/leds/leds-multi-gpio.yaml 
> b/Documentation/devicetree/bindings/leds/leds-multi-gpio.yaml
> new file mode 100644
> index ..6f2b47487b90
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/leds/leds-multi-gpio.yaml
> @@ -0,0 +1,50 @@
> +# SPDX-License-Identifier: GPL-2.0
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/leds/leds-multi-gpio.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Multiple GPIOs LED driver
> +
> +maintainers:
> +  - Hermes Zhang 
> +
> +description:
> +  This will support some LED made of multiple GPIOs and the brightness of the
> +  LED could map to different states of the GPIOs.
> +
> +properties:
> +  compatible:
> +const: multi-gpio-led
> +
> +  led-gpios:
> +description: Array of one or more GPIOs pins used to control the LED.
> +minItems: 1
> +maxItems: 8  # Should be enough
> +
> +  led-states:
> +description: |
> +  The array list the supported states here which will map to brightness
> +  from 0 to maximum. Each item in the array will present all the GPIOs
> +  value by bit.
> +$ref: /schemas/types.yaml#/definitions/uint8-array
> +minItems: 1
> +maxItems: 16 # Should be enough
> +
> +required:
> +  - compatible
> +  - led-gpios
> +  - led-states
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +gpios-led {
> +  compatible = "multi-gpio-led";
> +
> +  led-gpios = < 23 0x1>,
> +  < 24 0x1>;
> +  led-states = /bits/ 8 <0x00 0x01 0x02 0x03>;
> +};
> +...
> -- 
> 2.20.1


ERROR: "devm_platform_ioremap_resource" undefined!

2021-03-23 Thread kernel test robot
tree:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 
master
head:   7acac4b3196caee5e21fb5ea53f8bc124e6a16fc
commit: a9c56721d6ae99b22e983d0722e6b1b53a11dd59 dmaengine: dw: platform: Use 
devm_platform_ioremap_resource()
date:   1 year, 7 months ago
config: s390-randconfig-r013-20210324 (attached as .config)
compiler: s390-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
# 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a9c56721d6ae99b22e983d0722e6b1b53a11dd59
git remote add linus 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
git fetch --no-tags linus master
git checkout a9c56721d6ae99b22e983d0722e6b1b53a11dd59
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross 
ARCH=s390 

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

All errors (new ones prefixed by >>):

>> ERROR: "devm_platform_ioremap_resource" [drivers/dma/dw/dw_dmac.ko] 
>> undefined!

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


.config.gz
Description: application/gzip


Re: [PATCH v2 0/7] remove different PHY fixups

2021-03-23 Thread Oleksij Rempel
Hi Shawn,

ping, do this patches need some ACK from some one?

Regards,
Oleksij

On Tue, Mar 09, 2021 at 12:26:08PM +0100, Oleksij Rempel wrote:
> changes v2:
> - rebase against latest kernel
> - fix networking on RIoTBoard
> 
> This patch series tries to remove most of the imx6 and imx7 board
> specific PHY configuration via fixup, as this breaks the PHYs when
> connected to switch chips or USB Ethernet MACs.
> 
> Each patch has the possibility to break boards, but contains a
> recommendation to fix the problem in a more portable and future-proof
> way.
> 
> regards,
> Oleksij
> 
> Oleksij Rempel (7):
>   ARM: imx6q: remove PHY fixup for KSZ9031
>   ARM: imx6q: remove TX clock delay of ar8031_phy_fixup()
>   ARM: imx6q: remove hand crafted PHY power up in ar8035_phy_fixup()
>   ARM: imx6q: remove clk-out fixup for the Atheros AR8031 and AR8035
> PHYs
>   ARM: imx6q: remove Atheros AR8035 SmartEEE fixup
>   ARM: imx6sx: remove Atheros AR8031 PHY fixup
>   ARM: imx7d: remove Atheros AR8031 PHY fixup
> 
>  arch/arm/boot/dts/imx6dl-riotboard.dts  |  2 +
>  arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts |  2 +-
>  arch/arm/mach-imx/mach-imx6q.c  | 85 -
>  arch/arm/mach-imx/mach-imx6sx.c | 26 
>  arch/arm/mach-imx/mach-imx7d.c  | 22 ---
>  5 files changed, 3 insertions(+), 134 deletions(-)
> 
> -- 
> 2.29.2
> 
> 

-- 
Pengutronix e.K.   | |
Steuerwalder Str. 21   | http://www.pengutronix.de/  |
31137 Hildesheim, Germany  | Phone: +49-5121-206917-0|
Amtsgericht Hildesheim, HRA 2686   | Fax:   +49-5121-206917- |


Re: [PATCH 2/3] s390/vdso: fix arch_data access for __arch_get_hw_counter()

2021-03-23 Thread Heiko Carstens
On Tue, Mar 23, 2021 at 10:58:18PM +0100, Heiko Carstens wrote:
> Li Wang reported that clock_gettime(CLOCK_MONOTONIC_RAW, ...) returns
> incorrect values when time is provided via vdso instead of system call:
> 
> vdso_ts_nsec = 4484351380985507, vdso_ts.tv_sec = 4484351, vdso_ts.tv_nsec = 
> 380985507
> sys_ts_nsec  = 1446923235377, sys_ts.tv_sec  = 1446, sys_ts.tv_nsec  = 
> 923235377
> 
> Within the s390 specific vdso function __arch_get_hw_counter() tries
> to read tod clock steering values from the arch_data member of the
> passed in vdso_data structure.
> However only the arch_data member of the first clock source base
> (CS_HRES_COARSE) is initialized. For CS_RAW arch_data is not at all
> initialized, which explains the incorrect returned values.
> 
> It is a bit odd to provide the required tod clock steering parameters
> only within the first element of the _vdso_data array. However for
> time namespaces even no member of the _timens_data array contains the
> required data, which would make fixing __arch_get_hw_counter() quite
> complicated.
> 
> Therefore simply add an s390 specific vdso data page which contains
> the tod clock steering parameters. Everything else seems to be
> unnecessary complex.
> 
> Reported-by: Li Wang 
> Fixes: 1ba2d6c0fd4e ("s390/vdso: simplify __arch_get_hw_counter()")
> Fixes: eeab78b05d20 ("s390/vdso: implement generic vdso time namespace 
> support")
> Link: https://lore.kernel.org/linux-s390/YFnxr1ZlMIOIqjfq@osiris
> Signed-off-by: Heiko Carstens 
> ---
>  arch/s390/Kconfig |  1 -
>  arch/s390/include/asm/vdso.h  |  4 +++-
>  arch/s390/include/asm/vdso/data.h | 13 
>  arch/s390/include/asm/vdso/datapage.h | 17 +++
>  arch/s390/include/asm/vdso/gettimeofday.h | 11 --
>  arch/s390/kernel/time.c   |  6 +++---
>  arch/s390/kernel/vdso.c   | 25 ---
>  arch/s390/kernel/vdso64/vdso64.lds.S  |  3 ++-
>  8 files changed, 56 insertions(+), 24 deletions(-)
>  delete mode 100644 arch/s390/include/asm/vdso/data.h
>  create mode 100644 arch/s390/include/asm/vdso/datapage.h

FWIW, alternatively to this and the third patch we could also do the
much shorter and simpler variant below. What I personally don't like
is that data is duplicated.
But on the other hand it is much shorter, and the more I think of it
this seems to be the way to go.
Opinions?

diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index e37285a5101b..fa095ecf0349 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -80,10 +80,12 @@ void __init time_early_init(void)
 {
struct ptff_qto qto;
struct ptff_qui qui;
+   int i;
 
/* Initialize TOD steering parameters */
tod_steering_end = tod_clock_base.tod;
-   vdso_data->arch_data.tod_steering_end = tod_steering_end;
+   for (i = 0; i < CS_BASES; i++)
+   vdso_data[i].arch_data.tod_steering_end = tod_steering_end;
 
if (!test_facility(28))
return;
@@ -366,6 +368,7 @@ static void clock_sync_global(unsigned long delta)
 {
unsigned long now, adj;
struct ptff_qto qto;
+   int i;
 
/* Fixup the monotonic sched clock. */
tod_clock_base.eitod += delta;
@@ -381,8 +384,10 @@ static void clock_sync_global(unsigned long delta)
panic("TOD clock sync offset %li is too large to drift\n",
  tod_steering_delta);
tod_steering_end = now + (abs(tod_steering_delta) << 15);
-   vdso_data->arch_data.tod_steering_end = tod_steering_end;
-   vdso_data->arch_data.tod_steering_delta = tod_steering_delta;
+   for (i = 0; i < CS_BASES; i++) {
+   vdso_data[i].arch_data.tod_steering_end = tod_steering_end;
+   vdso_data[i].arch_data.tod_steering_delta = tod_steering_delta;
+   }
 
/* Update LPAR offset. */
if (ptff_query(PTFF_QTO) && ptff(, sizeof(qto), PTFF_QTO) == 0)


[PATCH] arc/kernel/signal.c: Fix couple of typos

2021-03-23 Thread Bhaskar Chowdhury


s/unconditonally/unconditionally/
s/gaurantees/guarantees/

Signed-off-by: Bhaskar Chowdhury 
---
 arch/arc/kernel/signal.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arc/kernel/signal.c b/arch/arc/kernel/signal.c
index a78d8f745a67..cf1788fd3812 100644
--- a/arch/arc/kernel/signal.c
+++ b/arch/arc/kernel/signal.c
@@ -259,7 +259,7 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct 
pt_regs *regs)
regs->r2 = (unsigned long)>uc;

/*
-* small optim to avoid unconditonally calling do_sigaltstack
+* small optim to avoid unconditionally calling do_sigaltstack
 * in sigreturn path, now that we only have rt_sigreturn
 */
magic = MAGIC_SIGALTSTK;
@@ -391,7 +391,7 @@ void do_signal(struct pt_regs *regs)
 void do_notify_resume(struct pt_regs *regs)
 {
/*
-* ASM glue gaurantees that this is only called when returning to
+* ASM glue guarantees that this is only called when returning to
 * user mode
 */
if (test_thread_flag(TIF_NOTIFY_RESUME))
--
2.30.1



[PATCH v2 2/3] arm64: dts: imx8mq-evk: add one regulator used to power up pcie phy

2021-03-23 Thread Richard Zhu
Both 1.8v and 3.3v power supplies can be used by i.MX8MQ PCIe PHY.
In default, the PCIE_VPH voltage is suggested to be 1.8v refer to data
sheet. When PCIE_VPH is supplied by 3.3v in the HW schematic design,
the VREG_BYPASS bits of GPR registers should be cleared from default
value 1b'1 to 1b'0. Thus, the internal 3v3 to 1v8 translator would be
turned on.

Signed-off-by: Richard Zhu 
---
 arch/arm64/boot/dts/freescale/imx8mq-evk.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts 
b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
index 85b045253a0e..4d2035e3dd7c 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
@@ -318,6 +318,7 @@
 < IMX8MQ_CLK_PCIE1_PHY>,
 <_refclk>;
clock-names = "pcie", "pcie_aux", "pcie_phy", "pcie_bus";
+   vph-supply = <_reg>;
status = "okay";
 };
 
-- 
2.17.1



[PATCH v2 0/3] add one regulator used to power up pcie phy

2021-03-23 Thread Richard Zhu
Changes:
v1 --> v2:
Suggested by Lucas, don't use the boolean property to specify the
different power supplies to PCIe PHY.
Use one regulator to power up PCIe PHY, and the regulator APIs to
get the voltage of it.

[PATCH v2 1/3] dt-bindings: imx6q-pcie: add one regulator used to
[PATCH v2 2/3] arm64: dts: imx8mq-evk: add one regulator used to
[PATCH v2 3/3] PCI: imx: clear vreg bypass when pcie vph voltage is


[PATCH v2 3/3] PCI: imx: clear vreg bypass when pcie vph voltage is 3v3

2021-03-23 Thread Richard Zhu
Both 1.8v and 3.3v power supplies can be used by i.MX8MQ PCIe PHY.
In default, the PCIE_VPH voltage is suggested to be 1.8v refer to data
sheet. When PCIE_VPH is supplied by 3.3v in the HW schematic design,
the VREG_BYPASS bits of GPR registers should be cleared from default
value 1b'1 to 1b'0. Thus, the internal 3v3 to 1v8 translator would be
turned on.

Signed-off-by: Richard Zhu 
---
 drivers/pci/controller/dwc/pci-imx6.c | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c 
b/drivers/pci/controller/dwc/pci-imx6.c
index 853ea8e82952..beca085a9300 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -37,6 +37,7 @@
 #define IMX8MQ_GPR_PCIE_REF_USE_PADBIT(9)
 #define IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_ENBIT(10)
 #define IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE   BIT(11)
+#define IMX8MQ_GPR_PCIE_VREG_BYPASSBIT(12)
 #define IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPEGENMASK(11, 8)
 #define IMX8MQ_PCIE2_BASE_ADDR 0x33c0
 
@@ -80,6 +81,7 @@ struct imx6_pcie {
u32 tx_swing_full;
u32 tx_swing_low;
struct regulator*vpcie;
+   struct regulator*vph;
void __iomem*phy_base;
 
/* power domain for pcie */
@@ -611,6 +613,8 @@ static void imx6_pcie_configure_type(struct imx6_pcie 
*imx6_pcie)
 
 static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
 {
+   int phy_uv;
+
switch (imx6_pcie->drvdata->variant) {
case IMX8MQ:
/*
@@ -621,6 +625,18 @@ static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
   imx6_pcie_grp_offset(imx6_pcie),
   IMX8MQ_GPR_PCIE_REF_USE_PAD,
   IMX8MQ_GPR_PCIE_REF_USE_PAD);
+   /*
+* Regarding to the datasheet, the PCIE_VPH is suggested
+* to be 1.8V. If the PCIE_VPH is supplied by 3.3V, the
+* VREG_BYPASS should be cleared to zero.
+*/
+   if (imx6_pcie->vph)
+   phy_uv = regulator_get_voltage(imx6_pcie->vph);
+   if (phy_uv > 300)
+   regmap_update_bits(imx6_pcie->iomuxc_gpr,
+  imx6_pcie_grp_offset(imx6_pcie),
+  IMX8MQ_GPR_PCIE_VREG_BYPASS,
+  0);
break;
case IMX7D:
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
@@ -1130,6 +1146,13 @@ static int imx6_pcie_probe(struct platform_device *pdev)
imx6_pcie->vpcie = NULL;
}
 
+   imx6_pcie->vph = devm_regulator_get_optional(>dev, "vph");
+   if (IS_ERR(imx6_pcie->vph)) {
+   if (PTR_ERR(imx6_pcie->vph) != -ENODEV)
+   return PTR_ERR(imx6_pcie->vph);
+   imx6_pcie->vph = NULL;
+   }
+
platform_set_drvdata(pdev, imx6_pcie);
 
ret = imx6_pcie_attach_pd(dev);
-- 
2.17.1



[PATCH v2 1/3] dt-bindings: imx6q-pcie: add one regulator used to power up pcie phy

2021-03-23 Thread Richard Zhu
Both 1.8v and 3.3v power supplies can be used by i.MX8MQ PCIe PHY.
In default, the PCIE_VPH voltage is suggested to be 1.8v refer to data
sheet. When PCIE_VPH is supplied by 3.3v in the HW schematic design,
the VREG_BYPASS bits of GPR registers should be cleared from default
value 1b'1 to 1b'0. Thus, the internal 3v3 to 1v8 translator would be
turned on.

Signed-off-by: Richard Zhu 
---
 Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt 
b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
index de4b2baf91e8..3248b7192ced 100644
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
@@ -38,6 +38,12 @@ Optional properties:
   The regulator will be enabled when initializing the PCIe host and
   disabled either as part of the init process or when shutting down the
   host.
+- vph-supply: Should specify the regulator in charge of PCIe PHY power.
+  On i.MX8MQ, both 1.8v and 3.3v power supplies can be used by i.MX8MQ PCIe
+  PHY. In default, the PCIE_VPH voltage is suggested to be 1.8v refer to data
+  sheet. When PCIE_VPH is supplied by 3.3v in the HW schematic design, the
+  VREG_BYPASS bits of GPR registers should be cleared from default value 1b'1
+  to 1b'0.
 
 Additional required properties for imx6sx-pcie:
 - clock names: Must include the following additional entries:
-- 
2.17.1



Re: [PATCH 02/10] ARM: disable CONFIG_IDE in footbridge_defconfig

2021-03-23 Thread Cye Borg
Sure, here it is:
snow / # lspci -vxxx -s 7.0
00:07.0 ISA bridge: Contaq Microsystems 82c693
Flags: bus master, medium devsel, latency 0
Kernel modules: pata_cypress
00: 80 10 93 c6 47 00 80 02 00 00 01 06 00 00 80 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
40: 03 02 00 00 26 60 00 01 f0 60 00 80 80 71 00 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Best regards,
Barnabas

ps.: let me know, if anything else I can do.

On Tue, Mar 23, 2021 at 7:43 PM Russell King - ARM Linux admin
 wrote:
>
> On Mon, Mar 22, 2021 at 06:10:01PM +0100, Cye Borg wrote:
> > PWS 500au:
> >
> > snow / # lspci -vvx -s 7.1
> > 00:07.1 IDE interface: Contaq Microsystems 82c693 (prog-if 80 [ISA
> > Compatibility mode-only controller, supports bus mastering])
> > Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop-
> > ParErr+ Stepping- SERR- FastB2B- DisINTx-
> > Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium
> > >TAbort- SERR-  > Latency: 0
> > Interrupt: pin A routed to IRQ 0
> > Region 0: I/O ports at 01f0 [size=8]
> > Region 1: I/O ports at 03f4
> > Region 4: I/O ports at 9080 [size=16]
> > Kernel driver in use: pata_cypress
> > Kernel modules: pata_cypress
> > 00: 80 10 93 c6 45 00 80 02 00 80 01 01 00 00 80 00
> > 10: f1 01 00 00 f5 03 00 00 00 00 00 00 00 00 00 00
> > 20: 81 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00
> >
> > snow / # lspci -vvx -s 7.2
> > 00:07.2 IDE interface: Contaq Microsystems 82c693 (prog-if 00 [ISA
> > Compatibility mode-only controller])
> > Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop-
> > ParErr+ Stepping- SERR- FastB2B- DisINTx-
> > Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium
> > >TAbort- SERR-  > Latency: 0
> > Interrupt: pin B routed to IRQ 0
> > Region 0: I/O ports at 0170 [size=8]
> > Region 1: I/O ports at 0374
> > Region 4: Memory at 0c24 (32-bit, non-prefetchable)
> > [disabled] [size=64K]
> > Kernel modules: pata_cypress
> > 00: 80 10 93 c6 45 00 80 02 00 00 01 01 00 00 80 00
> > 10: 71 01 00 00 75 03 00 00 00 00 00 00 00 00 00 00
> > 20: 00 00 24 0c 00 00 00 00 00 00 00 00 00 00 00 00
> > 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00
>
> Thanks very much.
>
> Could I also ask for the output of:
>
> # lspci -vxxx -s 7.0
>
> as well please - this will dump all 256 bytes for the ISA bridge, which
> contains a bunch of configuration registers. Thanks.
>
> --
> RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
> FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


[PATCH] drivers:staging: Simplify the if condition

2021-03-23 Thread caizhichao
From: Zhichao Cai 

Fixes coccicheck warning:
drivers/staging/media/atomisp/pci/sh_css_params.c:4652:24-26: WARNING !A || A 
&& B is equivalent to !A || B

Signed-off-by: Zhichao Cai 
---
 drivers/staging/media/atomisp/pci/sh_css_params.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/sh_css_params.c 
b/drivers/staging/media/atomisp/pci/sh_css_params.c
index 9fad28b..7467256 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_params.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_params.c
@@ -4649,10 +4649,8 @@ struct ia_css_dvs_6axis_config *
params = stream->isp_params_configs;
 
/* Backward compatibility by default consider pipe as Video*/
-   if (!params || (params &&
-   !params->pipe_dvs_6axis_config[IA_CSS_PIPE_ID_VIDEO])) {
+   if (!params || !params->pipe_dvs_6axis_config[IA_CSS_PIPE_ID_VIDEO])
goto err;
-   }
 
dvs_config = kvcalloc(1, sizeof(struct ia_css_dvs_6axis_config),
  GFP_KERNEL);
-- 
1.9.1



[PATCH] treewide: remove editor modelines and cruft

2021-03-23 Thread Masahiro Yamada
The section "19) Editor modelines and other cruft" in
Documentation/process/coding-style.rst clearly says,
"Do not include any of these in source files."

I recently receive a patch to explicitly add a new one.

Let's do treewide cleanups, otherwise some people follow the existing
code and attempt to upstream their favoriate editor setups.

It is even nicer if scripts/checkpatch.pl can check it.

If we like to impose coding style in an editor-independent manner,
I think editorconfig (patch [1]) is a saner solution.

[1] https://lore.kernel.org/lkml/20200703073143.423557-1-da...@kdrag0n.dev/

Signed-off-by: Masahiro Yamada 
---

You might wonder if I worked on this huge patch manually or generated it by
a tool. I wrote a Python script to generate this patch, but not from a scratch.
I contributed a similar tool to U-Boot some years ago.
(https://github.com/u-boot/u-boot/commit/8ba1f5de4571566be12efaffdad404a506b978e3)
I reused and modified it.

For completeness, this is the code I wrote (ugly since this is not intended for 
upstream)


#!/usr/bin/env python3

import copy
import os
import re
import sys

pattern_local_variables = re.compile(r'Local (V|v)ariables')
pattern_end = re.compile(r'End:')
pattern_blank = re.compile(r'^\s*$')#  empty line
pattern_comment_begin = re.compile(r'^(\s*)/\*')
pattern_comment_end = re.compile(r'\*/$')
pattern_comment_null = re.compile(r' \*$')
pattern_dash = re.compile(r'---')

def extend_matched_lines(lines, matched, pre_patterns, post_patterns, 
extend_pre,
 extend_post):
extended_matched = []

j = matched[0]

for i in matched:
if i == 0 or i < j:
continue
j = i
while j in matched:
j += 1
if j >= len(lines):
break

for p in pre_patterns:
if p.search(lines[i - 1]):
break
else:
# not matched
continue

for p in post_patterns:
if p.search(lines[j]):
break
else:
# not matched
continue

if extend_pre:
extended_matched.append(i - 1)
if extend_post:
extended_matched.append(j)

matched += extended_matched
matched.sort()


def cleanup_one_file(filepath, patterns):

#print(filepath)
with open(filepath) as f:
lines = f.readlines()

matched = []
for i, line in enumerate(lines):
if i - 1 in matched and lines[i - 1][-2:] == '\\\n':
matched.append(i)
continue
for pattern in patterns:
if pattern.search(line):
#print("hit {}".format(line), end='')
m = pattern_comment_begin.match(line)
if m and not pattern_comment_end.search(line):
#print("replace {}".format(line), end='')
lines[i] = m.group(1) + '/*\n'
if i + 1 < len(lines) and 
pattern_comment_end.search(lines[i + 1]):
matched.append(i)
matched.append(i + 1)
else:
matched.append(i)
break

if not matched:
return

while True:
old_matched = copy.copy(matched)
extend_matched_lines(lines, matched, [pattern_local_variables],
 [pattern_end], True, True)

extend_matched_lines(lines, matched, [pattern_comment_begin],
 [pattern_comment_end], True, True)
extend_matched_lines(lines, matched, [pattern_blank, pattern_dash],
 [pattern_comment_end], True, False)
extend_matched_lines(lines, matched, [pattern_comment_begin, 
pattern_comment_null],
 [pattern_comment_null], False, True)
extend_matched_lines(lines, matched, [pattern_blank],
 [pattern_blank], False, True)
if matched == old_matched:
break

# remove blank lines at the end of file
if matched and matched[-1] == len(lines) -1:
i = matched[-1] - 1
while i >= 0 and (i in matched or pattern_blank.search(lines[i])):
matched.append(i)
i -= 1
matched.sort()

with open(filepath, 'w') as f:
for i, line in enumerate(lines):
if i not in matched:
f.write(line)

def main():

cwd = os.getcwd()

if len(sys.argv) > 1:
topdir = os.path.join(cwd, sys.argv[1])
else:
topdir = cwd

exclude_dirs = [ os.path.join(cwd, d) for d in ('.git', 'Documentation') ]

# patterns to remove
strings = ('c-indent-level:', 'tab-width:',
   'vim:', 'version-control:', 'c-basic-offset:',
   'indent-tabs-mode:', 'c-file-style:', 'fill-column:', 
'kept-new-versions:',
   'ispell-local-dictionary', r'mode: (C|c)$', 'Emacs about 
preferred coding style',
   

Re: [PATCH v5] mm: cma: support sysfs

2021-03-23 Thread Minchan Kim
On Wed, Mar 24, 2021 at 04:34:34AM +, Matthew Wilcox wrote:
> On Tue, Mar 23, 2021 at 08:31:31PM -0700, Minchan Kim wrote:
> > On Wed, Mar 24, 2021 at 03:02:24AM +, Matthew Wilcox wrote:
> > > On Tue, Mar 23, 2021 at 12:50:50PM -0700, Minchan Kim wrote:
> > > > +   /* the number of CMA page successful allocations */
> > > > +   atomic64_t nr_pages_succeeded;
> > > 
> > > > +void cma_sysfs_alloc_pages_count(struct cma *cma, size_t count)
> > > > +{
> > > > +   atomic64_add(count, >nr_pages_succeeded);
> > > > +}
> > > 
> > > I don't understand.  A size_t is a byte count.  But the variable is called
> > > 'nr_pages'.  So which is it, a byte count or a page count?
> > 
> > It's page count. I followed the cma_alloc interface since it has
> > size_t count variable for nr_pages.
> 
> That's very confusing.  cma_alloc is wrong; if it needs to be an
> unsigned long, that's fine.  But it shouldn't be size_t.
> 
> 7.17 of n1256 defines:
> 
>   size_t
> which is the unsigned integer type of the result of the sizeof operator
> 
> Do you want to submit a patch to fix cma_alloc as well?

Sure, but it will be separate patch.

> 
> > Let's go with unsigned long nr_pages:
> > void cma_sysfs_alloc_pages_count(struct cma *cma, unsigned long
> > nr_pages)
> 
> Works for me!

Thanks for review!


Re: [PATCH v6] mm: cma: support sysfs

2021-03-23 Thread Minchan Kim
On Tue, Mar 23, 2021 at 09:47:27PM -0700, John Hubbard wrote:
> On 3/23/21 8:27 PM, Minchan Kim wrote:
> ...
> > > > +static int __init cma_sysfs_init(void)
> > > > +{
> > > > +   unsigned int i;
> > > > +
> > > > +   cma_kobj_root = kobject_create_and_add("cma", mm_kobj);
> > > > +   if (!cma_kobj_root)
> > > > +   return -ENOMEM;
> > > > +
> > > > +   for (i = 0; i < cma_area_count; i++) {
> > > > +   int err;
> > > > +   struct cma *cma;
> > > > +   struct cma_kobject *cma_kobj;
> > > > +
> > > > +   cma_kobj = kzalloc(sizeof(*cma_kobj), GFP_KERNEL);
> > > > +   if (!cma_kobj) {
> > > > +   kobject_put(cma_kobj_root);
> > > > +   return -ENOMEM;
> > > 
> > > This leaks little cma_kobj's all over the floor. :)
> > 
> > I thought kobject_put(cma_kobj_root) should deal with it. No?
> > 
> If this fails when i > 0, there will be cma_kobj instances that
> were stashed in the cma_areas[] array. But this code only deletes
> the most recently allocated cma_kobj, not anything allocated on
> previous iterations of the loop.

Oh, I misunderstood that destroying of root kobject will release
children recursively. Seems not true. Go back to old version.


index 16c81c9cb9b7..418951a3f138 100644
--- a/mm/cma_sysfs.c
+++ b/mm/cma_sysfs.c
@@ -80,20 +80,19 @@ static struct kobj_type cma_ktype = {
 static int __init cma_sysfs_init(void)
 {
unsigned int i;
+   int err;
+   struct cma *cma;
+   struct cma_kobject *cma_kobj;

cma_kobj_root = kobject_create_and_add("cma", mm_kobj);
if (!cma_kobj_root)
return -ENOMEM;

for (i = 0; i < cma_area_count; i++) {
-   int err;
-   struct cma *cma;
-   struct cma_kobject *cma_kobj;
-
cma_kobj = kzalloc(sizeof(*cma_kobj), GFP_KERNEL);
if (!cma_kobj) {
-   kobject_put(cma_kobj_root);
-   return -ENOMEM;
+   err = -ENOMEM;
+   goto out;
}

cma = _areas[i];
@@ -103,11 +102,21 @@ static int __init cma_sysfs_init(void)
   cma_kobj_root, "%s", cma->name);
if (err) {
kobject_put(_kobj->kobj);
-   kobject_put(cma_kobj_root);
-   return err;
+   goto out;
}
}

return 0;
+out:
+   while (--i >= 0) {
+   cma = _areas[i];
+
+   kobject_put(>kobj->kobj);
+   kfree(cma->kobj);
+   cma->kobj = NULL;
+   }
+   kobject_put(cma_kobj_root);
+
+   return err;
 }
 subsys_initcall(cma_sysfs_init);





Re: [PATCH v4 RESEND 3/5] perf/x86/lbr: Move cpuc->lbr_xsave allocation out of sleeping region

2021-03-23 Thread Like Xu

On 2021/3/24 12:04, Namhyung Kim wrote:

On Wed, Mar 24, 2021 at 12:47 PM Like Xu  wrote:


Hi Namhyung,

On 2021/3/24 9:32, Namhyung Kim wrote:

Hello,

On Mon, Mar 22, 2021 at 3:14 PM Like Xu  wrote:

+void reserve_lbr_buffers(struct perf_event *event)
+{
+   struct kmem_cache *kmem_cache = x86_get_pmu()->task_ctx_cache;
+   struct cpu_hw_events *cpuc;
+   int cpu;
+
+   if (!static_cpu_has(X86_FEATURE_ARCH_LBR))
+   return;
+
+   for_each_possible_cpu(cpu) {
+   cpuc = per_cpu_ptr(_hw_events, cpu);
+   if (kmem_cache && !cpuc->lbr_xsave && !event->attr.precise_ip)
+   cpuc->lbr_xsave = kmem_cache_alloc(kmem_cache, 
GFP_KERNEL);
+   }
+}


I think we should use kmem_cache_alloc_node().


"kmem_cache_alloc_node - Allocate an object on the specified node"

The reserve_lbr_buffers() is called in __x86_pmu_event_init().
When the LBR perf_event is scheduled to another node, it seems
that we will not call init() and allocate again.

Do you mean use kmem_cache_alloc_node() for each numa_nodes_parsed ?


I assume cpuc->lbr_xsave will be accessed for that cpu only.
Then it needs to allocate it in the node that cpu belongs to.
Something like below..

 cpuc->lbr_xsave = kmem_cache_alloc_node(kmem_cache, GFP_KERNEL,
cpu_to_node(cpu));


Thanks, it helps and I will apply it in the next version.



Thanks,
Namhyung





[PATCH] media: venus : hfi: add venus image info into smem

2021-03-23 Thread Dikshita Agarwal
fill fw version info into smem to be printed as part of
soc info.

Signed-off-by: Dikshita Agarwal 
---
 drivers/media/platform/qcom/venus/hfi_msgs.c | 36 ++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.c 
b/drivers/media/platform/qcom/venus/hfi_msgs.c
index 06a1908..0e94921 100644
--- a/drivers/media/platform/qcom/venus/hfi_msgs.c
+++ b/drivers/media/platform/qcom/venus/hfi_msgs.c
@@ -6,6 +6,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "core.h"
@@ -14,6 +15,8 @@
 #include "hfi_msgs.h"
 #include "hfi_parser.h"
 
+#define SMEM_IMAGE_VERSION_TABLE 469
+
 static void event_seq_changed(struct venus_core *core, struct venus_inst *inst,
  struct hfi_msg_event_notify_pkt *pkt)
 {
@@ -239,15 +242,44 @@ static void
 sys_get_prop_image_version(struct device *dev,
   struct hfi_msg_sys_property_info_pkt *pkt)
 {
+   u32 i = 0;
+   size_t smem_block_size = 0;
+   u8 *smem_table_ptr;
+   char version[256];
+   const u32 version_string_size = 128;
+   const u32 smem_image_index_venus = 14 * 128;
+   u8 *str_image_version;
int req_bytes;
 
req_bytes = pkt->hdr.size - sizeof(*pkt);
 
-   if (req_bytes < 128 || !pkt->data[1] || pkt->num_properties > 1)
+   if (req_bytes < version_string_size || !pkt->data[1] || 
pkt->num_properties > 1)
/* bad packet */
return;
 
-   dev_dbg(dev, VDBGL "F/W version: %s\n", (u8 *)>data[1]);
+   str_image_version = (u8 *)>data[1];
+
+   /*
+* The version string returned by firmware includes null
+* characters at the start and in between. Replace the null
+* characters with space, to print the version info.
+*/
+   for (i = 0; i < version_string_size; i++) {
+   if (str_image_version[i] != '\0')
+   version[i] = str_image_version[i];
+   else
+   version[i] = ' ';
+   }
+
+   version[i] = '\0';
+   dev_dbg(dev, VDBGL "F/W version: %s\n", version);
+
+   smem_table_ptr = qcom_smem_get(QCOM_SMEM_HOST_ANY,
+  SMEM_IMAGE_VERSION_TABLE, 
_block_size);
+   if ((smem_image_index_venus + version_string_size) <= smem_block_size &&
+   smem_table_ptr)
+   memcpy(smem_table_ptr + smem_image_index_venus,
+  str_image_version, version_string_size);
 }
 
 static void hfi_sys_property_info(struct venus_core *core,
-- 
2.7.4



[PATCH v2] locking/mutex: Remove repeated declaration

2021-03-23 Thread Shaokun Zhang
Commit 0cd39f4600ed ("locking/seqlock, headers: Untangle the spaghetti monster")
introduces 'struct ww_acquire_ctx' again, remove the repeated declaration and 
move
the pre-declarations to the top.

Cc: Peter Zijlstra 
Cc: Ingo Molnar 
Cc: Will Deacon 
Cc: Waiman Long 
Cc: Boqun Feng 
Acked-by: Waiman Long 
Signed-off-by: Shaokun Zhang 
---
 include/linux/mutex.h | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/include/linux/mutex.h b/include/linux/mutex.h
index 0cd631a19727..e7a126796937 100644
--- a/include/linux/mutex.h
+++ b/include/linux/mutex.h
@@ -20,6 +20,7 @@
 #include 
 #include 
 
+struct ww_class;
 struct ww_acquire_ctx;
 
 /*
@@ -65,9 +66,6 @@ struct mutex {
 #endif
 };
 
-struct ww_class;
-struct ww_acquire_ctx;
-
 struct ww_mutex {
struct mutex base;
struct ww_acquire_ctx *ctx;
-- 
2.7.4



[PATCH V4 XRT Alveo 20/20] fpga: xrt: Kconfig and Makefile updates for XRT drivers

2021-03-23 Thread Lizhi Hou
Update fpga Kconfig/Makefile and add Kconfig/Makefile for new drivers.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 MAINTAINERS| 11 +++
 drivers/Makefile   |  1 +
 drivers/fpga/Kconfig   |  2 ++
 drivers/fpga/Makefile  |  5 +
 drivers/fpga/xrt/Kconfig   |  8 
 drivers/fpga/xrt/lib/Kconfig   | 17 +
 drivers/fpga/xrt/lib/Makefile  | 30 ++
 drivers/fpga/xrt/metadata/Kconfig  | 12 
 drivers/fpga/xrt/metadata/Makefile | 16 
 drivers/fpga/xrt/mgmt/Kconfig  | 15 +++
 drivers/fpga/xrt/mgmt/Makefile | 19 +++
 11 files changed, 136 insertions(+)
 create mode 100644 drivers/fpga/xrt/Kconfig
 create mode 100644 drivers/fpga/xrt/lib/Kconfig
 create mode 100644 drivers/fpga/xrt/lib/Makefile
 create mode 100644 drivers/fpga/xrt/metadata/Kconfig
 create mode 100644 drivers/fpga/xrt/metadata/Makefile
 create mode 100644 drivers/fpga/xrt/mgmt/Kconfig
 create mode 100644 drivers/fpga/xrt/mgmt/Makefile

diff --git a/MAINTAINERS b/MAINTAINERS
index aa84121c5611..44ccc52987ac 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7009,6 +7009,17 @@ F:   Documentation/fpga/
 F: drivers/fpga/
 F: include/linux/fpga/
 
+FPGA XRT DRIVERS
+M: Lizhi Hou 
+R: Max Zhen 
+R: Sonal Santan 
+L: linux-f...@vger.kernel.org
+S: Maintained
+W: https://github.com/Xilinx/XRT
+F: Documentation/fpga/xrt.rst
+F: drivers/fpga/xrt/
+F: include/uapi/linux/xrt/
+
 FPU EMULATOR
 M: Bill Metzenthen 
 S: Maintained
diff --git a/drivers/Makefile b/drivers/Makefile
index 6fba7daba591..dbb3b727fc7a 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -179,6 +179,7 @@ obj-$(CONFIG_STM)   += hwtracing/stm/
 obj-$(CONFIG_ANDROID)  += android/
 obj-$(CONFIG_NVMEM)+= nvmem/
 obj-$(CONFIG_FPGA) += fpga/
+obj-$(CONFIG_FPGA_XRT_METADATA) += fpga/
 obj-$(CONFIG_FSI)  += fsi/
 obj-$(CONFIG_TEE)  += tee/
 obj-$(CONFIG_MULTIPLEXER)  += mux/
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index 5ff9438b7b46..01410ff000b9 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -227,4 +227,6 @@ config FPGA_MGR_ZYNQMP_FPGA
  to configure the programmable logic(PL) through PS
  on ZynqMP SoC.
 
+source "drivers/fpga/xrt/Kconfig"
+
 endif # FPGA
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 18dc9885883a..4b887bf95cb3 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -48,3 +48,8 @@ obj-$(CONFIG_FPGA_DFL_NIOS_INTEL_PAC_N3000)   += 
dfl-n3000-nios.o
 
 # Drivers for FPGAs which implement DFL
 obj-$(CONFIG_FPGA_DFL_PCI) += dfl-pci.o
+
+# XRT drivers for Alveo
+obj-$(CONFIG_FPGA_XRT_METADATA)+= xrt/metadata/
+obj-$(CONFIG_FPGA_XRT_LIB) += xrt/lib/
+obj-$(CONFIG_FPGA_XRT_XMGMT)   += xrt/mgmt/
diff --git a/drivers/fpga/xrt/Kconfig b/drivers/fpga/xrt/Kconfig
new file mode 100644
index ..0e2c59589ddd
--- /dev/null
+++ b/drivers/fpga/xrt/Kconfig
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Xilinx Alveo FPGA device configuration
+#
+
+source "drivers/fpga/xrt/metadata/Kconfig"
+source "drivers/fpga/xrt/lib/Kconfig"
+source "drivers/fpga/xrt/mgmt/Kconfig"
diff --git a/drivers/fpga/xrt/lib/Kconfig b/drivers/fpga/xrt/lib/Kconfig
new file mode 100644
index ..935369fad570
--- /dev/null
+++ b/drivers/fpga/xrt/lib/Kconfig
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# XRT Alveo FPGA device configuration
+#
+
+config FPGA_XRT_LIB
+   tristate "XRT Alveo Driver Library"
+   depends on HWMON && PCI && HAS_IOMEM
+   select FPGA_XRT_METADATA
+   select REGMAP_MMIO
+   help
+ Select this option to enable Xilinx XRT Alveo driver library. This
+ library is core infrastructure of XRT Alveo FPGA drivers which
+ provides functions for working with device nodes, iteration and
+ lookup of platform devices, common interfaces for platform devices,
+ plumbing of function call and ioctls between platform devices and
+ parent partitions.
diff --git a/drivers/fpga/xrt/lib/Makefile b/drivers/fpga/xrt/lib/Makefile
new file mode 100644
index ..58563416efbf
--- /dev/null
+++ b/drivers/fpga/xrt/lib/Makefile
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2020-2021 Xilinx, Inc. All rights reserved.
+#
+# Authors: sonal.san...@xilinx.com
+#
+
+FULL_XRT_PATH=$(srctree)/$(src)/..
+FULL_DTC_PATH=$(srctree)/scripts/dtc/libfdt
+
+obj-$(CONFIG_FPGA_XRT_LIB) += xrt-lib.o
+
+xrt-lib-objs :=\
+   lib-drv.o   \
+   xroot.o \
+   xclbin.o\
+   subdev.o\
+   cdev.o  \
+   

[PATCH V4 XRT Alveo 18/20] fpga: xrt: DDR calibration platform driver

2021-03-23 Thread Lizhi Hou
Add DDR calibration driver. DDR calibration is a hardware function
discovered by walking firmware metadata. A platform device node will
be created for it. Hardware provides DDR calibration status through
this function.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 .../fpga/xrt/include/xleaf/ddr_calibration.h  |  28 +++
 drivers/fpga/xrt/lib/xleaf/ddr_calibration.c  | 226 ++
 2 files changed, 254 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xleaf/ddr_calibration.h
 create mode 100644 drivers/fpga/xrt/lib/xleaf/ddr_calibration.c

diff --git a/drivers/fpga/xrt/include/xleaf/ddr_calibration.h 
b/drivers/fpga/xrt/include/xleaf/ddr_calibration.h
new file mode 100644
index ..878740c26ca2
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/ddr_calibration.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#ifndef _XRT_DDR_CALIBRATION_H_
+#define _XRT_DDR_CALIBRATION_H_
+
+#include "xleaf.h"
+#include 
+
+/*
+ * Memory calibration driver leaf calls.
+ */
+enum xrt_calib_results {
+   XRT_CALIB_UNKNOWN = 0,
+   XRT_CALIB_SUCCEEDED,
+   XRT_CALIB_FAILED,
+};
+
+enum xrt_calib_leaf_cmd {
+   XRT_CALIB_RESULT = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+};
+
+#endif /* _XRT_DDR_CALIBRATION_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/ddr_calibration.c 
b/drivers/fpga/xrt/lib/xleaf/ddr_calibration.c
new file mode 100644
index ..5a9fa82946cb
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/ddr_calibration.c
@@ -0,0 +1,226 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA memory calibration driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * memory calibration
+ *
+ * Authors:
+ *  Lizhi Hou
+ */
+#include 
+#include 
+#include "xclbin-helper.h"
+#include "metadata.h"
+#include "xleaf/ddr_calibration.h"
+
+#define XRT_CALIB  "xrt_calib"
+
+#define XRT_CALIB_STATUS_REG   0
+#define XRT_CALIB_READ_RETRIES 20
+#define XRT_CALIB_READ_INTERVAL500 /* ms */
+
+static const struct regmap_config calib_regmap_config = {
+   .reg_bits = 32,
+   .val_bits = 32,
+   .reg_stride = 4,
+   .max_register = 0x1000,
+};
+
+struct calib_cache {
+   struct list_headlink;
+   const char  *ep_name;
+   char*data;
+   u32 data_size;
+};
+
+struct calib {
+   struct platform_device  *pdev;
+   struct regmap   *regmap;
+   struct mutexlock; /* calibration dev lock */
+   struct list_headcache_list;
+   u32 cache_num;
+   enum xrt_calib_results  result;
+};
+
+static void __calib_cache_clean_nolock(struct calib *calib)
+{
+   struct calib_cache *cache, *temp;
+
+   list_for_each_entry_safe(cache, temp, >cache_list, link) {
+   vfree(cache->data);
+   list_del(>link);
+   vfree(cache);
+   }
+   calib->cache_num = 0;
+}
+
+static void calib_cache_clean(struct calib *calib)
+{
+   mutex_lock(>lock);
+   __calib_cache_clean_nolock(calib);
+   mutex_unlock(>lock);
+}
+
+static int calib_calibration(struct calib *calib)
+{
+   u32 times = XRT_CALIB_READ_RETRIES;
+   u32 status;
+   int ret;
+
+   while (times != 0) {
+   ret = regmap_read(calib->regmap, XRT_CALIB_STATUS_REG, );
+   if (ret) {
+   xrt_err(calib->pdev, "failed to read status reg %d", 
ret);
+   return ret;
+   }
+
+   if (status & BIT(0))
+   break;
+   msleep(XRT_CALIB_READ_INTERVAL);
+   times--;
+   }
+
+   if (!times) {
+   xrt_err(calib->pdev,
+   "MIG calibration timeout after bitstream download");
+   return -ETIMEDOUT;
+   }
+
+   xrt_info(calib->pdev, "took %dms", (XRT_CALIB_READ_RETRIES - times) *
+XRT_CALIB_READ_INTERVAL);
+   return 0;
+}
+
+static void xrt_calib_event_cb(struct platform_device *pdev, void *arg)
+{
+   struct calib *calib = platform_get_drvdata(pdev);
+   struct xrt_event *evt = (struct xrt_event *)arg;
+   enum xrt_events e = evt->xe_evt;
+   enum xrt_subdev_id id;
+   int ret;
+
+   id = evt->xe_subdev.xevt_subdev_id;
+
+   switch (e) {
+   case XRT_EVENT_POST_CREATION:
+   if (id == XRT_SUBDEV_UCS) {
+   ret = calib_calibration(calib);
+   if (ret)
+   calib->result = XRT_CALIB_FAILED;
+   else
+   calib->result = XRT_CALIB_SUCCEEDED;
+   }
+   break;
+   default:
+   xrt_dbg(pdev, "ignored event %d", e);
+   break;
+   }

[PATCH V4 XRT Alveo 17/20] fpga: xrt: clock frequency counter platform driver

2021-03-23 Thread Lizhi Hou
Add clock frequency counter driver. Clock frequency counter is
a hardware function discovered by walking xclbin metadata. A platform
device node will be created for it. Other part of driver can read the
actual clock frequency through clock frequency counter driver.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xleaf/clkfreq.h |  21 ++
 drivers/fpga/xrt/lib/xleaf/clkfreq.c | 240 +++
 2 files changed, 261 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xleaf/clkfreq.h
 create mode 100644 drivers/fpga/xrt/lib/xleaf/clkfreq.c

diff --git a/drivers/fpga/xrt/include/xleaf/clkfreq.h 
b/drivers/fpga/xrt/include/xleaf/clkfreq.h
new file mode 100644
index ..005441d5df78
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/clkfreq.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Lizhi Hou 
+ */
+
+#ifndef _XRT_CLKFREQ_H_
+#define _XRT_CLKFREQ_H_
+
+#include "xleaf.h"
+
+/*
+ * CLKFREQ driver leaf calls.
+ */
+enum xrt_clkfreq_leaf_cmd {
+   XRT_CLKFREQ_READ = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+};
+
+#endif /* _XRT_CLKFREQ_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/clkfreq.c 
b/drivers/fpga/xrt/lib/xleaf/clkfreq.c
new file mode 100644
index ..49473adde3fd
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/clkfreq.c
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA Clock Frequency Counter Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *  Lizhi Hou
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/clkfreq.h"
+
+#define CLKFREQ_ERR(clkfreq, fmt, arg...)   \
+   xrt_err((clkfreq)->pdev, fmt "\n", ##arg)
+#define CLKFREQ_WARN(clkfreq, fmt, arg...)  \
+   xrt_warn((clkfreq)->pdev, fmt "\n", ##arg)
+#define CLKFREQ_INFO(clkfreq, fmt, arg...)  \
+   xrt_info((clkfreq)->pdev, fmt "\n", ##arg)
+#define CLKFREQ_DBG(clkfreq, fmt, arg...)   \
+   xrt_dbg((clkfreq)->pdev, fmt "\n", ##arg)
+
+#define XRT_CLKFREQ"xrt_clkfreq"
+
+#define XRT_CLKFREQ_CONTROL_STATUS_MASK0x
+
+#define XRT_CLKFREQ_CONTROL_START  0x1
+#define XRT_CLKFREQ_CONTROL_DONE   0x2
+#define XRT_CLKFREQ_V5_CLK0_ENABLED0x1
+
+#define XRT_CLKFREQ_CONTROL_REG0
+#define XRT_CLKFREQ_COUNT_REG  0x8
+#define XRT_CLKFREQ_V5_COUNT_REG   0x10
+
+#define XRT_CLKFREQ_READ_RETRIES   10
+
+static const struct regmap_config clkfreq_regmap_config = {
+   .reg_bits = 32,
+   .val_bits = 32,
+   .reg_stride = 4,
+   .max_register = 0x1000,
+};
+
+struct clkfreq {
+   struct platform_device  *pdev;
+   struct regmap   *regmap;
+   const char  *clkfreq_ep_name;
+   struct mutexclkfreq_lock; /* clock counter dev lock */
+};
+
+static int clkfreq_read(struct clkfreq *clkfreq, u32 *freq)
+{
+   int times = XRT_CLKFREQ_READ_RETRIES;
+   u32 status;
+   int ret;
+
+   *freq = 0;
+   mutex_lock(>clkfreq_lock);
+   ret = regmap_write(clkfreq->regmap, XRT_CLKFREQ_CONTROL_REG, 
XRT_CLKFREQ_CONTROL_START);
+   if (ret) {
+   CLKFREQ_INFO(clkfreq, "write start to control reg failed %d", 
ret);
+   goto failed;
+   }
+   while (times != 0) {
+   ret = regmap_read(clkfreq->regmap, XRT_CLKFREQ_CONTROL_REG, 
);
+   if (ret) {
+   CLKFREQ_INFO(clkfreq, "read control reg failed %d", 
ret);
+   goto failed;
+   }
+   if ((status & XRT_CLKFREQ_CONTROL_STATUS_MASK) == 
XRT_CLKFREQ_CONTROL_DONE)
+   break;
+   mdelay(1);
+   times--;
+   };
+
+   if (!times) {
+   ret = -ETIMEDOUT;
+   goto failed;
+   }
+
+   if (status & XRT_CLKFREQ_V5_CLK0_ENABLED)
+   ret = regmap_read(clkfreq->regmap, XRT_CLKFREQ_V5_COUNT_REG, 
freq);
+   else
+   ret = regmap_read(clkfreq->regmap, XRT_CLKFREQ_COUNT_REG, freq);
+   if (ret) {
+   CLKFREQ_INFO(clkfreq, "read count failed %d", ret);
+   goto failed;
+   }
+
+   mutex_unlock(>clkfreq_lock);
+
+   return 0;
+
+failed:
+   mutex_unlock(>clkfreq_lock);
+
+   return ret;
+}
+
+static ssize_t freq_show(struct device *dev, struct device_attribute *attr, 
char *buf)
+{
+   struct clkfreq *clkfreq = platform_get_drvdata(to_platform_device(dev));
+   ssize_t count;
+   u32 freq;
+
+   if (clkfreq_read(clkfreq, ))
+   return -EINVAL;
+
+   count = snprintf(buf, 64, "%u\n", freq);
+
+   return count;
+}
+static DEVICE_ATTR_RO(freq);
+
+static struct attribute *clkfreq_attrs[] = {
+   _attr_freq.attr,
+   NULL,
+};
+

[PATCH V4 XRT Alveo 19/20] fpga: xrt: partition isolation platform driver

2021-03-23 Thread Lizhi Hou
Add partition isolation platform driver. partition isolation is
a hardware function discovered by walking firmware metadata.
A platform device node will be created for it. Partition isolation
function isolate the different fpga regions

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xleaf/axigate.h |  23 ++
 drivers/fpga/xrt/lib/xleaf/axigate.c | 342 +++
 2 files changed, 365 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xleaf/axigate.h
 create mode 100644 drivers/fpga/xrt/lib/xleaf/axigate.c

diff --git a/drivers/fpga/xrt/include/xleaf/axigate.h 
b/drivers/fpga/xrt/include/xleaf/axigate.h
new file mode 100644
index ..58f32c76dca1
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/axigate.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Lizhi Hou 
+ */
+
+#ifndef _XRT_AXIGATE_H_
+#define _XRT_AXIGATE_H_
+
+#include "xleaf.h"
+#include "metadata.h"
+
+/*
+ * AXIGATE driver leaf calls.
+ */
+enum xrt_axigate_leaf_cmd {
+   XRT_AXIGATE_CLOSE = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+   XRT_AXIGATE_OPEN,
+};
+
+#endif /* _XRT_AXIGATE_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/axigate.c 
b/drivers/fpga/xrt/lib/xleaf/axigate.c
new file mode 100644
index ..231bb0335278
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/axigate.c
@@ -0,0 +1,342 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA AXI Gate Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *  Lizhi Hou
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/axigate.h"
+
+#define XRT_AXIGATE "xrt_axigate"
+
+#define XRT_AXIGATE_WRITE_REG  0
+#define XRT_AXIGATE_READ_REG   8
+
+#define XRT_AXIGATE_CTRL_CLOSE 0
+#define XRT_AXIGATE_CTRL_OPEN_BIT0 1
+#define XRT_AXIGATE_CTRL_OPEN_BIT1 2
+
+#define XRT_AXIGATE_INTERVAL   500 /* ns */
+
+struct xrt_axigate {
+   struct platform_device  *pdev;
+   struct regmap   *regmap;
+   struct mutexgate_lock; /* gate dev lock */
+
+   void*evt_hdl;
+   const char  *ep_name;
+
+   boolgate_closed;
+};
+
+static const struct regmap_config axigate_regmap_config = {
+   .reg_bits = 32,
+   .val_bits = 32,
+   .reg_stride = 4,
+   .max_register = 0x1000,
+};
+
+/* the ep names are in the order of hardware layers */
+static const char * const xrt_axigate_epnames[] = {
+   XRT_MD_NODE_GATE_PLP, /* PLP: Provider Logic Partition */
+   XRT_MD_NODE_GATE_ULP  /* ULP: User Logic Partition */
+};
+
+static inline int close_gate(struct xrt_axigate *gate)
+{
+   u32 val;
+   int ret;
+
+   ret = regmap_write(gate->regmap, XRT_AXIGATE_WRITE_REG, 
XRT_AXIGATE_CTRL_CLOSE);
+   if (ret) {
+   xrt_err(gate->pdev, "write gate failed %d", ret);
+   return ret;
+   }
+   ndelay(XRT_AXIGATE_INTERVAL);
+   /*
+* Legacy hardware requires extra read work properly.
+* This is not on critical path, thus the extra read should not impact 
performance much.
+*/
+   ret = regmap_read(gate->regmap, XRT_AXIGATE_READ_REG, );
+   if (ret) {
+   xrt_err(gate->pdev, "read gate failed %d", ret);
+   return ret;
+   }
+
+   return 0;
+}
+
+static inline int open_gate(struct xrt_axigate *gate)
+{
+   u32 val;
+   int ret;
+
+   ret = regmap_write(gate->regmap, XRT_AXIGATE_WRITE_REG, 
XRT_AXIGATE_CTRL_OPEN_BIT1);
+   if (ret) {
+   xrt_err(gate->pdev, "write 2 failed %d", ret);
+   return ret;
+   }
+   ndelay(XRT_AXIGATE_INTERVAL);
+   /*
+* Legacy hardware requires extra read work properly.
+* This is not on critical path, thus the extra read should not impact 
performance much.
+*/
+   ret = regmap_read(gate->regmap, XRT_AXIGATE_READ_REG, );
+   if (ret) {
+   xrt_err(gate->pdev, "read 2 failed %d", ret);
+   return ret;
+   }
+   ret = regmap_write(gate->regmap, XRT_AXIGATE_WRITE_REG,
+  XRT_AXIGATE_CTRL_OPEN_BIT0 | 
XRT_AXIGATE_CTRL_OPEN_BIT1);
+   if (ret) {
+   xrt_err(gate->pdev, "write 3 failed %d", ret);
+   return ret;
+   }
+   ndelay(XRT_AXIGATE_INTERVAL);
+   ret = regmap_read(gate->regmap, XRT_AXIGATE_READ_REG, );
+   if (ret) {
+   xrt_err(gate->pdev, "read 3 failed %d", ret);
+   return ret;
+   }
+
+   return 0;
+}
+
+static int xrt_axigate_epname_idx(struct platform_device *pdev)
+{
+   struct resource *res;
+   int ret, i;
+
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   if (!res) {
+ 

[PATCH V4 XRT Alveo 15/20] fpga: xrt: devctl platform driver

2021-03-23 Thread Lizhi Hou
Add devctl driver. devctl is a type of hardware function which only has
few registers to read or write. They are discovered by walking firmware
metadata. A platform device node will be created for them.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xleaf/devctl.h |  40 ++
 drivers/fpga/xrt/lib/xleaf/devctl.c | 183 
 2 files changed, 223 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xleaf/devctl.h
 create mode 100644 drivers/fpga/xrt/lib/xleaf/devctl.c

diff --git a/drivers/fpga/xrt/include/xleaf/devctl.h 
b/drivers/fpga/xrt/include/xleaf/devctl.h
new file mode 100644
index ..b97f3b6d9326
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/devctl.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Lizhi Hou 
+ */
+
+#ifndef _XRT_DEVCTL_H_
+#define _XRT_DEVCTL_H_
+
+#include "xleaf.h"
+
+/*
+ * DEVCTL driver leaf calls.
+ */
+enum xrt_devctl_leaf_cmd {
+   XRT_DEVCTL_READ = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+};
+
+enum xrt_devctl_id {
+   XRT_DEVCTL_ROM_UUID = 0,
+   XRT_DEVCTL_DDR_CALIB,
+   XRT_DEVCTL_GOLDEN_VER,
+   XRT_DEVCTL_MAX
+};
+
+struct xrt_devctl_rw {
+   u32 xdr_id;
+   void*xdr_buf;
+   u32 xdr_len;
+   u32 xdr_offset;
+};
+
+struct xrt_devctl_intf_uuid {
+   u32 uuid_num;
+   uuid_t  *uuids;
+};
+
+#endif /* _XRT_DEVCTL_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/devctl.c 
b/drivers/fpga/xrt/lib/xleaf/devctl.c
new file mode 100644
index ..ae086d7c431d
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/devctl.c
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA devctl Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *  Lizhi Hou
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/devctl.h"
+
+#define XRT_DEVCTL "xrt_devctl"
+
+struct xrt_name_id {
+   char *ep_name;
+   int id;
+};
+
+static struct xrt_name_id name_id[XRT_DEVCTL_MAX] = {
+   { XRT_MD_NODE_BLP_ROM, XRT_DEVCTL_ROM_UUID },
+   { XRT_MD_NODE_GOLDEN_VER, XRT_DEVCTL_GOLDEN_VER },
+};
+
+static const struct regmap_config devctl_regmap_config = {
+   .reg_bits = 32,
+   .val_bits = 32,
+   .reg_stride = 4,
+};
+
+struct xrt_devctl {
+   struct platform_device  *pdev;
+   struct regmap   *regmap[XRT_DEVCTL_MAX];
+   ulong   sizes[XRT_DEVCTL_MAX];
+};
+
+static int xrt_devctl_name2id(struct xrt_devctl *devctl, const char *name)
+{
+   int i;
+
+   for (i = 0; i < XRT_DEVCTL_MAX && name_id[i].ep_name; i++) {
+   if (!strncmp(name_id[i].ep_name, name, 
strlen(name_id[i].ep_name) + 1))
+   return name_id[i].id;
+   }
+
+   return -EINVAL;
+}
+
+static int
+xrt_devctl_leaf_call(struct platform_device *pdev, u32 cmd, void *arg)
+{
+   struct xrt_devctl *devctl;
+   int ret = 0;
+
+   devctl = platform_get_drvdata(pdev);
+
+   switch (cmd) {
+   case XRT_XLEAF_EVENT:
+   /* Does not handle any event. */
+   break;
+   case XRT_DEVCTL_READ: {
+   struct xrt_devctl_rw *rw_arg = arg;
+
+   if (rw_arg->xdr_len & 0x3) {
+   xrt_err(pdev, "invalid len %d", rw_arg->xdr_len);
+   return -EINVAL;
+   }
+
+   if (rw_arg->xdr_id >= XRT_DEVCTL_MAX) {
+   xrt_err(pdev, "invalid id %d", rw_arg->xdr_id);
+   return -EINVAL;
+   }
+
+   if (!devctl->regmap[rw_arg->xdr_id]) {
+   xrt_err(pdev, "io not found, id %d",
+   rw_arg->xdr_id);
+   return -EINVAL;
+   }
+
+   ret = regmap_bulk_read(devctl->regmap[rw_arg->xdr_id], 
rw_arg->xdr_offset,
+  rw_arg->xdr_buf,
+  rw_arg->xdr_len / 
devctl_regmap_config.reg_stride);
+   break;
+   }
+   default:
+   xrt_err(pdev, "unsupported cmd %d", cmd);
+   return -EINVAL;
+   }
+
+   return ret;
+}
+
+static int xrt_devctl_probe(struct platform_device *pdev)
+{
+   struct xrt_devctl *devctl = NULL;
+   void __iomem *base = NULL;
+   struct resource *res;
+   int i, id, ret = 0;
+
+   devctl = devm_kzalloc(>dev, sizeof(*devctl), GFP_KERNEL);
+   if (!devctl)
+   return -ENOMEM;
+
+   devctl->pdev = pdev;
+   platform_set_drvdata(pdev, devctl);
+
+   xrt_info(pdev, "probing...");
+   for (i = 0, res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   res;
+   res = platform_get_resource(pdev, IORESOURCE_MEM, ++i)) {

[PATCH V4 XRT Alveo 16/20] fpga: xrt: clock platform driver

2021-03-23 Thread Lizhi Hou
Add clock driver. Clock is a hardware function discovered by walking
xclbin metadata. A platform device node will be created for it. Other
part of driver configures clock through clock driver.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xleaf/clock.h |  29 ++
 drivers/fpga/xrt/lib/xleaf/clock.c | 669 +
 2 files changed, 698 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xleaf/clock.h
 create mode 100644 drivers/fpga/xrt/lib/xleaf/clock.c

diff --git a/drivers/fpga/xrt/include/xleaf/clock.h 
b/drivers/fpga/xrt/include/xleaf/clock.h
new file mode 100644
index ..6858473fd096
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/clock.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Lizhi Hou 
+ */
+
+#ifndef _XRT_CLOCK_H_
+#define _XRT_CLOCK_H_
+
+#include "xleaf.h"
+#include 
+
+/*
+ * CLOCK driver leaf calls.
+ */
+enum xrt_clock_leaf_cmd {
+   XRT_CLOCK_SET = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+   XRT_CLOCK_GET,
+   XRT_CLOCK_VERIFY,
+};
+
+struct xrt_clock_get {
+   u16 freq;
+   u32 freq_cnter;
+};
+
+#endif /* _XRT_CLOCK_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/clock.c 
b/drivers/fpga/xrt/lib/xleaf/clock.c
new file mode 100644
index ..071485e4bf65
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/clock.c
@@ -0,0 +1,669 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA Clock Wizard Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *  Lizhi Hou
+ *  Sonal Santan 
+ *  David Zhang 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/clock.h"
+#include "xleaf/clkfreq.h"
+
+/* XRT_CLOCK_MAX_NUM_CLOCKS should be a concept from XCLBIN_ in the future */
+#define XRT_CLOCK_MAX_NUM_CLOCKS   4
+#define XRT_CLOCK_STATUS_MASK  0x
+#define XRT_CLOCK_STATUS_MEASURE_START 0x1
+#define XRT_CLOCK_STATUS_MEASURE_DONE  0x2
+
+#define XRT_CLOCK_STATUS_REG   0x4
+#define XRT_CLOCK_CLKFBOUT_REG 0x200
+#define XRT_CLOCK_CLKOUT0_REG  0x208
+#define XRT_CLOCK_LOAD_SADDR_SEN_REG   0x25C
+#define XRT_CLOCK_DEFAULT_EXPIRE_SECS  1
+
+#define CLOCK_ERR(clock, fmt, arg...)  \
+   xrt_err((clock)->pdev, fmt "\n", ##arg)
+#define CLOCK_WARN(clock, fmt, arg...) \
+   xrt_warn((clock)->pdev, fmt "\n", ##arg)
+#define CLOCK_INFO(clock, fmt, arg...) \
+   xrt_info((clock)->pdev, fmt "\n", ##arg)
+#define CLOCK_DBG(clock, fmt, arg...)  \
+   xrt_dbg((clock)->pdev, fmt "\n", ##arg)
+
+#define XRT_CLOCK  "xrt_clock"
+
+static const struct regmap_config clock_regmap_config = {
+   .reg_bits = 32,
+   .val_bits = 32,
+   .reg_stride = 4,
+   .max_register = 0x1000,
+};
+
+struct clock {
+   struct platform_device  *pdev;
+   struct regmap   *regmap;
+   struct mutexclock_lock; /* clock dev lock */
+
+   const char  *clock_ep_name;
+};
+
+/*
+ * Precomputed table with config0 and config2 register values together with
+ * target frequency. The steps are approximately 5 MHz apart. Table is
+ * generated by platform creation tool.
+ */
+static const struct xmgmt_ocl_clockwiz {
+   /* target frequency */
+   u16 ocl;
+   /* config0 register */
+   u32 config0;
+   /* config2 register */
+   u32 config2;
+} frequency_table[] = {
+   /*1275.000*/ { 10, 0x02EE0C01, 0x0001F47F },
+   /*1575.000*/ { 15, 0x02EE0F01, 0x0069},
+   /*1600.000*/ { 20, 0x1001, 0x0050},
+   /*1600.000*/ { 25, 0x1001, 0x0040},
+   /*1575.000*/ { 30, 0x02EE0F01, 0x0001F434},
+   /*1575.000*/ { 35, 0x02EE0F01, 0x002D},
+   /*1600.000*/ { 40, 0x1001, 0x0028},
+   /*1575.000*/ { 45, 0x02EE0F01, 0x0023},
+   /*1600.000*/ { 50, 0x1001, 0x0020},
+   /*1512.500*/ { 55, 0x007D0F01, 0x0001F41B},
+   /*1575.000*/ { 60, 0x02EE0F01, 0xFA1A},
+   /*1462.500*/ { 65, 0x02710E01, 0x0001F416},
+   /*1575.000*/ { 70, 0x02EE0F01, 0x0001F416},
+   /*1575.000*/ { 75, 0x02EE0F01, 0x0015},
+   /*1600.000*/ { 80, 0x1001, 0x0014},
+   /*1487.500*/ { 85, 0x036B0E01, 0x0001F411},
+   /*1575.000*/ { 90, 0x02EE0F01, 0x0001F411},
+   /*1425.000*/ { 95, 0x00FA0E01, 0x000F},
+   /*1600.000*/ { 100, 0x1001, 0x0010},
+   /*1575.000*/ { 105, 0x02EE0F01, 0x000F},
+   /*1512.500*/ { 110, 0x007D0F01, 0x0002EE0D},
+   /*1437.500*/ { 115, 0x01770E01, 0x0001F40C},
+   /*1575.000*/ { 120, 0x02EE0F01, 0x7D0D},
+   /*1562.500*/ { 125, 0x02710F01, 0x0001F40C},
+   /*1462.500*/ { 130, 0x02710E01, 0xFA0B},
+   /*1350.000*/ { 135, 0x01F40D01, 0x000A},
+   /*1575.000*/ { 140, 0x02EE0F01, 0xFA0B},
+   

[PATCH V4 XRT Alveo 13/20] fpga: xrt: User Clock Subsystem platform driver

2021-03-23 Thread Lizhi Hou
Add User Clock Subsystem (UCS) driver. UCS is a hardware function
discovered by walking xclbin metadata. A platform device node will be
created for it.  UCS enables/disables the dynamic region clocks.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/lib/xleaf/ucs.c | 167 +++
 1 file changed, 167 insertions(+)
 create mode 100644 drivers/fpga/xrt/lib/xleaf/ucs.c

diff --git a/drivers/fpga/xrt/lib/xleaf/ucs.c b/drivers/fpga/xrt/lib/xleaf/ucs.c
new file mode 100644
index ..d91ee229e7cb
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/ucs.c
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA UCS Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *  Lizhi Hou
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/clock.h"
+
+#define UCS_ERR(ucs, fmt, arg...)   \
+   xrt_err((ucs)->pdev, fmt "\n", ##arg)
+#define UCS_WARN(ucs, fmt, arg...)  \
+   xrt_warn((ucs)->pdev, fmt "\n", ##arg)
+#define UCS_INFO(ucs, fmt, arg...)  \
+   xrt_info((ucs)->pdev, fmt "\n", ##arg)
+#define UCS_DBG(ucs, fmt, arg...)   \
+   xrt_dbg((ucs)->pdev, fmt "\n", ##arg)
+
+#define XRT_UCS"xrt_ucs"
+
+#define XRT_UCS_CHANNEL1_REG   0
+#define XRT_UCS_CHANNEL2_REG   8
+
+#define CLK_MAX_VALUE  6400
+
+static const struct regmap_config ucs_regmap_config = {
+   .reg_bits = 32,
+   .val_bits = 32,
+   .reg_stride = 4,
+   .max_register = 0x1000,
+};
+
+struct xrt_ucs {
+   struct platform_device  *pdev;
+   struct regmap   *regmap;
+   struct mutexucs_lock; /* ucs dev lock */
+};
+
+static void xrt_ucs_event_cb(struct platform_device *pdev, void *arg)
+{
+   struct xrt_event *evt = (struct xrt_event *)arg;
+   enum xrt_events e = evt->xe_evt;
+   struct platform_device *leaf;
+   enum xrt_subdev_id id;
+   int instance;
+
+   id = evt->xe_subdev.xevt_subdev_id;
+   instance = evt->xe_subdev.xevt_subdev_instance;
+
+   if (e != XRT_EVENT_POST_CREATION) {
+   xrt_dbg(pdev, "ignored event %d", e);
+   return;
+   }
+
+   if (id != XRT_SUBDEV_CLOCK)
+   return;
+
+   leaf = xleaf_get_leaf_by_id(pdev, XRT_SUBDEV_CLOCK, instance);
+   if (!leaf) {
+   xrt_err(pdev, "does not get clock subdev");
+   return;
+   }
+
+   xleaf_call(leaf, XRT_CLOCK_VERIFY, NULL);
+   xleaf_put_leaf(pdev, leaf);
+}
+
+static int ucs_enable(struct xrt_ucs *ucs)
+{
+   int ret;
+
+   mutex_lock(>ucs_lock);
+   ret = regmap_write(ucs->regmap, XRT_UCS_CHANNEL2_REG, 1);
+   mutex_unlock(>ucs_lock);
+
+   return ret;
+}
+
+static int
+xrt_ucs_leaf_call(struct platform_device *pdev, u32 cmd, void *arg)
+{
+   switch (cmd) {
+   case XRT_XLEAF_EVENT:
+   xrt_ucs_event_cb(pdev, arg);
+   break;
+   default:
+   xrt_err(pdev, "unsupported cmd %d", cmd);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int ucs_probe(struct platform_device *pdev)
+{
+   struct xrt_ucs *ucs = NULL;
+   void __iomem *base = NULL;
+   struct resource *res;
+
+   ucs = devm_kzalloc(>dev, sizeof(*ucs), GFP_KERNEL);
+   if (!ucs)
+   return -ENOMEM;
+
+   platform_set_drvdata(pdev, ucs);
+   ucs->pdev = pdev;
+   mutex_init(>ucs_lock);
+
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   if (!res)
+   return -EINVAL;
+
+   base = devm_ioremap_resource(>dev, res);
+   if (IS_ERR(base))
+   return PTR_ERR(base);
+
+   ucs->regmap = devm_regmap_init_mmio(>dev, base, 
_regmap_config);
+   if (IS_ERR(ucs->regmap)) {
+   UCS_ERR(ucs, "map base %pR failed", res);
+   return PTR_ERR(ucs->regmap);
+   }
+   ucs_enable(ucs);
+
+   return 0;
+}
+
+static struct xrt_subdev_endpoints xrt_ucs_endpoints[] = {
+   {
+   .xse_names = (struct xrt_subdev_ep_names[]) {
+   { .ep_name = XRT_MD_NODE_UCS_CONTROL_STATUS },
+   { NULL },
+   },
+   .xse_min_ep = 1,
+   },
+   { 0 },
+};
+
+static struct xrt_subdev_drvdata xrt_ucs_data = {
+   .xsd_dev_ops = {
+   .xsd_leaf_call = xrt_ucs_leaf_call,
+   },
+};
+
+static const struct platform_device_id xrt_ucs_table[] = {
+   { XRT_UCS, (kernel_ulong_t)_ucs_data },
+   { },
+};
+
+static struct platform_driver xrt_ucs_driver = {
+   .driver = {
+   .name = XRT_UCS,
+   },
+   .probe = ucs_probe,
+   .id_table = xrt_ucs_table,
+};
+
+XRT_LEAF_INIT_FINI_FUNC(XRT_SUBDEV_UCS, ucs);
-- 
2.27.0



[PATCH V4 XRT Alveo 14/20] fpga: xrt: ICAP platform driver

2021-03-23 Thread Lizhi Hou
ICAP stands for Hardware Internal Configuration Access Port. ICAP is
discovered by walking firmware metadata. A platform device node will be
created for it. FPGA bitstream is written to hardware through ICAP.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xleaf/icap.h |  27 ++
 drivers/fpga/xrt/lib/xleaf/icap.c | 344 ++
 2 files changed, 371 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xleaf/icap.h
 create mode 100644 drivers/fpga/xrt/lib/xleaf/icap.c

diff --git a/drivers/fpga/xrt/include/xleaf/icap.h 
b/drivers/fpga/xrt/include/xleaf/icap.h
new file mode 100644
index ..96d39a8934fa
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/icap.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Lizhi Hou 
+ */
+
+#ifndef _XRT_ICAP_H_
+#define _XRT_ICAP_H_
+
+#include "xleaf.h"
+
+/*
+ * ICAP driver leaf calls.
+ */
+enum xrt_icap_leaf_cmd {
+   XRT_ICAP_WRITE = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+   XRT_ICAP_GET_IDCODE,
+};
+
+struct xrt_icap_wr {
+   void*xiiw_bit_data;
+   u32 xiiw_data_len;
+};
+
+#endif /* _XRT_ICAP_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/icap.c 
b/drivers/fpga/xrt/lib/xleaf/icap.c
new file mode 100644
index ..13db2b759138
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/icap.c
@@ -0,0 +1,344 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA ICAP Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *  Lizhi Hou
+ *  Sonal Santan 
+ *  Max Zhen 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/icap.h"
+#include "xclbin-helper.h"
+
+#define XRT_ICAP "xrt_icap"
+
+#define ICAP_ERR(icap, fmt, arg...)\
+   xrt_err((icap)->pdev, fmt "\n", ##arg)
+#define ICAP_WARN(icap, fmt, arg...)   \
+   xrt_warn((icap)->pdev, fmt "\n", ##arg)
+#define ICAP_INFO(icap, fmt, arg...)   \
+   xrt_info((icap)->pdev, fmt "\n", ##arg)
+#define ICAP_DBG(icap, fmt, arg...)\
+   xrt_dbg((icap)->pdev, fmt "\n", ##arg)
+
+/*
+ * AXI-HWICAP IP register layout. Please see
+ * 
https://www.xilinx.com/support/documentation/ip_documentation/axi_hwicap/v3_0/pg134-axi-hwicap.pdf
+ */
+#define ICAP_REG_GIER  0x1C
+#define ICAP_REG_ISR   0x20
+#define ICAP_REG_IER   0x28
+#define ICAP_REG_WF0x100
+#define ICAP_REG_RF0x104
+#define ICAP_REG_SZ0x108
+#define ICAP_REG_CR0x10C
+#define ICAP_REG_SR0x110
+#define ICAP_REG_WFV   0x114
+#define ICAP_REG_RFO   0x118
+#define ICAP_REG_ASR   0x11C
+
+#define ICAP_STATUS_EOS0x4
+#define ICAP_STATUS_DONE   0x1
+
+/*
+ * Canned command sequence to obtain IDCODE of the FPGA
+ */
+static const u32 idcode_stream[] = {
+   /* dummy word */
+   cpu_to_be32(0x),
+   /* sync word */
+   cpu_to_be32(0xaa995566),
+   /* NOP word */
+   cpu_to_be32(0x2000),
+   /* NOP word */
+   cpu_to_be32(0x2000),
+   /* ID code */
+   cpu_to_be32(0x28018001),
+   /* NOP word */
+   cpu_to_be32(0x2000),
+   /* NOP word */
+   cpu_to_be32(0x2000),
+};
+
+static const struct regmap_config icap_regmap_config = {
+   .reg_bits = 32,
+   .val_bits = 32,
+   .reg_stride = 4,
+   .max_register = 0x1000,
+};
+
+struct icap {
+   struct platform_device  *pdev;
+   struct regmap   *regmap;
+   struct mutexicap_lock; /* icap dev lock */
+
+   u32 idcode;
+};
+
+static int wait_for_done(const struct icap *icap)
+{
+   int i = 0;
+   int ret;
+   u32 w;
+
+   for (i = 0; i < 10; i++) {
+   /*
+* it requires few micro seconds for ICAP to process incoming 
data.
+* Polling every 5us for 10 times would be good enough.
+*/
+   udelay(5);
+   ret = regmap_read(icap->regmap, ICAP_REG_SR, );
+   if (ret)
+   return ret;
+   ICAP_INFO(icap, "XHWICAP_SR: %x", w);
+   if (w & (ICAP_STATUS_EOS | ICAP_STATUS_DONE))
+   return 0;
+   }
+
+   ICAP_ERR(icap, "bitstream download timeout");
+   return -ETIMEDOUT;
+}
+
+static int icap_write(const struct icap *icap, const u32 *word_buf, int size)
+{
+   u32 value = 0;
+   int ret;
+   int i;
+
+   for (i = 0; i < size; i++) {
+   value = be32_to_cpu(word_buf[i]);
+   ret = regmap_write(icap->regmap, ICAP_REG_WF, value);
+   if (ret)
+   return ret;
+   }
+
+   ret = regmap_write(icap->regmap, ICAP_REG_CR, 0x1);
+   if (ret)
+   return ret;
+
+   

[PATCH V4 XRT Alveo 12/20] fpga: xrt: VSEC platform driver

2021-03-23 Thread Lizhi Hou
Add VSEC driver. VSEC is a hardware function discovered by walking
PCI Express configure space. A platform device node will be created
for it. VSEC provides board logic UUID and few offset of other hardware
functions.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/lib/xleaf/vsec.c | 388 ++
 1 file changed, 388 insertions(+)
 create mode 100644 drivers/fpga/xrt/lib/xleaf/vsec.c

diff --git a/drivers/fpga/xrt/lib/xleaf/vsec.c 
b/drivers/fpga/xrt/lib/xleaf/vsec.c
new file mode 100644
index ..8595d23f5710
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/vsec.c
@@ -0,0 +1,388 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA VSEC Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *  Lizhi Hou
+ */
+
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+
+#define XRT_VSEC "xrt_vsec"
+
+#define VSEC_TYPE_UUID 0x50
+#define VSEC_TYPE_FLASH0x51
+#define VSEC_TYPE_PLATINFO 0x52
+#define VSEC_TYPE_MAILBOX  0x53
+#define VSEC_TYPE_END  0xff
+
+#define VSEC_UUID_LEN  16
+
+#define VSEC_REG_FORMAT0x0
+#define VSEC_REG_LENGTH0x4
+#define VSEC_REG_ENTRY 0x8
+
+struct xrt_vsec_header {
+   u32 format;
+   u32 length;
+   u32 entry_sz;
+   u32 rsvd;
+} __packed;
+
+struct xrt_vsec_entry {
+   u8  type;
+   u8  bar_rev;
+   u16 off_lo;
+   u32 off_hi;
+   u8  ver_type;
+   u8  minor;
+   u8  major;
+   u8  rsvd0;
+   u32 rsvd1;
+} __packed;
+
+struct vsec_device {
+   u8  type;
+   char*ep_name;
+   ulong   size;
+   char*regmap;
+};
+
+static struct vsec_device vsec_devs[] = {
+   {
+   .type = VSEC_TYPE_UUID,
+   .ep_name = XRT_MD_NODE_BLP_ROM,
+   .size = VSEC_UUID_LEN,
+   .regmap = "vsec-uuid",
+   },
+   {
+   .type = VSEC_TYPE_FLASH,
+   .ep_name = XRT_MD_NODE_FLASH_VSEC,
+   .size = 4096,
+   .regmap = "vsec-flash",
+   },
+   {
+   .type = VSEC_TYPE_PLATINFO,
+   .ep_name = XRT_MD_NODE_PLAT_INFO,
+   .size = 4,
+   .regmap = "vsec-platinfo",
+   },
+   {
+   .type = VSEC_TYPE_MAILBOX,
+   .ep_name = XRT_MD_NODE_MAILBOX_VSEC,
+   .size = 48,
+   .regmap = "vsec-mbx",
+   },
+};
+
+static const struct regmap_config vsec_regmap_config = {
+   .reg_bits = 32,
+   .val_bits = 32,
+   .reg_stride = 4,
+   .max_register = 0x1000,
+};
+
+struct xrt_vsec {
+   struct platform_device  *pdev;
+   struct regmap   *regmap;
+   u32 length;
+
+   char*metadata;
+   charuuid[VSEC_UUID_LEN];
+   int group;
+};
+
+static inline int vsec_read_entry(struct xrt_vsec *vsec, u32 index, struct 
xrt_vsec_entry *entry)
+{
+   int ret;
+
+   ret = regmap_bulk_read(vsec->regmap, sizeof(struct xrt_vsec_header) +
+  index * sizeof(struct xrt_vsec_entry), entry,
+  sizeof(struct xrt_vsec_entry) /
+  vsec_regmap_config.reg_stride);
+
+   return ret;
+}
+
+static inline u32 vsec_get_bar(struct xrt_vsec_entry *entry)
+{
+   return ((entry)->bar_rev >> 4) & 0xf;
+}
+
+static inline u64 vsec_get_bar_off(struct xrt_vsec_entry *entry)
+{
+   return (entry)->off_lo | ((u64)(entry)->off_hi << 16);
+}
+
+static inline u32 vsec_get_rev(struct xrt_vsec_entry *entry)
+{
+   return (entry)->bar_rev & 0xf;
+}
+
+static char *type2epname(u32 type)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(vsec_devs); i++) {
+   if (vsec_devs[i].type == type)
+   return (vsec_devs[i].ep_name);
+   }
+
+   return NULL;
+}
+
+static ulong type2size(u32 type)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(vsec_devs); i++) {
+   if (vsec_devs[i].type == type)
+   return (vsec_devs[i].size);
+   }
+
+   return 0;
+}
+
+static char *type2regmap(u32 type)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(vsec_devs); i++) {
+   if (vsec_devs[i].type == type)
+   return (vsec_devs[i].regmap);
+   }
+
+   return NULL;
+}
+
+static int xrt_vsec_add_node(struct xrt_vsec *vsec,
+void *md_blob, struct xrt_vsec_entry *p_entry)
+{
+   struct xrt_md_endpoint ep;
+   char regmap_ver[64];
+   int ret;
+
+   if (!type2epname(p_entry->type))
+   return 

[PATCH V4 XRT Alveo 11/20] fpga: xrt: fpga-mgr and region implementation for xclbin download

2021-03-23 Thread Lizhi Hou
fpga-mgr and region implementation for xclbin download which will be
called from main platform driver

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/mgmt/fmgr-drv.c| 191 +++
 drivers/fpga/xrt/mgmt/fmgr.h|  19 ++
 drivers/fpga/xrt/mgmt/main-region.c | 483 
 3 files changed, 693 insertions(+)
 create mode 100644 drivers/fpga/xrt/mgmt/fmgr-drv.c
 create mode 100644 drivers/fpga/xrt/mgmt/fmgr.h
 create mode 100644 drivers/fpga/xrt/mgmt/main-region.c

diff --git a/drivers/fpga/xrt/mgmt/fmgr-drv.c b/drivers/fpga/xrt/mgmt/fmgr-drv.c
new file mode 100644
index ..12e1cc788ad9
--- /dev/null
+++ b/drivers/fpga/xrt/mgmt/fmgr-drv.c
@@ -0,0 +1,191 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * FPGA Manager Support for Xilinx Alveo Management Function Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors: sonal.san...@xilinx.com
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "xclbin-helper.h"
+#include "xleaf.h"
+#include "fmgr.h"
+#include "xleaf/axigate.h"
+#include "xleaf/icap.h"
+#include "xmgnt.h"
+
+struct xfpga_class {
+   const struct platform_device *pdev;
+   char  name[64];
+};
+
+/*
+ * xclbin download plumbing -- find the download subsystem, ICAP and
+ * pass the xclbin for heavy lifting
+ */
+static int xmgmt_download_bitstream(struct platform_device *pdev,
+   const struct axlf *xclbin)
+
+{
+   struct xclbin_bit_head_info bit_header = { 0 };
+   struct platform_device *icap_leaf = NULL;
+   struct xrt_icap_wr arg;
+   char *bitstream = NULL;
+   u64 bit_len;
+   int ret;
+
+   ret = xrt_xclbin_get_section(DEV(pdev), xclbin, BITSTREAM, (void 
**), _len);
+   if (ret) {
+   xrt_err(pdev, "bitstream not found");
+   return -ENOENT;
+   }
+   ret = xrt_xclbin_parse_bitstream_header(DEV(pdev), bitstream,
+   XCLBIN_HWICAP_BITFILE_BUF_SZ,
+   _header);
+   if (ret) {
+   ret = -EINVAL;
+   xrt_err(pdev, "invalid bitstream header");
+   goto fail;
+   }
+   if (bit_header.header_length + bit_header.bitstream_length > bit_len) {
+   ret = -EINVAL;
+   xrt_err(pdev, "invalid bitstream length. header %d, bitstream 
%d, section len %lld",
+   bit_header.header_length, bit_header.bitstream_length, 
bit_len);
+   goto fail;
+   }
+
+   icap_leaf = xleaf_get_leaf_by_id(pdev, XRT_SUBDEV_ICAP, 
PLATFORM_DEVID_NONE);
+   if (!icap_leaf) {
+   ret = -ENODEV;
+   xrt_err(pdev, "icap does not exist");
+   goto fail;
+   }
+   arg.xiiw_bit_data = bitstream + bit_header.header_length;
+   arg.xiiw_data_len = bit_header.bitstream_length;
+   ret = xleaf_call(icap_leaf, XRT_ICAP_WRITE, );
+   if (ret) {
+   xrt_err(pdev, "write bitstream failed, ret = %d", ret);
+   xleaf_put_leaf(pdev, icap_leaf);
+   goto fail;
+   }
+
+   xleaf_put_leaf(pdev, icap_leaf);
+   vfree(bitstream);
+
+   return 0;
+
+fail:
+   vfree(bitstream);
+
+   return ret;
+}
+
+/*
+ * There is no HW prep work we do here since we need the full
+ * xclbin for its sanity check.
+ */
+static int xmgmt_pr_write_init(struct fpga_manager *mgr,
+  struct fpga_image_info *info,
+  const char *buf, size_t count)
+{
+   const struct axlf *bin = (const struct axlf *)buf;
+   struct xfpga_class *obj = mgr->priv;
+
+   if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
+   xrt_info(obj->pdev, "%s only supports partial 
reconfiguration\n", obj->name);
+   return -EINVAL;
+   }
+
+   if (count < sizeof(struct axlf))
+   return -EINVAL;
+
+   if (count > bin->header.length)
+   return -EINVAL;
+
+   xrt_info(obj->pdev, "Prepare download of xclbin %pUb of length %lld B",
+>header.uuid, bin->header.length);
+
+   return 0;
+}
+
+/*
+ * The implementation requries full xclbin image before we can start
+ * programming the hardware via ICAP subsystem. The full image is required
+ * for checking the validity of xclbin and walking the sections to
+ * discover the bitstream.
+ */
+static int xmgmt_pr_write(struct fpga_manager *mgr,
+ const char *buf, size_t count)
+{
+   const struct axlf *bin = (const struct axlf *)buf;
+   struct xfpga_class *obj = mgr->priv;
+
+   if (bin->header.length != count)
+   return -EINVAL;
+
+   return xmgmt_download_bitstream((void *)obj->pdev, bin);
+}
+
+static int xmgmt_pr_write_complete(struct fpga_manager *mgr,
+   

[PATCH V4 XRT Alveo 09/20] fpga: xrt: management physical function driver (root)

2021-03-23 Thread Lizhi Hou
The PCIE device driver which attaches to management function on Alveo
devices. It instantiates one or more group drivers which, in turn,
instantiate platform drivers. The instantiation of group and platform
drivers is completely dtb driven.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/mgmt/root.c | 333 +++
 1 file changed, 333 insertions(+)
 create mode 100644 drivers/fpga/xrt/mgmt/root.c

diff --git a/drivers/fpga/xrt/mgmt/root.c b/drivers/fpga/xrt/mgmt/root.c
new file mode 100644
index ..f97f92807c01
--- /dev/null
+++ b/drivers/fpga/xrt/mgmt/root.c
@@ -0,0 +1,333 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo Management Function Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "xroot.h"
+#include "xmgnt.h"
+#include "metadata.h"
+
+#define XMGMT_MODULE_NAME  "xrt-mgmt"
+#define XMGMT_DRIVER_VERSION   "4.0.0"
+
+#define XMGMT_PDEV(xm) ((xm)->pdev)
+#define XMGMT_DEV(xm)  (&(XMGMT_PDEV(xm)->dev))
+#define xmgmt_err(xm, fmt, args...)\
+   dev_err(XMGMT_DEV(xm), "%s: " fmt, __func__, ##args)
+#define xmgmt_warn(xm, fmt, args...)   \
+   dev_warn(XMGMT_DEV(xm), "%s: " fmt, __func__, ##args)
+#define xmgmt_info(xm, fmt, args...)   \
+   dev_info(XMGMT_DEV(xm), "%s: " fmt, __func__, ##args)
+#define xmgmt_dbg(xm, fmt, args...)\
+   dev_dbg(XMGMT_DEV(xm), "%s: " fmt, __func__, ##args)
+#define XMGMT_DEV_ID(_pcidev)  \
+   ({ typeof(_pcidev) (pcidev) = (_pcidev);\
+   ((pci_domain_nr((pcidev)->bus) << 16) | \
+   PCI_DEVID((pcidev)->bus->number, 0)); })
+
+static struct class *xmgmt_class;
+
+/* PCI Device IDs */
+#define PCI_DEVICE_ID_U50_GOLDEN   0xD020
+#define PCI_DEVICE_ID_U50  0x5020
+static const struct pci_device_id xmgmt_pci_ids[] = {
+   { PCI_DEVICE(PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_U50_GOLDEN), }, /* 
Alveo U50 (golden) */
+   { PCI_DEVICE(PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_U50), }, /* Alveo U50 
*/
+   { 0, }
+};
+
+struct xmgmt {
+   struct pci_dev *pdev;
+   void *root;
+
+   bool ready;
+};
+
+static int xmgmt_config_pci(struct xmgmt *xm)
+{
+   struct pci_dev *pdev = XMGMT_PDEV(xm);
+   int rc;
+
+   rc = pcim_enable_device(pdev);
+   if (rc < 0) {
+   xmgmt_err(xm, "failed to enable device: %d", rc);
+   return rc;
+   }
+
+   rc = pci_enable_pcie_error_reporting(pdev);
+   if (rc)
+   xmgmt_warn(xm, "failed to enable AER: %d", rc);
+
+   pci_set_master(pdev);
+
+   rc = pcie_get_readrq(pdev);
+   if (rc > 512)
+   pcie_set_readrq(pdev, 512);
+   return 0;
+}
+
+static int xmgmt_match_slot_and_save(struct device *dev, void *data)
+{
+   struct xmgmt *xm = data;
+   struct pci_dev *pdev = to_pci_dev(dev);
+
+   if (XMGMT_DEV_ID(pdev) == XMGMT_DEV_ID(xm->pdev)) {
+   pci_cfg_access_lock(pdev);
+   pci_save_state(pdev);
+   }
+
+   return 0;
+}
+
+static void xmgmt_pci_save_config_all(struct xmgmt *xm)
+{
+   bus_for_each_dev(_bus_type, NULL, xm, xmgmt_match_slot_and_save);
+}
+
+static int xmgmt_match_slot_and_restore(struct device *dev, void *data)
+{
+   struct xmgmt *xm = data;
+   struct pci_dev *pdev = to_pci_dev(dev);
+
+   if (XMGMT_DEV_ID(pdev) == XMGMT_DEV_ID(xm->pdev)) {
+   pci_restore_state(pdev);
+   pci_cfg_access_unlock(pdev);
+   }
+
+   return 0;
+}
+
+static void xmgmt_pci_restore_config_all(struct xmgmt *xm)
+{
+   bus_for_each_dev(_bus_type, NULL, xm, xmgmt_match_slot_and_restore);
+}
+
+static void xmgmt_root_hot_reset(struct pci_dev *pdev)
+{
+   struct xmgmt *xm = pci_get_drvdata(pdev);
+   struct pci_bus *bus;
+   u8 pci_bctl;
+   u16 pci_cmd, devctl;
+   int i, ret;
+
+   xmgmt_info(xm, "hot reset start");
+
+   xmgmt_pci_save_config_all(xm);
+
+   pci_disable_device(pdev);
+
+   bus = pdev->bus;
+
+   /*
+* When flipping the SBR bit, device can fall off the bus. This is
+* usually no problem at all so long as drivers are working properly
+* after SBR. However, some systems complain bitterly when the device
+* falls off the bus.
+* The quick solution is to temporarily disable the SERR reporting of
+* switch port during SBR.
+*/
+
+   pci_read_config_word(bus->self, PCI_COMMAND, _cmd);
+   pci_write_config_word(bus->self, PCI_COMMAND, (pci_cmd & 
~PCI_COMMAND_SERR));
+   pcie_capability_read_word(bus->self, PCI_EXP_DEVCTL, );
+   pcie_capability_write_word(bus->self, PCI_EXP_DEVCTL, (devctl & 
~PCI_EXP_DEVCTL_FERE));
+   pci_read_config_byte(bus->self, PCI_BRIDGE_CONTROL, _bctl);
+   pci_write_config_byte(bus->self, 

[PATCH V4 XRT Alveo 10/20] fpga: xrt: main platform driver for management function device

2021-03-23 Thread Lizhi Hou
platform driver that handles IOCTLs, such as hot reset and xclbin download.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xmgmt-main.h |  34 ++
 drivers/fpga/xrt/mgmt/main.c  | 670 ++
 drivers/fpga/xrt/mgmt/xmgnt.h |  34 ++
 include/uapi/linux/xrt/xmgmt-ioctl.h  |  46 ++
 4 files changed, 784 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xmgmt-main.h
 create mode 100644 drivers/fpga/xrt/mgmt/main.c
 create mode 100644 drivers/fpga/xrt/mgmt/xmgnt.h
 create mode 100644 include/uapi/linux/xrt/xmgmt-ioctl.h

diff --git a/drivers/fpga/xrt/include/xmgmt-main.h 
b/drivers/fpga/xrt/include/xmgmt-main.h
new file mode 100644
index ..dce9f0d1a0dc
--- /dev/null
+++ b/drivers/fpga/xrt/include/xmgmt-main.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#ifndef _XMGMT_MAIN_H_
+#define _XMGMT_MAIN_H_
+
+#include 
+#include "xleaf.h"
+
+enum xrt_mgmt_main_leaf_cmd {
+   XRT_MGMT_MAIN_GET_AXLF_SECTION = XRT_XLEAF_CUSTOM_BASE, /* See comments 
in xleaf.h */
+   XRT_MGMT_MAIN_GET_VBNV,
+};
+
+/* There are three kind of partitions. Each of them is programmed 
independently. */
+enum provider_kind {
+   XMGMT_BLP, /* Base Logic Partition */
+   XMGMT_PLP, /* Provider Logic Partition */
+   XMGMT_ULP, /* User Logic Partition */
+};
+
+struct xrt_mgmt_main_get_axlf_section {
+   enum provider_kind xmmigas_axlf_kind;
+   enum axlf_section_kind xmmigas_section_kind;
+   void *xmmigas_section;
+   u64 xmmigas_section_size;
+};
+
+#endif /* _XMGMT_MAIN_H_ */
diff --git a/drivers/fpga/xrt/mgmt/main.c b/drivers/fpga/xrt/mgmt/main.c
new file mode 100644
index ..f3b46e1fd78b
--- /dev/null
+++ b/drivers/fpga/xrt/mgmt/main.c
@@ -0,0 +1,670 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA MGMT PF entry point driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Sonal Santan 
+ */
+
+#include 
+#include 
+#include "xclbin-helper.h"
+#include "metadata.h"
+#include "xleaf.h"
+#include 
+#include "xleaf/devctl.h"
+#include "xmgmt-main.h"
+#include "fmgr.h"
+#include "xleaf/icap.h"
+#include "xleaf/axigate.h"
+#include "xmgnt.h"
+
+#define XMGMT_MAIN "xmgmt_main"
+#define XMGMT_SUPP_XCLBIN_MAJOR 2
+
+#define XMGMT_FLAG_FLASH_READY 1
+#define XMGMT_FLAG_DEVCTL_READY2
+
+#define XMGMT_UUID_STR_LEN 80
+
+struct xmgmt_main {
+   struct platform_device *pdev;
+   struct axlf *firmware_blp;
+   struct axlf *firmware_plp;
+   struct axlf *firmware_ulp;
+   u32 flags;
+   struct fpga_manager *fmgr;
+   struct mutex lock; /* busy lock */
+
+   uuid_t *blp_interface_uuids;
+   u32 blp_interface_uuid_num;
+};
+
+/*
+ * VBNV stands for Vendor, BoardID, Name, Version. It is a string
+ * which describes board and shell.
+ *
+ * Caller is responsible for freeing the returned string.
+ */
+char *xmgmt_get_vbnv(struct platform_device *pdev)
+{
+   struct xmgmt_main *xmm = platform_get_drvdata(pdev);
+   const char *vbnv;
+   char *ret;
+   int i;
+
+   if (xmm->firmware_plp)
+   vbnv = xmm->firmware_plp->header.platform_vbnv;
+   else if (xmm->firmware_blp)
+   vbnv = xmm->firmware_blp->header.platform_vbnv;
+   else
+   return NULL;
+
+   ret = kstrdup(vbnv, GFP_KERNEL);
+   if (!ret)
+   return NULL;
+
+   for (i = 0; i < strlen(ret); i++) {
+   if (ret[i] == ':' || ret[i] == '.')
+   ret[i] = '_';
+   }
+   return ret;
+}
+
+static int get_dev_uuid(struct platform_device *pdev, char *uuidstr, size_t 
len)
+{
+   struct xrt_devctl_rw devctl_arg = { 0 };
+   struct platform_device *devctl_leaf;
+   char uuid_buf[UUID_SIZE];
+   uuid_t uuid;
+   int err;
+
+   devctl_leaf = xleaf_get_leaf_by_epname(pdev, XRT_MD_NODE_BLP_ROM);
+   if (!devctl_leaf) {
+   xrt_err(pdev, "can not get %s", XRT_MD_NODE_BLP_ROM);
+   return -EINVAL;
+   }
+
+   devctl_arg.xdr_id = XRT_DEVCTL_ROM_UUID;
+   devctl_arg.xdr_buf = uuid_buf;
+   devctl_arg.xdr_len = sizeof(uuid_buf);
+   devctl_arg.xdr_offset = 0;
+   err = xleaf_call(devctl_leaf, XRT_DEVCTL_READ, _arg);
+   xleaf_put_leaf(pdev, devctl_leaf);
+   if (err) {
+   xrt_err(pdev, "can not get uuid: %d", err);
+   return err;
+   }
+   import_uuid(, uuid_buf);
+   xrt_md_trans_uuid2str(, uuidstr);
+
+   return 0;
+}
+
+int xmgmt_hot_reset(struct platform_device *pdev)
+{
+   int ret = xleaf_broadcast_event(pdev, XRT_EVENT_PRE_HOT_RESET, false);
+
+   if (ret) {
+   xrt_err(pdev, "offline failed, hot reset is canceled");
+   return ret;
+   }
+
+   xleaf_hot_reset(pdev);
+   

[PATCH V4 XRT Alveo 06/20] fpga: xrt: char dev node helper functions

2021-03-23 Thread Lizhi Hou
Helper functions for char device node creation / removal for platform
drivers. This is part of platform driver infrastructure.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/lib/cdev.c | 232 
 1 file changed, 232 insertions(+)
 create mode 100644 drivers/fpga/xrt/lib/cdev.c

diff --git a/drivers/fpga/xrt/lib/cdev.c b/drivers/fpga/xrt/lib/cdev.c
new file mode 100644
index ..38efd24b6e10
--- /dev/null
+++ b/drivers/fpga/xrt/lib/cdev.c
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA device node helper functions.
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#include "xleaf.h"
+
+extern struct class *xrt_class;
+
+#define XRT_CDEV_DIR   "xfpga"
+#define INODE2PDATA(inode) \
+   container_of((inode)->i_cdev, struct xrt_subdev_platdata, xsp_cdev)
+#define INODE2PDEV(inode)  \
+   to_platform_device(kobj_to_dev((inode)->i_cdev->kobj.parent))
+#define CDEV_NAME(sysdev)  (strchr((sysdev)->kobj.name, '!') + 1)
+
+/* Allow it to be accessed from cdev. */
+static void xleaf_devnode_allowed(struct platform_device *pdev)
+{
+   struct xrt_subdev_platdata *pdata = DEV_PDATA(pdev);
+
+   /* Allow new opens. */
+   mutex_lock(>xsp_devnode_lock);
+   pdata->xsp_devnode_online = true;
+   mutex_unlock(>xsp_devnode_lock);
+}
+
+/* Turn off access from cdev and wait for all existing user to go away. */
+static int xleaf_devnode_disallowed(struct platform_device *pdev)
+{
+   int ret = 0;
+   struct xrt_subdev_platdata *pdata = DEV_PDATA(pdev);
+
+   mutex_lock(>xsp_devnode_lock);
+
+   /* Prevent new opens. */
+   pdata->xsp_devnode_online = false;
+   /* Wait for existing user to close. */
+   while (!ret && pdata->xsp_devnode_ref) {
+   int rc;
+
+   mutex_unlock(>xsp_devnode_lock);
+   rc = wait_for_completion_killable(>xsp_devnode_comp);
+   mutex_lock(>xsp_devnode_lock);
+
+   if (rc == -ERESTARTSYS) {
+   /* Restore online state. */
+   pdata->xsp_devnode_online = true;
+   xrt_err(pdev, "%s is in use, ref=%d",
+   CDEV_NAME(pdata->xsp_sysdev),
+   pdata->xsp_devnode_ref);
+   ret = -EBUSY;
+   }
+   }
+
+   mutex_unlock(>xsp_devnode_lock);
+
+   return ret;
+}
+
+static struct platform_device *
+__xleaf_devnode_open(struct inode *inode, bool excl)
+{
+   struct xrt_subdev_platdata *pdata = INODE2PDATA(inode);
+   struct platform_device *pdev = INODE2PDEV(inode);
+   bool opened = false;
+
+   mutex_lock(>xsp_devnode_lock);
+
+   if (pdata->xsp_devnode_online) {
+   if (excl && pdata->xsp_devnode_ref) {
+   xrt_err(pdev, "%s has already been opened exclusively",
+   CDEV_NAME(pdata->xsp_sysdev));
+   } else if (!excl && pdata->xsp_devnode_excl) {
+   xrt_err(pdev, "%s has been opened exclusively",
+   CDEV_NAME(pdata->xsp_sysdev));
+   } else {
+   pdata->xsp_devnode_ref++;
+   pdata->xsp_devnode_excl = excl;
+   opened = true;
+   xrt_info(pdev, "opened %s, ref=%d",
+CDEV_NAME(pdata->xsp_sysdev),
+pdata->xsp_devnode_ref);
+   }
+   } else {
+   xrt_err(pdev, "%s is offline", CDEV_NAME(pdata->xsp_sysdev));
+   }
+
+   mutex_unlock(>xsp_devnode_lock);
+
+   pdev = opened ? pdev : NULL;
+   return pdev;
+}
+
+struct platform_device *
+xleaf_devnode_open_excl(struct inode *inode)
+{
+   return __xleaf_devnode_open(inode, true);
+}
+
+struct platform_device *
+xleaf_devnode_open(struct inode *inode)
+{
+   return __xleaf_devnode_open(inode, false);
+}
+EXPORT_SYMBOL_GPL(xleaf_devnode_open);
+
+void xleaf_devnode_close(struct inode *inode)
+{
+   struct xrt_subdev_platdata *pdata = INODE2PDATA(inode);
+   struct platform_device *pdev = INODE2PDEV(inode);
+   bool notify = false;
+
+   mutex_lock(>xsp_devnode_lock);
+
+   WARN_ON(pdata->xsp_devnode_ref == 0);
+   pdata->xsp_devnode_ref--;
+   if (pdata->xsp_devnode_ref == 0) {
+   pdata->xsp_devnode_excl = false;
+   notify = true;
+   }
+   if (notify) {
+   xrt_info(pdev, "closed %s, ref=%d",
+CDEV_NAME(pdata->xsp_sysdev), pdata->xsp_devnode_ref);
+   } else {
+   xrt_info(pdev, "closed %s, notifying waiter",
+CDEV_NAME(pdata->xsp_sysdev));
+   }
+
+   mutex_unlock(>xsp_devnode_lock);
+
+   if (notify)
+   

[PATCH V4 XRT Alveo 07/20] fpga: xrt: root driver infrastructure

2021-03-23 Thread Lizhi Hou
Contains common code for all root drivers and handles root calls from
platform drivers. This is part of root driver infrastructure.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/events.h  |  45 +++
 drivers/fpga/xrt/include/xroot.h   | 117 ++
 drivers/fpga/xrt/lib/subdev_pool.h |  53 +++
 drivers/fpga/xrt/lib/xroot.c   | 589 +
 4 files changed, 804 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/events.h
 create mode 100644 drivers/fpga/xrt/include/xroot.h
 create mode 100644 drivers/fpga/xrt/lib/subdev_pool.h
 create mode 100644 drivers/fpga/xrt/lib/xroot.c

diff --git a/drivers/fpga/xrt/include/events.h 
b/drivers/fpga/xrt/include/events.h
new file mode 100644
index ..775171a47c8e
--- /dev/null
+++ b/drivers/fpga/xrt/include/events.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#ifndef _XRT_EVENTS_H_
+#define _XRT_EVENTS_H_
+
+#include "subdev_id.h"
+
+/*
+ * Event notification.
+ */
+enum xrt_events {
+   XRT_EVENT_TEST = 0, /* for testing */
+   /*
+* Events related to specific subdev
+* Callback arg: struct xrt_event_arg_subdev
+*/
+   XRT_EVENT_POST_CREATION,
+   XRT_EVENT_PRE_REMOVAL,
+   /*
+* Events related to change of the whole board
+* Callback arg: 
+*/
+   XRT_EVENT_PRE_HOT_RESET,
+   XRT_EVENT_POST_HOT_RESET,
+   XRT_EVENT_PRE_GATE_CLOSE,
+   XRT_EVENT_POST_GATE_OPEN,
+};
+
+struct xrt_event_arg_subdev {
+   enum xrt_subdev_id xevt_subdev_id;
+   int xevt_subdev_instance;
+};
+
+struct xrt_event {
+   enum xrt_events xe_evt;
+   struct xrt_event_arg_subdev xe_subdev;
+};
+
+#endif /* _XRT_EVENTS_H_ */
diff --git a/drivers/fpga/xrt/include/xroot.h b/drivers/fpga/xrt/include/xroot.h
new file mode 100644
index ..91c0aeb30bf8
--- /dev/null
+++ b/drivers/fpga/xrt/include/xroot.h
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#ifndef _XRT_ROOT_H_
+#define _XRT_ROOT_H_
+
+#include 
+#include 
+#include "subdev_id.h"
+#include "events.h"
+
+typedef bool (*xrt_subdev_match_t)(enum xrt_subdev_id,
+   struct platform_device *, void *);
+#define XRT_SUBDEV_MATCH_PREV  ((xrt_subdev_match_t)-1)
+#define XRT_SUBDEV_MATCH_NEXT  ((xrt_subdev_match_t)-2)
+
+/*
+ * Root calls.
+ */
+enum xrt_root_cmd {
+   /* Leaf actions. */
+   XRT_ROOT_GET_LEAF = 0,
+   XRT_ROOT_PUT_LEAF,
+   XRT_ROOT_GET_LEAF_HOLDERS,
+
+   /* Group actions. */
+   XRT_ROOT_CREATE_GROUP,
+   XRT_ROOT_REMOVE_GROUP,
+   XRT_ROOT_LOOKUP_GROUP,
+   XRT_ROOT_WAIT_GROUP_BRINGUP,
+
+   /* Event actions. */
+   XRT_ROOT_EVENT_SYNC,
+   XRT_ROOT_EVENT_ASYNC,
+
+   /* Device info. */
+   XRT_ROOT_GET_RESOURCE,
+   XRT_ROOT_GET_ID,
+
+   /* Misc. */
+   XRT_ROOT_HOT_RESET,
+   XRT_ROOT_HWMON,
+};
+
+struct xrt_root_get_leaf {
+   struct platform_device *xpigl_caller_pdev;
+   xrt_subdev_match_t xpigl_match_cb;
+   void *xpigl_match_arg;
+   struct platform_device *xpigl_tgt_pdev;
+};
+
+struct xrt_root_put_leaf {
+   struct platform_device *xpipl_caller_pdev;
+   struct platform_device *xpipl_tgt_pdev;
+};
+
+struct xrt_root_lookup_group {
+   struct platform_device *xpilp_pdev; /* caller's pdev */
+   xrt_subdev_match_t xpilp_match_cb;
+   void *xpilp_match_arg;
+   int xpilp_grp_inst;
+};
+
+struct xrt_root_get_holders {
+   struct platform_device *xpigh_pdev; /* caller's pdev */
+   char *xpigh_holder_buf;
+   size_t xpigh_holder_buf_len;
+};
+
+struct xrt_root_get_res {
+   struct resource *xpigr_res;
+};
+
+struct xrt_root_get_id {
+   unsigned short  xpigi_vendor_id;
+   unsigned short  xpigi_device_id;
+   unsigned short  xpigi_sub_vendor_id;
+   unsigned short  xpigi_sub_device_id;
+};
+
+struct xrt_root_hwmon {
+   bool xpih_register;
+   const char *xpih_name;
+   void *xpih_drvdata;
+   const struct attribute_group **xpih_groups;
+   struct device *xpih_hwmon_dev;
+};
+
+/*
+ * Callback for leaf to make a root request. Arguments are: parent device, 
parent cookie, req,
+ * and arg.
+ */
+typedef int (*xrt_subdev_root_cb_t)(struct device *, void *, u32, void *);
+int xrt_subdev_root_request(struct platform_device *self, u32 cmd, void *arg);
+
+/*
+ * Defines physical function (MPF / UPF) specific operations
+ * needed in common root driver.
+ */
+struct xroot_physical_function_callback {
+   void (*xpc_hot_reset)(struct pci_dev *pdev);
+};
+
+int xroot_probe(struct pci_dev *pdev, struct xroot_physical_function_callback 
*cb, void **root);
+void xroot_remove(void *root);
+bool xroot_wait_for_bringup(void *root);
+int xroot_add_vsec_node(void 

[PATCH V4 XRT Alveo 08/20] fpga: xrt: platform driver infrastructure

2021-03-23 Thread Lizhi Hou
Infrastructure code providing APIs for managing leaf driver instance
groups, facilitating inter-leaf driver calls and root calls.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/lib/subdev.c | 865 ++
 1 file changed, 865 insertions(+)
 create mode 100644 drivers/fpga/xrt/lib/subdev.c

diff --git a/drivers/fpga/xrt/lib/subdev.c b/drivers/fpga/xrt/lib/subdev.c
new file mode 100644
index ..6428b183fee3
--- /dev/null
+++ b/drivers/fpga/xrt/lib/subdev.c
@@ -0,0 +1,865 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#include 
+#include 
+#include 
+#include "xleaf.h"
+#include "subdev_pool.h"
+#include "lib-drv.h"
+#include "metadata.h"
+
+#define IS_ROOT_DEV(dev) ((dev)->bus == _bus_type)
+static inline struct device *find_root(struct platform_device *pdev)
+{
+   struct device *d = DEV(pdev);
+
+   while (!IS_ROOT_DEV(d))
+   d = d->parent;
+   return d;
+}
+
+/*
+ * It represents a holder of a subdev. One holder can repeatedly hold a subdev
+ * as long as there is a unhold corresponding to a hold.
+ */
+struct xrt_subdev_holder {
+   struct list_head xsh_holder_list;
+   struct device *xsh_holder;
+   int xsh_count;
+   struct kref xsh_kref;
+};
+
+/*
+ * It represents a specific instance of platform driver for a subdev, which
+ * provides services to its clients (another subdev driver or root driver).
+ */
+struct xrt_subdev {
+   struct list_head xs_dev_list;
+   struct list_head xs_holder_list;
+   enum xrt_subdev_id xs_id;   /* type of subdev */
+   struct platform_device *xs_pdev;/* a particular subdev inst */
+   struct completion xs_holder_comp;
+};
+
+static struct xrt_subdev *xrt_subdev_alloc(void)
+{
+   struct xrt_subdev *sdev = kzalloc(sizeof(*sdev), GFP_KERNEL);
+
+   if (!sdev)
+   return NULL;
+
+   INIT_LIST_HEAD(>xs_dev_list);
+   INIT_LIST_HEAD(>xs_holder_list);
+   init_completion(>xs_holder_comp);
+   return sdev;
+}
+
+static void xrt_subdev_free(struct xrt_subdev *sdev)
+{
+   kfree(sdev);
+}
+
+int xrt_subdev_root_request(struct platform_device *self, u32 cmd, void *arg)
+{
+   struct device *dev = DEV(self);
+   struct xrt_subdev_platdata *pdata = DEV_PDATA(self);
+
+   WARN_ON(!pdata->xsp_root_cb);
+   return (*pdata->xsp_root_cb)(dev->parent, pdata->xsp_root_cb_arg, cmd, 
arg);
+}
+
+/*
+ * Subdev common sysfs nodes.
+ */
+static ssize_t holders_show(struct device *dev, struct device_attribute *attr, 
char *buf)
+{
+   ssize_t len;
+   struct platform_device *pdev = to_platform_device(dev);
+   struct xrt_root_get_holders holders = { pdev, buf, 1024 };
+
+   len = xrt_subdev_root_request(pdev, XRT_ROOT_GET_LEAF_HOLDERS, 
);
+   if (len >= holders.xpigh_holder_buf_len)
+   return len;
+   buf[len] = '\n';
+   return len + 1;
+}
+static DEVICE_ATTR_RO(holders);
+
+static struct attribute *xrt_subdev_attrs[] = {
+   _attr_holders.attr,
+   NULL,
+};
+
+static ssize_t metadata_output(struct file *filp, struct kobject *kobj,
+  struct bin_attribute *attr, char *buf, loff_t 
off, size_t count)
+{
+   struct device *dev = kobj_to_dev(kobj);
+   struct platform_device *pdev = to_platform_device(dev);
+   struct xrt_subdev_platdata *pdata = DEV_PDATA(pdev);
+   unsigned char *blob;
+   unsigned long  size;
+   ssize_t ret = 0;
+
+   blob = pdata->xsp_dtb;
+   size = xrt_md_size(dev, blob);
+   if (size == XRT_MD_INVALID_LENGTH) {
+   ret = -EINVAL;
+   goto failed;
+   }
+
+   if (off >= size)
+   goto failed;
+
+   if (off + count > size)
+   count = size - off;
+   memcpy(buf, blob + off, count);
+
+   ret = count;
+failed:
+   return ret;
+}
+
+static struct bin_attribute meta_data_attr = {
+   .attr = {
+   .name = "metadata",
+   .mode = 0400
+   },
+   .read = metadata_output,
+   .size = 0
+};
+
+static struct bin_attribute  *xrt_subdev_bin_attrs[] = {
+   _data_attr,
+   NULL,
+};
+
+static const struct attribute_group xrt_subdev_attrgroup = {
+   .attrs = xrt_subdev_attrs,
+   .bin_attrs = xrt_subdev_bin_attrs,
+};
+
+/*
+ * Given the device metadata, parse it to get IO ranges and construct
+ * resource array.
+ */
+static int
+xrt_subdev_getres(struct device *parent, enum xrt_subdev_id id,
+ char *dtb, struct resource **res, int *res_num)
+{
+   struct xrt_subdev_platdata *pdata;
+   struct resource *pci_res = NULL;
+   const u64 *bar_range;
+   const u32 *bar_idx;
+   char *ep_name = NULL, *regmap = NULL;
+   uint bar;
+   int count1 = 0, count2 = 0, ret;
+
+   if (!dtb)
+   

[PATCH V4 XRT Alveo 04/20] fpga: xrt: xrt-lib platform driver manager

2021-03-23 Thread Lizhi Hou
xrt-lib kernel module infrastructure code to register and manage all
leaf driver modules.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/subdev_id.h |  38 
 drivers/fpga/xrt/include/xleaf.h | 264 +
 drivers/fpga/xrt/lib/lib-drv.c   | 277 +++
 drivers/fpga/xrt/lib/lib-drv.h   |  17 ++
 4 files changed, 596 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/subdev_id.h
 create mode 100644 drivers/fpga/xrt/include/xleaf.h
 create mode 100644 drivers/fpga/xrt/lib/lib-drv.c
 create mode 100644 drivers/fpga/xrt/lib/lib-drv.h

diff --git a/drivers/fpga/xrt/include/subdev_id.h 
b/drivers/fpga/xrt/include/subdev_id.h
new file mode 100644
index ..42fbd6f5e80a
--- /dev/null
+++ b/drivers/fpga/xrt/include/subdev_id.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#ifndef _XRT_SUBDEV_ID_H_
+#define _XRT_SUBDEV_ID_H_
+
+/*
+ * Every subdev driver has an ID for others to refer to it. There can be 
multiple number of
+ * instances of a subdev driver. A  tuple is a 
unique identification
+ * of a specific instance of a subdev driver.
+ */
+enum xrt_subdev_id {
+   XRT_SUBDEV_GRP = 0,
+   XRT_SUBDEV_VSEC = 1,
+   XRT_SUBDEV_VSEC_GOLDEN = 2,
+   XRT_SUBDEV_DEVCTL = 3,
+   XRT_SUBDEV_AXIGATE = 4,
+   XRT_SUBDEV_ICAP = 5,
+   XRT_SUBDEV_TEST = 6,
+   XRT_SUBDEV_MGMT_MAIN = 7,
+   XRT_SUBDEV_QSPI = 8,
+   XRT_SUBDEV_MAILBOX = 9,
+   XRT_SUBDEV_CMC = 10,
+   XRT_SUBDEV_CALIB = 11,
+   XRT_SUBDEV_CLKFREQ = 12,
+   XRT_SUBDEV_CLOCK = 13,
+   XRT_SUBDEV_SRSR = 14,
+   XRT_SUBDEV_UCS = 15,
+   XRT_SUBDEV_NUM = 16, /* Total number of subdevs. */
+   XRT_ROOT = -1, /* Special ID for root driver. */
+};
+
+#endif /* _XRT_SUBDEV_ID_H_ */
diff --git a/drivers/fpga/xrt/include/xleaf.h b/drivers/fpga/xrt/include/xleaf.h
new file mode 100644
index ..acb500df04b0
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf.h
@@ -0,0 +1,264 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *Cheng Zhen 
+ *Sonal Santan 
+ */
+
+#ifndef _XRT_XLEAF_H_
+#define _XRT_XLEAF_H_
+
+#include 
+#include 
+#include 
+#include "subdev_id.h"
+#include "xroot.h"
+#include "events.h"
+
+/* All subdev drivers should use below common routines to print out msg. */
+#define DEV(pdev)  (&(pdev)->dev)
+#define DEV_PDATA(pdev)\
+   ((struct xrt_subdev_platdata *)dev_get_platdata(DEV(pdev)))
+#define DEV_DRVDATA(pdev)  \
+   ((struct xrt_subdev_drvdata *)  \
+   platform_get_device_id(pdev)->driver_data)
+#define FMT_PRT(prt_fn, pdev, fmt, args...)\
+   ({typeof(pdev) (_pdev) = (pdev);\
+   prt_fn(DEV(_pdev), "%s %s: " fmt,   \
+   DEV_PDATA(_pdev)->xsp_root_name, __func__, ##args); })
+#define xrt_err(pdev, fmt, args...) FMT_PRT(dev_err, pdev, fmt, ##args)
+#define xrt_warn(pdev, fmt, args...) FMT_PRT(dev_warn, pdev, fmt, ##args)
+#define xrt_info(pdev, fmt, args...) FMT_PRT(dev_info, pdev, fmt, ##args)
+#define xrt_dbg(pdev, fmt, args...) FMT_PRT(dev_dbg, pdev, fmt, ##args)
+
+enum {
+   /* Starting cmd for common leaf cmd implemented by all leaves. */
+   XRT_XLEAF_COMMON_BASE = 0,
+   /* Starting cmd for leaves' specific leaf cmds. */
+   XRT_XLEAF_CUSTOM_BASE = 64,
+};
+
+enum xrt_xleaf_common_leaf_cmd {
+   XRT_XLEAF_EVENT = XRT_XLEAF_COMMON_BASE,
+};
+
+/*
+ * If populated by subdev driver, infra will handle the mechanics of
+ * char device (un)registration.
+ */
+enum xrt_subdev_file_mode {
+   /* Infra create cdev, default file name */
+   XRT_SUBDEV_FILE_DEFAULT = 0,
+   /* Infra create cdev, need to encode inst num in file name */
+   XRT_SUBDEV_FILE_MULTI_INST,
+   /* No auto creation of cdev by infra, leaf handles it by itself */
+   XRT_SUBDEV_FILE_NO_AUTO,
+};
+
+struct xrt_subdev_file_ops {
+   const struct file_operations xsf_ops;
+   dev_t xsf_dev_t;
+   const char *xsf_dev_name;
+   enum xrt_subdev_file_mode xsf_mode;
+};
+
+/*
+ * Subdev driver callbacks populated by subdev driver.
+ */
+struct xrt_subdev_drv_ops {
+   /*
+* Per driver instance callback. The pdev points to the instance.
+* If defined, these are called by other leaf drivers.
+* Note that root driver may call into xsd_leaf_call of a group driver.
+*/
+   int (*xsd_leaf_call)(struct platform_device *pdev, u32 cmd, void *arg);
+};
+
+/*
+ * Defined and populated by subdev driver, exported as driver_data in
+ * struct platform_device_id.
+ */
+struct xrt_subdev_drvdata {
+   struct xrt_subdev_file_ops xsd_file_ops;
+   struct xrt_subdev_drv_ops 

[PATCH V4 XRT Alveo 05/20] fpga: xrt: group platform driver

2021-03-23 Thread Lizhi Hou
group driver that manages life cycle of a bunch of leaf driver instances
and bridges them with root.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/group.h |  25 +++
 drivers/fpga/xrt/lib/group.c | 286 +++
 2 files changed, 311 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/group.h
 create mode 100644 drivers/fpga/xrt/lib/group.c

diff --git a/drivers/fpga/xrt/include/group.h b/drivers/fpga/xrt/include/group.h
new file mode 100644
index ..09e9d03f53fe
--- /dev/null
+++ b/drivers/fpga/xrt/include/group.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#ifndef _XRT_GROUP_H_
+#define _XRT_GROUP_H_
+
+#include "xleaf.h"
+
+/*
+ * Group driver leaf calls.
+ */
+enum xrt_group_leaf_cmd {
+   XRT_GROUP_GET_LEAF = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h 
*/
+   XRT_GROUP_PUT_LEAF,
+   XRT_GROUP_INIT_CHILDREN,
+   XRT_GROUP_FINI_CHILDREN,
+   XRT_GROUP_TRIGGER_EVENT,
+};
+
+#endif /* _XRT_GROUP_H_ */
diff --git a/drivers/fpga/xrt/lib/group.c b/drivers/fpga/xrt/lib/group.c
new file mode 100644
index ..7b8716569641
--- /dev/null
+++ b/drivers/fpga/xrt/lib/group.c
@@ -0,0 +1,286 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA Group Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#include 
+#include 
+#include "xleaf.h"
+#include "subdev_pool.h"
+#include "group.h"
+#include "metadata.h"
+#include "lib-drv.h"
+
+#define XRT_GRP "xrt_group"
+
+struct xrt_group {
+   struct platform_device *pdev;
+   struct xrt_subdev_pool leaves;
+   bool leaves_created;
+   struct mutex lock; /* lock for group */
+};
+
+static int xrt_grp_root_cb(struct device *dev, void *parg,
+  enum xrt_root_cmd cmd, void *arg)
+{
+   int rc;
+   struct platform_device *pdev =
+   container_of(dev, struct platform_device, dev);
+   struct xrt_group *xg = (struct xrt_group *)parg;
+
+   switch (cmd) {
+   case XRT_ROOT_GET_LEAF_HOLDERS: {
+   struct xrt_root_get_holders *holders =
+   (struct xrt_root_get_holders *)arg;
+   rc = xrt_subdev_pool_get_holders(>leaves,
+holders->xpigh_pdev,
+holders->xpigh_holder_buf,
+holders->xpigh_holder_buf_len);
+   break;
+   }
+   default:
+   /* Forward parent call to root. */
+   rc = xrt_subdev_root_request(pdev, cmd, arg);
+   break;
+   }
+
+   return rc;
+}
+
+/*
+ * Cut subdev's dtb from group's dtb based on passed-in endpoint descriptor.
+ * Return the subdev's dtb through dtbp, if found.
+ */
+static int xrt_grp_cut_subdev_dtb(struct xrt_group *xg, struct 
xrt_subdev_endpoints *eps,
+ char *grp_dtb, char **dtbp)
+{
+   int ret, i, ep_count = 0;
+   char *dtb = NULL;
+
+   ret = xrt_md_create(DEV(xg->pdev), );
+   if (ret)
+   return ret;
+
+   for (i = 0; eps->xse_names[i].ep_name || eps->xse_names[i].regmap_name; 
i++) {
+   const char *ep_name = eps->xse_names[i].ep_name;
+   const char *reg_name = eps->xse_names[i].regmap_name;
+
+   if (!ep_name)
+   xrt_md_get_compatible_endpoint(DEV(xg->pdev), grp_dtb, 
reg_name, _name);
+   if (!ep_name)
+   continue;
+
+   ret = xrt_md_copy_endpoint(DEV(xg->pdev), dtb, grp_dtb, 
ep_name, reg_name, NULL);
+   if (ret)
+   continue;
+   xrt_md_del_endpoint(DEV(xg->pdev), grp_dtb, ep_name, reg_name);
+   ep_count++;
+   }
+   /* Found enough endpoints, return the subdev's dtb. */
+   if (ep_count >= eps->xse_min_ep) {
+   *dtbp = dtb;
+   return 0;
+   }
+
+   /* Cleanup - Restore all endpoints that has been deleted, if any. */
+   if (ep_count > 0) {
+   xrt_md_copy_endpoint(DEV(xg->pdev), grp_dtb, dtb,
+XRT_MD_NODE_ENDPOINTS, NULL, NULL);
+   }
+   vfree(dtb);
+   *dtbp = NULL;
+   return 0;
+}
+
+static int xrt_grp_create_leaves(struct xrt_group *xg)
+{
+   struct xrt_subdev_platdata *pdata = DEV_PDATA(xg->pdev);
+   struct xrt_subdev_endpoints *eps = NULL;
+   int ret = 0, failed = 0;
+   enum xrt_subdev_id did;
+   char *grp_dtb = NULL;
+   unsigned long mlen;
+
+   if (!pdata)
+   return -EINVAL;
+
+   mlen = xrt_md_size(DEV(xg->pdev), pdata->xsp_dtb);
+   if (mlen == XRT_MD_INVALID_LENGTH) {
+   xrt_err(xg->pdev, "invalid dtb, len 

[PATCH V4 XRT Alveo 02/20] fpga: xrt: driver metadata helper functions

2021-03-23 Thread Lizhi Hou
XRT drivers use device tree as metadata format to discover HW subsystems
behind PCIe BAR. Thus libfdt functions are called for the driver to parse
device tree blob.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/metadata.h  | 233 
 drivers/fpga/xrt/metadata/metadata.c | 545 +++
 2 files changed, 778 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/metadata.h
 create mode 100644 drivers/fpga/xrt/metadata/metadata.c

diff --git a/drivers/fpga/xrt/include/metadata.h 
b/drivers/fpga/xrt/include/metadata.h
new file mode 100644
index ..479e47960c61
--- /dev/null
+++ b/drivers/fpga/xrt/include/metadata.h
@@ -0,0 +1,233 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *  Lizhi Hou 
+ */
+
+#ifndef _XRT_METADATA_H
+#define _XRT_METADATA_H
+
+#include 
+#include 
+#include 
+
+#define XRT_MD_INVALID_LENGTH (~0UL)
+
+/* metadata properties */
+#define XRT_MD_PROP_BAR_IDX "pcie_bar_mapping"
+#define XRT_MD_PROP_COMPATIBLE "compatible"
+#define XRT_MD_PROP_HWICAP "axi_hwicap"
+#define XRT_MD_PROP_INTERFACE_UUID "interface_uuid"
+#define XRT_MD_PROP_INTERRUPTS "interrupts"
+#define XRT_MD_PROP_IO_OFFSET "reg"
+#define XRT_MD_PROP_LOGIC_UUID "logic_uuid"
+#define XRT_MD_PROP_PDI_CONFIG "pdi_config_mem"
+#define XRT_MD_PROP_PF_NUM "pcie_physical_function"
+#define XRT_MD_PROP_VERSION_MAJOR "firmware_version_major"
+
+/* non IP nodes */
+#define XRT_MD_NODE_ENDPOINTS "addressable_endpoints"
+#define XRT_MD_NODE_FIRMWARE "firmware"
+#define XRT_MD_NODE_INTERFACES "interfaces"
+#define XRT_MD_NODE_PARTITION_INFO "partition_info"
+
+/*
+ * IP nodes
+ * AF:  AXI Firewall
+ * CMC: Card Management Controller
+ * ERT: Embedded Runtime
+ * PLP: Provider Reconfigurable Partition
+ * ULP: User Reconfigurable Partition
+ */
+#define XRT_MD_NODE_ADDR_TRANSLATOR "ep_remap_data_c2h_00"
+#define XRT_MD_NODE_AF_BLP_CTRL_MGMT "ep_firewall_blp_ctrl_mgmt_00"
+#define XRT_MD_NODE_AF_BLP_CTRL_USER "ep_firewall_blp_ctrl_user_00"
+#define XRT_MD_NODE_AF_CTRL_DEBUG "ep_firewall_ctrl_debug_00"
+#define XRT_MD_NODE_AF_CTRL_MGMT "ep_firewall_ctrl_mgmt_00"
+#define XRT_MD_NODE_AF_CTRL_USER "ep_firewall_ctrl_user_00"
+#define XRT_MD_NODE_AF_DATA_C2H "ep_firewall_data_c2h_00"
+#define XRT_MD_NODE_AF_DATA_H2C "ep_firewall_data_h2c_00"
+#define XRT_MD_NODE_AF_DATA_M2M "ep_firewall_data_m2m_00"
+#define XRT_MD_NODE_AF_DATA_P2P "ep_firewall_data_p2p_00"
+#define XRT_MD_NODE_CLKFREQ_HBM "ep_freq_cnt_aclk_hbm_00"
+#define XRT_MD_NODE_CLKFREQ_K1 "ep_freq_cnt_aclk_kernel_00"
+#define XRT_MD_NODE_CLKFREQ_K2 "ep_freq_cnt_aclk_kernel_01"
+#define XRT_MD_NODE_CLK_KERNEL1 "ep_aclk_kernel_00"
+#define XRT_MD_NODE_CLK_KERNEL2 "ep_aclk_kernel_01"
+#define XRT_MD_NODE_CLK_KERNEL3 "ep_aclk_hbm_00"
+#define XRT_MD_NODE_CLK_SHUTDOWN "ep_aclk_shutdown_00"
+#define XRT_MD_NODE_CMC_FW_MEM "ep_cmc_firmware_mem_00"
+#define XRT_MD_NODE_CMC_MUTEX "ep_cmc_mutex_00"
+#define XRT_MD_NODE_CMC_REG "ep_cmc_regmap_00"
+#define XRT_MD_NODE_CMC_RESET "ep_cmc_reset_00"
+#define XRT_MD_NODE_DDR_CALIB "ep_ddr_mem_calib_00"
+#define XRT_MD_NODE_DDR4_RESET_GATE "ep_ddr_mem_srsr_gate_00"
+#define XRT_MD_NODE_ERT_BASE "ep_ert_base_address_00"
+#define XRT_MD_NODE_ERT_CQ_MGMT "ep_ert_command_queue_mgmt_00"
+#define XRT_MD_NODE_ERT_CQ_USER "ep_ert_command_queue_user_00"
+#define XRT_MD_NODE_ERT_FW_MEM "ep_ert_firmware_mem_00"
+#define XRT_MD_NODE_ERT_RESET "ep_ert_reset_00"
+#define XRT_MD_NODE_ERT_SCHED "ep_ert_sched_00"
+#define XRT_MD_NODE_FLASH "ep_card_flash_program_00"
+#define XRT_MD_NODE_FPGA_CONFIG "ep_fpga_configuration_00"
+#define XRT_MD_NODE_GAPPING "ep_gapping_demand_00"
+#define XRT_MD_NODE_GATE_PLP "ep_pr_isolate_plp_00"
+#define XRT_MD_NODE_GATE_ULP "ep_pr_isolate_ulp_00"
+#define XRT_MD_NODE_KDMA_CTRL "ep_kdma_ctrl_00"
+#define XRT_MD_NODE_MAILBOX_MGMT "ep_mailbox_mgmt_00"
+#define XRT_MD_NODE_MAILBOX_USER "ep_mailbox_user_00"
+#define XRT_MD_NODE_MAILBOX_XRT "ep_mailbox_user_to_ert_00"
+#define XRT_MD_NODE_MSIX "ep_msix_00"
+#define XRT_MD_NODE_P2P "ep_p2p_00"
+#define XRT_MD_NODE_PCIE_MON "ep_pcie_link_mon_00"
+#define XRT_MD_NODE_PMC_INTR   "ep_pmc_intr_00"
+#define XRT_MD_NODE_PMC_MUX"ep_pmc_mux_00"
+#define XRT_MD_NODE_QDMA "ep_qdma_00"
+#define XRT_MD_NODE_QDMA4 "ep_qdma4_00"
+#define XRT_MD_NODE_REMAP_P2P "ep_remap_p2p_00"
+#define XRT_MD_NODE_STM "ep_stream_traffic_manager_00"
+#define XRT_MD_NODE_STM4 "ep_stream_traffic_manager4_00"
+#define XRT_MD_NODE_SYSMON "ep_cmp_sysmon_00"
+#define XRT_MD_NODE_XDMA "ep_xdma_00"
+#define XRT_MD_NODE_XVC_PUB "ep_debug_bscan_user_00"
+#define XRT_MD_NODE_XVC_PRI "ep_debug_bscan_mgmt_00"
+#define XRT_MD_NODE_UCS_CONTROL_STATUS "ep_ucs_control_status_00"
+
+/* endpoint regmaps */
+#define XRT_MD_REGMAP_DDR_SRSR "drv_ddr_srsr"
+#define XRT_MD_REGMAP_CLKFREQ "freq_cnt"
+
+/* driver defined endpoints */
+#define XRT_MD_NODE_BLP_ROM "drv_ep_blp_rom_00"

[PATCH V4 XRT Alveo 03/20] fpga: xrt: xclbin file helper functions

2021-03-23 Thread Lizhi Hou
Alveo FPGA firmware and partial reconfigure file are in xclbin format. This
code enumerates and extracts sections from xclbin files. xclbin.h is cross
platform and used across all platforms and OS.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xclbin-helper.h |  48 +++
 drivers/fpga/xrt/lib/xclbin.c| 369 
 include/uapi/linux/xrt/xclbin.h  | 409 +++
 3 files changed, 826 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xclbin-helper.h
 create mode 100644 drivers/fpga/xrt/lib/xclbin.c
 create mode 100644 include/uapi/linux/xrt/xclbin.h

diff --git a/drivers/fpga/xrt/include/xclbin-helper.h 
b/drivers/fpga/xrt/include/xclbin-helper.h
new file mode 100644
index ..382b1de97b0a
--- /dev/null
+++ b/drivers/fpga/xrt/include/xclbin-helper.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *David Zhang 
+ *Sonal Santan 
+ */
+
+#ifndef _XCLBIN_HELPER_H_
+#define _XCLBIN_HELPER_H_
+
+#include 
+#include 
+#include 
+
+#define XCLBIN_VERSION2"xclbin2"
+#define XCLBIN_HWICAP_BITFILE_BUF_SZ 1024
+#define XCLBIN_MAX_SIZE (1024 * 1024 * 1024) /* Assuming xclbin <= 1G, always 
*/
+
+enum axlf_section_kind;
+struct axlf;
+
+/**
+ * Bitstream header information as defined by Xilinx tools.
+ * Please note that this struct definition is not owned by the driver.
+ */
+struct xclbin_bit_head_info {
+   u32 header_length;  /* Length of header in 32 bit words */
+   u32 bitstream_length;   /* Length of bitstream to read in bytes 
*/
+   const unchar *design_name;  /* Design name get from bitstream */
+   const unchar *part_name;/* Part name read from bitstream */
+   const unchar *date; /* Date read from bitstream header */
+   const unchar *time; /* Bitstream creation time */
+   u32 magic_length;   /* Length of the magic numbers */
+   const unchar *version;  /* Version string */
+};
+
+/* caller must free the allocated memory for **data. len could be NULL. */
+int xrt_xclbin_get_section(struct device *dev,  const struct axlf *xclbin,
+  enum axlf_section_kind kind, void **data,
+  uint64_t *len);
+int xrt_xclbin_get_metadata(struct device *dev, const struct axlf *xclbin, 
char **dtb);
+int xrt_xclbin_parse_bitstream_header(struct device *dev, const unchar *data,
+ u32 size, struct xclbin_bit_head_info 
*head_info);
+const char *xrt_clock_type2epname(enum XCLBIN_CLOCK_TYPE type);
+
+#endif /* _XCLBIN_HELPER_H_ */
diff --git a/drivers/fpga/xrt/lib/xclbin.c b/drivers/fpga/xrt/lib/xclbin.c
new file mode 100644
index ..31b363c014a3
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xclbin.c
@@ -0,0 +1,369 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA Driver XCLBIN parser
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors: David Zhang 
+ */
+
+#include 
+#include 
+#include 
+#include "xclbin-helper.h"
+#include "metadata.h"
+
+/* Used for parsing bitstream header */
+#define BITSTREAM_EVEN_MAGIC_BYTE  0x0f
+#define BITSTREAM_ODD_MAGIC_BYTE   0xf0
+
+static int xrt_xclbin_get_section_hdr(const struct axlf *xclbin,
+ enum axlf_section_kind kind,
+ const struct axlf_section_header **header)
+{
+   const struct axlf_section_header *phead = NULL;
+   u64 xclbin_len;
+   int i;
+
+   *header = NULL;
+   for (i = 0; i < xclbin->header.num_sections; i++) {
+   if (xclbin->sections[i].section_kind == kind) {
+   phead = >sections[i];
+   break;
+   }
+   }
+
+   if (!phead)
+   return -ENOENT;
+
+   xclbin_len = xclbin->header.length;
+   if (xclbin_len > XCLBIN_MAX_SIZE ||
+   phead->section_offset + phead->section_size > xclbin_len)
+   return -EINVAL;
+
+   *header = phead;
+   return 0;
+}
+
+static int xrt_xclbin_section_info(const struct axlf *xclbin,
+  enum axlf_section_kind kind,
+  u64 *offset, u64 *size)
+{
+   const struct axlf_section_header *mem_header = NULL;
+   int rc;
+
+   rc = xrt_xclbin_get_section_hdr(xclbin, kind, _header);
+   if (rc)
+   return rc;
+
+   *offset = mem_header->section_offset;
+   *size = mem_header->section_size;
+
+   return 0;
+}
+
+/* caller must free the allocated memory for **data */
+int xrt_xclbin_get_section(struct device *dev,
+  const struct axlf *buf,
+  enum axlf_section_kind kind,
+  void **data, u64 *len)
+{
+   const struct axlf *xclbin = 

[PATCH V4 XRT Alveo 01/20] Documentation: fpga: Add a document describing XRT Alveo drivers

2021-03-23 Thread Lizhi Hou
Describe XRT driver architecture and provide basic overview of
Xilinx Alveo platform.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 Documentation/fpga/index.rst |   1 +
 Documentation/fpga/xrt.rst   | 844 +++
 2 files changed, 845 insertions(+)
 create mode 100644 Documentation/fpga/xrt.rst

diff --git a/Documentation/fpga/index.rst b/Documentation/fpga/index.rst
index f80f95667ca2..30134357b70d 100644
--- a/Documentation/fpga/index.rst
+++ b/Documentation/fpga/index.rst
@@ -8,6 +8,7 @@ fpga
 :maxdepth: 1
 
 dfl
+xrt
 
 .. only::  subproject and html
 
diff --git a/Documentation/fpga/xrt.rst b/Documentation/fpga/xrt.rst
new file mode 100644
index ..0f7977464270
--- /dev/null
+++ b/Documentation/fpga/xrt.rst
@@ -0,0 +1,844 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==
+XRTV2 Linux Kernel Driver Overview
+==
+
+Authors:
+
+* Sonal Santan 
+* Max Zhen 
+* Lizhi Hou 
+
+XRTV2 drivers are second generation `XRT `_
+drivers which support `Alveo 
`_
+PCIe platforms from Xilinx.
+
+XRTV2 drivers support *subsystem* style data driven platforms where driver's
+configuration and behavior is determined by meta data provided by the platform
+(in *device tree* format). Primary management physical function (MPF) driver
+is called **xmgmt**. Primary user physical function (UPF) driver is called
+**xuser** and is under development. xrt driver framework and HW subsystem
+drivers are packaged into a library module called **xrt-lib**, which is
+shared by **xmgmt** and **xuser** (under development). The xrt driver framework
+implements a pseudo-bus which is used to discover HW subsystems and facilitate
+inter HW subsystem interaction.
+
+Driver Modules
+==
+
+xrt-lib.ko
+--
+
+Repository of all subsystem drivers and pure software modules that can 
potentially
+be shared between xmgmt and xuser. All these drivers are structured as Linux
+*platform driver* and are instantiated by xmgmt (or xuser under development) 
based
+on meta data associated with the hardware. The metadata is in the form of a 
device
+tree as mentioned before. Each platform driver statically defines a subsystem 
node
+array by using node name or a string in its ``compatible`` property. And this
+array is eventually translated to IOMEM resources of the platform device.
+
+The xrt-lib core infrastructure provides hooks to platform drivers for device 
node
+management, user file operations and ioctl callbacks. The core infrastructure 
also
+provides pseudo-bus functionality for platform driver registration, discovery 
and
+inter platform driver ioctl calls.
+
+.. note::
+   See code in ``include/xleaf.h``
+
+
+xmgmt.ko
+
+
+The xmgmt driver is a PCIe device driver driving MPF found on Xilinx's Alveo
+PCIE device. It consists of one *root* driver, one or more *group* drivers
+and one or more *xleaf* drivers. The root and MPF specific xleaf drivers are
+in xmgmt.ko. The group driver and other xleaf drivers are in xrt-lib.ko.
+
+The instantiation of specific group driver or xleaf driver is completely data
+driven based on meta data (mostly in device tree format) found through VSEC
+capability and inside firmware files, such as platform xsabin or user xclbin 
file.
+The root driver manages the life cycle of multiple group drivers, which, in 
turn,
+manages multiple xleaf drivers. This allows a single set of drivers to support
+all kinds of subsystems exposed by different shells. The difference among all
+these subsystems will be handled in xleaf drivers with root and group drivers
+being part of the infrastructure and provide common services for all leaves
+found on all platforms.
+
+The driver object model looks like the following::
+
++---+
+|   xroot   |
++-+-+
+  |
+  +---+---+
+  |   |
+  v   v
++---+  +---+
+|   group   |...   |   group   |
++-+-+  +--++
+  |   |
+  |   |
++-+++-++
+|  ||  |
+v  vv  v
++---+  +---++---+  +---+
+| xleaf |..| xleaf || xleaf |..| xleaf |
++---+  +---++---+  +---+
+
+As an example for Xilinx Alveo U50 before user xclbin download, the tree
+looks like the following::
+
++---+
+|   xmgmt   |
++-+-+
+  |
+

[PATCH V4 XRT Alveo 00/20] XRT Alveo driver overview

2021-03-23 Thread Lizhi Hou
Hello,

This is V4 of patch series which adds management physical function driver
for Xilinx Alveo PCIe accelerator cards.
https://www.xilinx.com/products/boards-and-kits/alveo.html

This driver is part of Xilinx Runtime (XRT) open source stack.
The V4 patch series do not include bus_type change as suggested before.
The bus_type change will come with v5 patch series.

XILINX ALVEO PLATFORM ARCHITECTURE

Alveo PCIe FPGA based platforms have a static *shell* partition and a
partial re-configurable *user* partition. The shell partition is
automatically loaded from flash when host is booted and PCIe is enumerated
by BIOS. Shell cannot be changed till the next cold reboot. The shell
exposes two PCIe physical functions:

1. management physical function
2. user physical function

The patch series includes Documentation/xrt.rst which describes Alveo
platform, XRT driver architecture and deployment model in more detail.

Users compile their high level design in C/C++/OpenCL or RTL into FPGA
image using Vitis tools.
https://www.xilinx.com/products/design-tools/vitis/vitis-platform.html

The compiled image is packaged as xclbin which contains partial bitstream
for the user partition and necessary metadata. Users can dynamically swap
the image running on the user partition in order to switch between
different workloads by loading different xclbins.

XRT DRIVERS FOR XILINX ALVEO

XRT Linux kernel driver *xmgmt* binds to management physical function of
Alveo platform. The modular driver framework is organized into several
platform drivers which primarily handle the following functionality:

1.  Loading firmware container also called xsabin at driver attach time
2.  Loading of user compiled xclbin with FPGA Manager integration
3.  Clock scaling of image running on user partition
4.  In-band sensors: temp, voltage, power, etc.
5.  Device reset and rescan

The platform drivers are packaged into *xrt-lib* helper module with well
defined interfaces. The module provides a pseudo-bus implementation for the
platform drivers. More details on the driver model can be found in
Documentation/xrt.rst.

User physical function driver is not included in this patch series.

LIBFDT REQUIREMENT

XRT driver infrastructure uses Device Tree as a metadata format to discover
HW subsystems in the Alveo PCIe device. The Device Tree schema used by XRT
is documented in Documentation/xrt.rst.

TESTING AND VALIDATION

xmgmt driver can be tested with full XRT open source stack which includes
user space libraries, board utilities and (out of tree) first generation
user physical function driver xocl. XRT open source runtime stack is
available at https://github.com/Xilinx/XRT

Complete documentation for XRT open source stack including sections on
Alveo/XRT security and platform architecture can be found here:

https://xilinx.github.io/XRT/master/html/index.html
https://xilinx.github.io/XRT/master/html/security.html
https://xilinx.github.io/XRT/master/html/platforms_partitions.html

Changes since v3:
- Leaf drivers use regmap-mmio to access hardware registers.
- Renamed driver module: xmgmt.ko -> xrt-mgmt.ko
- Renamed files: calib.[c|h] -> ddr_calibration.[c|h],
 lib/main.[c|h] -> lib/lib-drv.[c|h],
 mgmt/main-impl.h - > mgmt/xmgnt.h
- Updated code base to include v3 code review comments.

Changes since v2:
- Streamlined the driver framework into *xleaf*, *group* and *xroot*
- Updated documentation to show the driver model with examples
- Addressed kernel test robot errors
- Added a selftest for basic driver framework
- Documented device tree schema
- Removed need to export libfdt symbols

Changes since v1:
- Updated the driver to use fpga_region and fpga_bridge for FPGA
  programming
- Dropped platform drivers not related to PR programming to focus on XRT
  core framework
- Updated Documentation/fpga/xrt.rst with information on XRT core framework
- Addressed checkpatch issues
- Dropped xrt- prefix from some header files

For reference V3 version of patch series can be found here:

https://lore.kernel.org/lkml/20210218064019.29189-1-liz...@xilinx.com
https://lore.kernel.org/lkml/20210218064019.29189-2-liz...@xilinx.com
https://lore.kernel.org/lkml/20210218064019.29189-3-liz...@xilinx.com
https://lore.kernel.org/lkml/20210218064019.29189-4-liz...@xilinx.com
https://lore.kernel.org/lkml/20210218064019.29189-5-liz...@xilinx.com
https://lore.kernel.org/lkml/20210218064019.29189-6-liz...@xilinx.com
https://lore.kernel.org/lkml/20210218064019.29189-7-liz...@xilinx.com
https://lore.kernel.org/lkml/20210218064019.29189-8-liz...@xilinx.com
https://lore.kernel.org/lkml/20210218064019.29189-9-liz...@xilinx.com
https://lore.kernel.org/lkml/20210218064019.29189-10-liz...@xilinx.com
https://lore.kernel.org/lkml/20210218064019.29189-11-liz...@xilinx.com
https://lore.kernel.org/lkml/20210218064019.29189-12-liz...@xilinx.com
https://lore.kernel.org/lkml/20210218064019.29189-13-liz...@xilinx.com

Re: [PATCH v2 03/18] ovl: stack miscattr ops

2021-03-23 Thread Al Viro
On Wed, Mar 24, 2021 at 05:09:59AM +, Al Viro wrote:
> On Mon, Mar 22, 2021 at 03:49:01PM +0100, Miklos Szeredi wrote:

> Umm...  No equivalents of
> /*  
>  * Prevent copy up if immutable and has no CAP_LINUX_IMMUTABLE
>  * capability.
>  */ 
> ret = -EPERM;
> if (!ovl_has_upperdata(inode) && IS_IMMUTABLE(inode) &&
> !capable(CAP_LINUX_IMMUTABLE))
> goto unlock;
> 

Nevermind, you take care of that in the caller...


Re: [PATCH v2 03/18] ovl: stack miscattr ops

2021-03-23 Thread Al Viro
On Mon, Mar 22, 2021 at 03:49:01PM +0100, Miklos Szeredi wrote:

> +int ovl_miscattr_set(struct user_namespace *mnt_userns,
> +  struct dentry *dentry, struct miscattr *ma)
> +{
> + struct inode *inode = d_inode(dentry);
> + struct dentry *upperdentry;
> + const struct cred *old_cred;
> + int err;
> +
> + err = ovl_want_write(dentry);
> + if (err)
> + goto out;
> +
> + err = ovl_copy_up(dentry);
> + if (!err) {
> + upperdentry = ovl_dentry_upper(dentry);
> +
> + old_cred = ovl_override_creds(inode->i_sb);
> + err = ovl_security_miscattr(dentry, ma, true);
> + if (!err)
> + err = vfs_miscattr_set(_user_ns, upperdentry, ma);
> + revert_creds(old_cred);
> + ovl_copyflags(ovl_inode_real(inode), inode);
> + }
> + ovl_drop_write(dentry);
> +out:
> + return err;
> +}

Umm...  No equivalents of
/*  
 * Prevent copy up if immutable and has no CAP_LINUX_IMMUTABLE
 * capability.
 */ 
ret = -EPERM;
if (!ovl_has_upperdata(inode) && IS_IMMUTABLE(inode) &&
!capable(CAP_LINUX_IMMUTABLE))
goto unlock;

ret = ovl_maybe_copy_up(file_dentry(file), O_WRONLY);
if (ret)
goto unlock;
in the current tree?


Re: [PATCH v3 3/8] extconn: Clean-up few drivers by using managed work init

2021-03-23 Thread Matti Vaittinen
Hello Chanwoo, Greg,

Thanks for the review.

On Wed, 2021-03-24 at 11:09 +0900, Chanwoo Choi wrote:
> Hi,
> 
> Need to fix the work as following:
> s/extconn/extcon
> 
> And I'd like you to use the more correct patch title like the
> following example:
> "extcon: Use resource-managed function for delayed work"

I think Greg merged this already. How should we handle this?

> @@ -112,7 +113,9 @@ static int gpio_extcon_probe(struct
> > platform_device *pdev)
> > if (ret < 0)
> > return ret;
> >  
> > -   INIT_DELAYED_WORK(>work, gpio_extcon_work);
> > +   ret = devm_delayed_work_autocancel(dev, >work,
> > gpio_extcon_work);
> > +   if (ret)
> > +   return ret;
> 
> Need to add the error log as following:
>   if (ret) {
>   dev_err(dev, "Failed to initialize delayed_work");
>   return ret;
>   }   

I could send incremental patch to Greg for this but it does not change
the commit message.

Best Regards
Matti Vaittinen




Re: [PATCH v31 4/4] scsi: ufs: Add HPB 2.0 support

2021-03-23 Thread Can Guo

On 2021-03-22 14:55, Daejun Park wrote:

This patch supports the HPB 2.0.

The HPB 2.0 supports read of varying sizes from 4KB to 512KB.
In the case of Read (<= 32KB) is supported as single HPB read.
In the case of Read (36KB ~ 512KB) is supported by as a combination of
write buffer command and HPB read command to deliver more PPN.
The write buffer commands may not be issued immediately due to busy 
tags.
To use HPB read more aggressively, the driver can requeue the write 
buffer

command. The requeue threshold is implemented as timeout and can be
modified with requeue_timeout_ms entry in sysfs.

Signed-off-by: Daejun Park 
---
 Documentation/ABI/testing/sysfs-driver-ufs |  47 +-
 drivers/scsi/ufs/ufs-sysfs.c   |   4 +
 drivers/scsi/ufs/ufs.h |   3 +-
 drivers/scsi/ufs/ufshcd.c  |  25 +-
 drivers/scsi/ufs/ufshcd.h  |   7 +
 drivers/scsi/ufs/ufshpb.c  | 626 +++--
 drivers/scsi/ufs/ufshpb.h  |  67 ++-
 7 files changed, 698 insertions(+), 81 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-driver-ufs
b/Documentation/ABI/testing/sysfs-driver-ufs
index 528bf89fc98b..419adf450b89 100644
--- a/Documentation/ABI/testing/sysfs-driver-ufs
+++ b/Documentation/ABI/testing/sysfs-driver-ufs
@@ -1253,14 +1253,14 @@ Description:This entry shows the number of
HPB pinned regions assigned to

The file is read only.

-What:  /sys/class/scsi_device/*/device/hpb_sysfs/hit_cnt
+What:  /sys/class/scsi_device/*/device/hpb_stat_sysfs/hit_cnt
 Date:  March 2021
 Contact:   Daejun Park 
 Description:	This entry shows the number of reads that changed to HPB 
read.


The file is read only.

-What:  /sys/class/scsi_device/*/device/hpb_sysfs/miss_cnt
+What:  /sys/class/scsi_device/*/device/hpb_stat_sysfs/miss_cnt
 Date:  March 2021
 Contact:   Daejun Park 
 Description:	This entry shows the number of reads that cannot be 
changed to

@@ -1268,7 +1268,7 @@ Description:  This entry shows the number of
reads that cannot be changed to

The file is read only.

-What:  /sys/class/scsi_device/*/device/hpb_sysfs/rb_noti_cnt
+What:  /sys/class/scsi_device/*/device/hpb_stat_sysfs/rb_noti_cnt
 Date:  March 2021
 Contact:   Daejun Park 
 Description:   This entry shows the number of response UPIUs that has
@@ -1276,7 +1276,7 @@ Description:  This entry shows the number of
response UPIUs that has

The file is read only.

-What:  /sys/class/scsi_device/*/device/hpb_sysfs/rb_active_cnt
+What:  /sys/class/scsi_device/*/device/hpb_stat_sysfs/rb_active_cnt
 Date:  March 2021
 Contact:   Daejun Park 
 Description:	This entry shows the number of active sub-regions 
recommended by

@@ -1284,7 +1284,7 @@ Description:  This entry shows the number of
active sub-regions recommended by

The file is read only.

-What:  /sys/class/scsi_device/*/device/hpb_sysfs/rb_inactive_cnt
+What:  /sys/class/scsi_device/*/device/hpb_stat_sysfs/rb_inactive_cnt
 Date:  March 2021
 Contact:   Daejun Park 
 Description:	This entry shows the number of inactive regions 
recommended by

@@ -1292,10 +1292,45 @@ Description:This entry shows the number of
inactive regions recommended by

The file is read only.

-What:  /sys/class/scsi_device/*/device/hpb_sysfs/map_req_cnt
+What:  /sys/class/scsi_device/*/device/hpb_stat_sysfs/map_req_cnt
 Date:  March 2021
 Contact:   Daejun Park 
 Description:   This entry shows the number of read buffer commands for
activating sub-regions recommended by response UPIUs.

The file is read only.
+
+What:  
/sys/class/scsi_device/*/device/hpb_param_sysfs/requeue_timeout_ms
+Date:  March 2021
+Contact:   Daejun Park 
+Description:	This entry shows the requeue timeout threshold for write 
buffer
+		command in ms. This value can be changed by writing proper integer 
to

+   this entry.
+
+What:  
/sys/bus/platform/drivers/ufshcd/*/attributes/max_data_size_hpb_single_cmd
+Date:  March 2021
+Contact:   Daejun Park 
+Description:	This entry shows the maximum HPB data size for using 
single HPB

+   command.
+
+   ===  
+   00h  4KB
+   01h  8KB
+   02h  12KB
+   ...
+   FFh  1024KB
+   ===  
+
+   The file is read only.
+
+What:  /sys/bus/platform/drivers/ufshcd/*/flags/wb_enable
+Date:  March 2021
+Contact:   Daejun Park 
+Description:   This entry shows the status of HPB.
+
+   == 
+   0  HPB is not enabled.
+   1  HPB is enabled
+   == 

Re: [PATCH v2 01/18] vfs: add miscattr ops

2021-03-23 Thread Al Viro
On Mon, Mar 22, 2021 at 03:48:59PM +0100, Miklos Szeredi wrote:

minor nit: copy_fsxattr_{to,from}_user() might be better.

> +int fsxattr_copy_to_user(const struct miscattr *ma, struct fsxattr __user 
> *ufa)
> +{
> + struct fsxattr fa = {
> + .fsx_xflags = ma->fsx_xflags,
> + .fsx_extsize= ma->fsx_extsize,
> + .fsx_nextents   = ma->fsx_nextents,
> + .fsx_projid = ma->fsx_projid,
> + .fsx_cowextsize = ma->fsx_cowextsize,
> + };

That wants a comment along the lines of "guaranteed to be gap-free",
since otherwise you'd need memset() to avoid an infoleak.

> +static int ioctl_getflags(struct file *file, void __user *argp)
> +{
> + struct miscattr ma = { .flags_valid = true }; /* hint only */
> + unsigned int flags;
> + int err;
> +
> + err = vfs_miscattr_get(file_dentry(file), );

Umm...  Just to clarify - do we plan to have that ever called via
ovl_real_ioctl()?  IOW, is file_dentry() anything other than a way
to spell ->f_path.dentry here?

> +struct miscattr {
> + u32 flags;  /* flags (FS_IOC_GETFLAGS/FS_IOC_SETFLAGS) */
> + /* struct fsxattr: */
> + u32 fsx_xflags; /* xflags field value (get/set) */
> + u32 fsx_extsize;/* extsize field value (get/set)*/
> + u32 fsx_nextents;   /* nextents field value (get)   */
> + u32 fsx_projid; /* project identifier (get/set) */
> + u32 fsx_cowextsize; /* CoW extsize field value (get/set)*/
> + /* selectors: */
> + boolflags_valid:1;
> + boolxattr_valid:1;
> +};

OK as long as it stays kernel-only, but if we ever expose that to userland, we'd
better remember to turn the last two into an u32 with explicit bitmasks.


Re: [PATCH v6] mm: cma: support sysfs

2021-03-23 Thread John Hubbard

On 3/23/21 8:27 PM, Minchan Kim wrote:
...

+static int __init cma_sysfs_init(void)
+{
+   unsigned int i;
+
+   cma_kobj_root = kobject_create_and_add("cma", mm_kobj);
+   if (!cma_kobj_root)
+   return -ENOMEM;
+
+   for (i = 0; i < cma_area_count; i++) {
+   int err;
+   struct cma *cma;
+   struct cma_kobject *cma_kobj;
+
+   cma_kobj = kzalloc(sizeof(*cma_kobj), GFP_KERNEL);
+   if (!cma_kobj) {
+   kobject_put(cma_kobj_root);
+   return -ENOMEM;


This leaks little cma_kobj's all over the floor. :)


I thought kobject_put(cma_kobj_root) should deal with it. No?


If this fails when i > 0, there will be cma_kobj instances that
were stashed in the cma_areas[] array. But this code only deletes
the most recently allocated cma_kobj, not anything allocated on
previous iterations of the loop.

thanks,
--
John Hubbard
NVIDIA


Re: [RFC PATCH] arm64: dts: allwinner: a64/h5: Add CPU idle states

2021-03-23 Thread Samuel Holland
On 3/22/21 8:56 PM, Andre Przywara wrote:
>> I'm sending this patch as an RFC because it raises questions about how
>> we handle firmware versioning. How far back does (or should) our support
>> for old TF-A and Crust versions go?
>>
>> cpuidle has a problem that without working firmware support, CPUs will
>> enter idle states and be unable to wake up. As a result, the system will
>> hang at some point during boot, usually before getting to userspace.
>>
>> For over a year[0], TF-A has exposed the PSCI CPU_SUSPEND function when
>> a SCPI implementation is present[1]. Implementing CPU_SUSPEND is
>> required for implementing SYSTEM_SUSPEND[2], even if CPU_SUSPEND is not
>> itself used for anything. 
>>
>> However, there was no code to actually wake up a CPU once it called the
>> CPU_SUSPEND function, because I could not find the register providing
>> the necessary information. The fact that CPU_SUSPEND was broken affected
>> nobody, because nothing ever called it -- there were no idle states in
>> the DTS. In hindsight, what I should have done was always return failure
>> from sunxi_validate_power_state(), but that ship has long sailed.
>>
>> I finally found the elusive register and implemented the wakeup code
>> earlier this month[3]. So now, CPU_SUSPEND actually works, if all of
>> your firmware is up to date, and cpuidle works if you add the states in
>> your device tree.
>>
>> Unfortunately, there is currently nothing verifying that compatibility.
>> So you can get into four possible scenarios:
>>   1) No idle states in DTS, any firmware => Linux works, with baseline
>>  power consumption.
>>   2) Idle states added to DTS, no Crust/SCPI => Linux works, but every
>>  attempt to enter an idle state is rejected because CPU_SUSPEND is
>>  not hooked up. So power consumption increases by a sizable amount.
>>   3) Idle states added to DTS, "old" Crust/SCPI (before [3]) => Linux
>>  fails to boot, because CPUs never return from idle states.
>>   4) Idle states added to DTS, "new" Crust/SCPI (after [3]) => Linux
>>  works, with improved power consumption compared to the baseline.
>>
>> Obviously, we want to prevent scenario 3 if possible.
> 
> So I think the core of the problem is that the DT describes some
> firmware feature, but we have the DT bundled with the kernel, not the
> firmware.

I would say the core problem is that the firmware lies about supporting
PSCI CPU_SUSPEND. Linux shouldn't be calling CPU_SUSPEND if the firmware
declares it as unavailable, regardless of what is in the DTS.
(Technically, per the PSCI standard, CPU_SUSPEND is a mandatory
function, but a quick survey of the TF-A platforms shows it is far from
universally implemented.)

> So is there any way we can detect an older crust version in U-Boot,
> then remove any potential idle states from the DT?

Let's assume that we are using a functioning SoC (H3) or the secure fuse
is blown (A64) and therefore U-Boot cannot access SRAM A2. I can think
of three ways it can learn about crust:

a) PSCI_FEATURES (e.g. is CPU_SUSPEND supported)
b) Metadata in the FIT image
c) Custom SMCs

TF-A has some additional methods available:

d) The SCPI-reported firmware version
e) The magic number at the beginning of the firmware binary

> Granted, this requires recent U-Boot as well, but at least we could try
> to mitigate the worst case a bit?

If we're okay with modifying firmware to solve this problem, then I
propose the following solution:

1) Version bump crust or change its magic number.
2) Modify TF-A to only report CPU_SUSPEND as available if it detects the
   new crust version. This would involve conditionally setting
   sunxi_scpi_psci_ops.validate_power_state, and updating psci_setup.c
   to also check for .validate_power_state when setting psci_caps.
3) Modify the Linux PSCI client to respect PSCI_FEATURES when setting
   psci_ops.cpu_suspend. cpuidle-psci checks for this function before
   setting up idle states.
4) Finally, after some time, add the idle states to the DTS.

In fact, this solution solves both scenarios 2 and 3, because it also
takes care of the native PM implementation, which doesn't implement
CPU_SUSPEND at all.

Does that sound workable?

Regards,
Samuel

> A better solution could be to only *add* the idle states if the rest of
> the firmware is deemed worthy. So the mainline DTs would not carry the
> properties in the first place, and only U-Boot adds them, on detecting
> a capable firmware?
> Admittedly this changes the "flow" of the DT, where the kernel is the
> authority, but it might help to solve this problem?
> 
> Or any other way, which involves U-Boot patching the DTB? (This would
> apply to the DTB passed to the kernel, regardless of where and when
> it's loaded from)
> 
> Any opinions?
> 
> Cheers,
> Andre
> 
>> Enter the current patch: I chose the arm,psci-suspend-param values
>> specifically so they would be _rejected_ by the current TF-A code. This
>> makes scenario 3 behave like scenario 2. I 

Re: [PATCH] video: mmp: Few typo fixes

2021-03-23 Thread Joe Perches
On Mon, 2021-03-22 at 12:36 -0700, Randy Dunlap wrote:
> On 3/22/21 6:02 AM, Bhaskar Chowdhury wrote:
> > 
> > s/configed/configured/
> > s/registed/registered/
> > s/defintions/definitions/
> > 
> > Signed-off-by: Bhaskar Chowdhury 
> 
> Acked-by: Randy Dunlap 
[]
> > diff --git a/include/video/mmp_disp.h b/include/video/mmp_disp.h
> > index 77252cb46361..ea8b4331b7a1 100644
> > --- a/include/video/mmp_disp.h
> > +++ b/include/video/mmp_disp.h
> > @@ -172,7 +172,7 @@ struct mmp_panel {
> >     /* use node to register to list */
> >     struct list_head node;
> >     const char *name;
> > -   /* path name used to connect to proper path configed */
> > +   /* path name used to connect to proper path configured */

The spelling is now correct, but the word order doesn't make much sense.

> > @@ -291,7 +291,7 @@ static inline int mmp_overlay_set_addr(struct 
> > mmp_overlay *overlay,
> >   * it defined a common interface that plat driver need to implement
> >   */
> >  struct mmp_path_info {
> > -   /* driver data, set when registed*/
> > +   /* driver data, set when registered*/

should have a space before */




[tip:master] BUILD SUCCESS 4f469efcd03fe6ab88749f53252044c3f4491efb

2021-03-23 Thread kernel test robot
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git master
branch HEAD: 4f469efcd03fe6ab88749f53252044c3f4491efb  Merge branch 'core/entry'

elapsed time: 725m

configs tested: 125
configs skipped: 2

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm defconfig
arm64allyesconfig
arm64   defconfig
arm  allyesconfig
arm  allmodconfig
x86_64   allyesconfig
riscvallmodconfig
riscvallyesconfig
i386 allyesconfig
mipsworkpad_defconfig
powerpc mpc8313_rdb_defconfig
mips cu1000-neo_defconfig
armmini2440_defconfig
powerpc redwood_defconfig
mipsar7_defconfig
m68kmac_defconfig
arm  imote2_defconfig
mips  bmips_stb_defconfig
arm   milbeaut_m10v_defconfig
arm mv78xx0_defconfig
arm   h5000_defconfig
armspear3xx_defconfig
sh kfr2r09-romimage_defconfig
powerpcklondike_defconfig
sh   se7712_defconfig
ia64  tiger_defconfig
mips  ath25_defconfig
arm shannon_defconfig
arm   omap2plus_defconfig
arm  tct_hammer_defconfig
powerpc  cm5200_defconfig
powerpc  iss476-smp_defconfig
powerpc   bluestone_defconfig
arm  pxa255-idp_defconfig
armhisi_defconfig
arm  exynos_defconfig
mips tb0287_defconfig
sh  sdk7780_defconfig
powerpc  storcenter_defconfig
powerpc kilauea_defconfig
mips   sb1250_swarm_defconfig
mips  malta_kvm_defconfig
arm   stm32_defconfig
arc haps_hs_smp_defconfig
s390 alldefconfig
mipse55_defconfig
sh sh7710voipgw_defconfig
m68kstmark2_defconfig
arm lpc18xx_defconfig
shecovec24-romimage_defconfig
mips   rs90_defconfig
mips   capcella_defconfig
shsh7785lcr_defconfig
sh   se7721_defconfig
arm  colibri_pxa300_defconfig
mips   jazz_defconfig
mipsbcm47xx_defconfig
powerpc mpc837x_mds_defconfig
sh   se7619_defconfig
ia64 allmodconfig
ia64defconfig
ia64 allyesconfig
m68k allmodconfig
m68kdefconfig
m68k allyesconfig
nios2   defconfig
arc  allyesconfig
nds32 allnoconfig
nds32   defconfig
nios2allyesconfig
cskydefconfig
alpha   defconfig
alphaallyesconfig
xtensa   allyesconfig
h8300allyesconfig
arc defconfig
sh   allmodconfig
parisc  defconfig
s390 allyesconfig
s390 allmodconfig
parisc   allyesconfig
s390defconfig
sparcallyesconfig
sparc   defconfig
i386   tinyconfig
i386defconfig
mips allyesconfig
mips allmodconfig
powerpc  allyesconfig
powerpc  allmodconfig
powerpc   allnoconfig
x86_64   randconfig-a002-20210323
x86_64   randconfig-a003-20210323
x86_64   randconfig-a006-20210323
x86_64   randconfig-a001-20210323
x86_64   randconfig-a004-20210323
x86_64   randconfig-a005-20210323
i386 randconfig-a003-20210323
i386 randconfig-a004-20210323
i386 randconfig-a001-20210323
i386 randconfig-a002-20210323
i386

Re: [PATCH v4 1/2] usbip: tools: add options and examples in man page related to device mode

2021-03-23 Thread Hongren Zheng (Zenithal)
On Tue, Mar 23, 2021 at 05:12:00PM -0600, Shuah Khan wrote:
> On 3/23/21 6:55 AM, Hongren Zheng (Zenithal) wrote:
> > The commit e0546fd8b748 ("usbip: tools: Start using VUDC backend in
> > usbip tools") implemented device mode for user space tools, however the
> > corresponding options are not documented in man page.
> > 
> > This commit documents the options and provides examples on device mode.
> > 
> > Signed-off-by: Hongren Zheng 
> > ---
> >   tools/usb/usbip/doc/usbip.8  | 25 +
> >   tools/usb/usbip/doc/usbipd.8 | 22 ++
> >   2 files changed, 47 insertions(+)
> > 
> > PATCH v2:
> >  Add signed-off-by line
> > 
> > PATCH v3:
> >  Move patch changelog after the marker line
> >  Remove nickname in signed-off-by line
> > 
> > PATCH v4:
> >  Use commit short hash and message instead of long hash only when
> >referring to commit in the kernel
> > 
> 
> Thank you for the patch. Please see comments below:
> 
> > diff --git a/tools/usb/usbip/doc/usbip.8 b/tools/usb/usbip/doc/usbip.8
> > index a15d20063b98..385b0eda8746 100644
> > --- a/tools/usb/usbip/doc/usbip.8
> > +++ b/tools/usb/usbip/doc/usbip.8
> > @@ -49,6 +49,13 @@ then exit.
> >   Attach a remote USB device.
> >   .PP
> > +.HP
> > +\fBattach\fR \-\-remote=<\fIhost\fR> \-\-device=<\fdev_id\fR>
> > +.IP
> > +Attach a remote USB gadget.
> > +Only used when the remote usbipd is in device mode.
> > +.PP
> > +
> >   .HP
> >   \fBdetach\fR \-\-port=<\fIport\fR>
> >   .IP
> 
> This is a bit confusing. Please add a separate section for
> Attach a remote USB gadget complete with attach and detach
> instructions.

The detaching of a USB device and a USB gadget share the same detach
command. You attach one USB device/gadget use either one of the
above attach commands, and when you need to detach one device/gadget,
you first need `usbip port` to show the port of imported device/gadget,
for example, 

client:# usbip port
Imported USB devices

Port 00:  at High Speed(480Mbps)
   Netchip Technology, Inc. : Pocketbook Pro 903 / Mobius 2 Action Cam / 
xDuoo X3 / PocketBook Pro 602
   3-1 -> usbip://localhost:3240/usbip-vudc.0
   -> remote bus/dev 000/000


then use `usbip detach --port=0` to detach the device/gadget.
Since they share the same workflow for detaching, a separate section
may not be necessary.

Meanwhile, in the example below a detach command for device mode
can be added. With the example I think the complete flow for device
mode would be made clear enough.

I will send a new version of this patch with this command added in the
example, some description rephrased and typo fixed.

> 
> > @@ -73,6 +80,14 @@ Stop exporting a device so it can be used by a local 
> > driver.
> >   List USB devices exported by a remote host.
> >   .PP
> > +.HP
> > +\fBlist\fR \-\-device
> > +.IP
> > +List USB gadgets of local usbip-vudc.
> > +Only used when the local usbipd is in device mode.
> > +This can not list usbip-vudc USB gadgets of the remote device mode usbipd.
> > +.PP
> > +
> >   .HP
> >   \fBlist\fR \-\-local
> >   .IP
> > @@ -93,5 +108,15 @@ List local USB devices.
> >   client:# usbip detach --port=0
> >   - Detach the usb device.
> > +The following example shows the use of device mode
> > +
> > +server:# usbip list --device
> > +- Note this is the server side
> > +
> > +client:# modprobe vhci-hcd
> > +
> > +client:# usbip attach --remote=server --device=usbip-vudc.0
> > +- Connect the remote USB gadget
> > +
> >   .SH "SEE ALSO"
> >   \fBusbipd\fP\fB(8)\fB\fP
> > diff --git a/tools/usb/usbip/doc/usbipd.8 b/tools/usb/usbip/doc/usbipd.8
> > index fb62a756893b..53c8d5792de6 100644
> > --- a/tools/usb/usbip/doc/usbipd.8
> > +++ b/tools/usb/usbip/doc/usbipd.8
> > @@ -29,6 +29,12 @@ Bind to IPv4. Default is both.
> >   Bind to IPv6. Default is both.
> >   .PP
> > +.HP
> > +\fB\-e\fR, \fB\-\-device\fR
> > +.IP
> > +Run in device mode. Rather than drive an attached device, create a virtual 
> > UDC to bind gadgets to.
> > +.PP
> > +
> >   .HP
> >   \fB\-D\fR, \fB\-\-daemon\fR
> >   .IP
> > @@ -86,6 +92,22 @@ USB/IP client can connect and use exported devices.
> >   - A usb device 1-2 is now exportable to other hosts!
> >   - Use 'usbip unbind --busid=1-2' when you want to shutdown 
> > exporting and use the device locally.
> > +The following example shows the use of device mode
> > +
> > +server:# modprobe usbip-vudc
> > +- Use /sys/class/udc/ interface
> > +- usbip-host is independent of this module.
> > +
> > +server:# usbipd -e -D
> > +- Start usbip daemon in device mode.
> > +
> > +server:# modprobe g_mass_storage file=/tmp/tmp.img
> > +- Bind a gadget to usbip-vudc
> > +- in this example, a mass storage gadget is bound
> > +
> > +server:# usbip list --device
> > +- Note this is the server side
> > +
> >   .SH "SEE ALSO"
> >   

Re: [PATCH V2 1/5] powerpc/perf: Expose processor pipeline stage cycles using PERF_SAMPLE_WEIGHT_STRUCT

2021-03-23 Thread Madhavan Srinivasan



On 3/22/21 8:27 PM, Athira Rajeev wrote:

Performance Monitoring Unit (PMU) registers in powerpc provides
information on cycles elapsed between different stages in the
pipeline. This can be used for application tuning. On ISA v3.1
platform, this information is exposed by sampling registers.
Patch adds kernel support to capture two of the cycle counters
as part of perf sample using the sample type:
PERF_SAMPLE_WEIGHT_STRUCT.

The power PMU function 'get_mem_weight' currently uses 64 bit weight
field of perf_sample_data to capture memory latency. But following the
introduction of PERF_SAMPLE_WEIGHT_TYPE, weight field could contain
64-bit or 32-bit value depending on the architexture support for
PERF_SAMPLE_WEIGHT_STRUCT. Patches uses WEIGHT_STRUCT to expose the
pipeline stage cycles info. Hence update the ppmu functions to work for
64-bit and 32-bit weight values.

If the sample type is PERF_SAMPLE_WEIGHT, use the 64-bit weight field.
if the sample type is PERF_SAMPLE_WEIGHT_STRUCT, memory subsystem
latency is stored in the low 32bits of perf_sample_weight structure.
Also for CPU_FTR_ARCH_31, capture the two cycle counter information in
two 16 bit fields of perf_sample_weight structure.


Changes looks fine to me.

Reviewed-by: Madhavan Srinivasan 



Signed-off-by: Athira Rajeev 
---
  arch/powerpc/include/asm/perf_event_server.h |  2 +-
  arch/powerpc/perf/core-book3s.c  |  4 ++--
  arch/powerpc/perf/isa207-common.c| 29 +---
  arch/powerpc/perf/isa207-common.h|  6 +-
  4 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/include/asm/perf_event_server.h 
b/arch/powerpc/include/asm/perf_event_server.h
index 00e7e671bb4b..112cf092d7b3 100644
--- a/arch/powerpc/include/asm/perf_event_server.h
+++ b/arch/powerpc/include/asm/perf_event_server.h
@@ -43,7 +43,7 @@ struct power_pmu {
u64 alt[]);
void(*get_mem_data_src)(union perf_mem_data_src *dsrc,
u32 flags, struct pt_regs *regs);
-   void(*get_mem_weight)(u64 *weight);
+   void(*get_mem_weight)(u64 *weight, u64 type);
unsigned long   group_constraint_mask;
unsigned long   group_constraint_val;
u64 (*bhrb_filter_map)(u64 branch_sample_type);
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 766f064f00fb..6936763246bd 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -2206,9 +2206,9 @@ static void record_and_restart(struct perf_event *event, 
unsigned long val,
ppmu->get_mem_data_src)
ppmu->get_mem_data_src(_src, ppmu->flags, 
regs);
  
-		if (event->attr.sample_type & PERF_SAMPLE_WEIGHT &&

+   if (event->attr.sample_type & PERF_SAMPLE_WEIGHT_TYPE &&
ppmu->get_mem_weight)
-   ppmu->get_mem_weight();
+   ppmu->get_mem_weight(, 
event->attr.sample_type);
  
  		if (perf_event_overflow(event, , regs))

power_pmu_stop(event, 0);
diff --git a/arch/powerpc/perf/isa207-common.c 
b/arch/powerpc/perf/isa207-common.c
index e4f577da33d8..5dcbdbd54598 100644
--- a/arch/powerpc/perf/isa207-common.c
+++ b/arch/powerpc/perf/isa207-common.c
@@ -284,8 +284,10 @@ void isa207_get_mem_data_src(union perf_mem_data_src 
*dsrc, u32 flags,
}
  }
  
-void isa207_get_mem_weight(u64 *weight)

+void isa207_get_mem_weight(u64 *weight, u64 type)
  {
+   union perf_sample_weight *weight_fields;
+   u64 weight_lat;
u64 mmcra = mfspr(SPRN_MMCRA);
u64 exp = MMCRA_THR_CTR_EXP(mmcra);
u64 mantissa = MMCRA_THR_CTR_MANT(mmcra);
@@ -296,9 +298,30 @@ void isa207_get_mem_weight(u64 *weight)
mantissa = P10_MMCRA_THR_CTR_MANT(mmcra);
  
  	if (val == 0 || val == 7)

-   *weight = 0;
+   weight_lat = 0;
else
-   *weight = mantissa << (2 * exp);
+   weight_lat = mantissa << (2 * exp);
+
+   /*
+* Use 64 bit weight field (full) if sample type is
+* WEIGHT.
+*
+* if sample type is WEIGHT_STRUCT:
+* - store memory latency in the lower 32 bits.
+* - For ISA v3.1, use remaining two 16 bit fields of
+*   perf_sample_weight to store cycle counter values
+*   from sier2.
+*/
+   weight_fields = (union perf_sample_weight *)weight;
+   if (type & PERF_SAMPLE_WEIGHT)
+   weight_fields->full = weight_lat;
+   else {
+   weight_fields->var1_dw = (u32)weight_lat;
+   if (cpu_has_feature(CPU_FTR_ARCH_31)) {
+   weight_fields->var2_w = 
P10_SIER2_FINISH_CYC(mfspr(SPRN_SIER2));
+   weight_fields->var3_w = 
P10_SIER2_DISPATCH_CYC(mfspr(SPRN_SIER2));
+   

Re: [PATCH v5] mm: cma: support sysfs

2021-03-23 Thread Matthew Wilcox
On Tue, Mar 23, 2021 at 08:31:31PM -0700, Minchan Kim wrote:
> On Wed, Mar 24, 2021 at 03:02:24AM +, Matthew Wilcox wrote:
> > On Tue, Mar 23, 2021 at 12:50:50PM -0700, Minchan Kim wrote:
> > > + /* the number of CMA page successful allocations */
> > > + atomic64_t nr_pages_succeeded;
> > 
> > > +void cma_sysfs_alloc_pages_count(struct cma *cma, size_t count)
> > > +{
> > > + atomic64_add(count, >nr_pages_succeeded);
> > > +}
> > 
> > I don't understand.  A size_t is a byte count.  But the variable is called
> > 'nr_pages'.  So which is it, a byte count or a page count?
> 
> It's page count. I followed the cma_alloc interface since it has
> size_t count variable for nr_pages.

That's very confusing.  cma_alloc is wrong; if it needs to be an
unsigned long, that's fine.  But it shouldn't be size_t.

7.17 of n1256 defines:

size_t
which is the unsigned integer type of the result of the sizeof operator

Do you want to submit a patch to fix cma_alloc as well?

> Let's go with unsigned long nr_pages:
> void cma_sysfs_alloc_pages_count(struct cma *cma, unsigned long
> nr_pages)

Works for me!


Re: [PATCH v2] IB/mlx5: Reduce max order of memory allocated for xlt update

2021-03-23 Thread Aruna Ramakrishna


> On Mar 23, 2021, at 4:13 PM, Jason Gunthorpe  wrote:
> 
> On Tue, Mar 23, 2021 at 12:41:51PM -0700, Aruna Ramakrishna wrote:
>>   There is a far greater possibility of an order-8 allocation failing,
>>   esp. with the addition of __GFP_NORETRY , and the code would have to
>>   fall back to a lower order allocation more often than not (esp. on a
>>   long running system). Unless the performance gains from using order-8
>>   pages is significant (and it does not seem that way to me), we can just
>>   skip this step and directly go to the lower order allocation.
> 
> Do not send HTML mails.

I apologize; I’ve fixed the setting now.

> 
> Do you have benchmarks that show the performance of the high order
> pages is not relavent? I'm a bit surprised to hear that
> 

I guess my point was more to the effect that an order-8 alloc will fail more 
often than not, in this flow. For instance, when we were debugging the latency 
spikes here, this was the typical buddyinfo output on that system:

Node 0, zone  DMA  0  1  1  2  3  0  1  0   
   1  1  3 
Node 0, zoneDMA32  7  7  7  6 10  2  6  7   
   6  2306 
Node 0, zone   Normal   3390  51354  17574   6556   1586 26  2  1   
   0  0  0 
Node 1, zone   Normal  11519  23315  23306   9738 73  2  0  1   
   0  0  0 

I think this level of fragmentation is pretty normal on long running systems. 
Here, in the reg_mr flow, the first try (order-8) alloc will probably fail 9 
times out of 10 (esp. after the addition of GFP_NORETRY flag), and then as 
fallback, the code tries to allocate a lower order, and if that too fails, it 
allocates a page. I think it makes sense to just avoid trying an order-8 alloc 
here.

Thanks,
Aruna


> This code really needs some attention to use a proper
> scatter/gather. I understand the chip can do it, just some of the
> software layers need to be stripped away so it can form the right SGL
> in the HW.
> 
> Jason



Re: [PATCH] Revert "f2fs: give a warning only for readonly partition"

2021-03-23 Thread Jaegeuk Kim
On 03/24, Chao Yu wrote:
> On 2021/3/24 2:39, Jaegeuk Kim wrote:
> > On 03/23, Chao Yu wrote:
> > > This reverts commit 938a184265d75ea474f1c6fe1da96a5196163789.
> > > 
> > > Because that commit fails generic/050 testcase which expect failure
> > > during mount a recoverable readonly partition.
> > 
> > I think we need to change generic/050, since f2fs can recover this 
> > partition,
> 
> Well, not sure we can change that testcase, since it restricts all generic
> filesystems behavior. At least, ext4's behavior makes sense to me:
> 
>   journal_dev_ro = bdev_read_only(journal->j_dev);
>   really_read_only = bdev_read_only(sb->s_bdev) | journal_dev_ro;
> 
>   if (journal_dev_ro && !sb_rdonly(sb)) {
>   ext4_msg(sb, KERN_ERR,
>"journal device read-only, try mounting with '-o ro'");
>   err = -EROFS;
>   goto err_out;
>   }
> 
>   if (ext4_has_feature_journal_needs_recovery(sb)) {
>   if (sb_rdonly(sb)) {
>   ext4_msg(sb, KERN_INFO, "INFO: recovery "
>   "required on readonly filesystem");
>   if (really_read_only) {
>   ext4_msg(sb, KERN_ERR, "write access "
>   "unavailable, cannot proceed "
>   "(try mounting with noload)");
>   err = -EROFS;
>   goto err_out;
>   }
>   ext4_msg(sb, KERN_INFO, "write access will "
>  "be enabled during recovery");
>   }
>   }
> 
> > even though using it as readonly. And, valid checkpoint can allow for user 
> > to
> > read all the data without problem.
> 
> >>if (f2fs_hw_is_readonly(sbi)) {
> 
> Since device is readonly now, all write to the device will fail, checkpoint 
> can
> not persist recovered data, after page cache is expired, user can see stale 
> data.

My point is, after mount with ro, there'll be no data write which preserves the
current status. So, in the next time, we can recover fsync'ed data later, if
user succeeds to mount as rw. Another point is, with the current checkpoint, we
should not have any corrupted metadata. So, why not giving a chance to show what
data remained to user? I think this can be doable only with CoW filesystems.

> 
> Am I missing something?
> 
> Thanks,
> 
> > 
> > > 
> > > Fixes: 938a184265d7 ("f2fs: give a warning only for readonly partition")
> > > Signed-off-by: Chao Yu 
> > > ---
> > >   fs/f2fs/super.c | 8 +---
> > >   1 file changed, 5 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> > > index b48281642e98..2b78ee11f093 100644
> > > --- a/fs/f2fs/super.c
> > > +++ b/fs/f2fs/super.c
> > > @@ -3952,10 +3952,12 @@ static int f2fs_fill_super(struct super_block 
> > > *sb, void *data, int silent)
> > >* previous checkpoint was not done by clean system 
> > > shutdown.
> > >*/
> > >   if (f2fs_hw_is_readonly(sbi)) {
> > > - if (!is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG))
> > > + if (!is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) {
> > > + err = -EROFS;
> > >   f2fs_err(sbi, "Need to recover fsync 
> > > data, but write access unavailable");
> > > - else
> > > - f2fs_info(sbi, "write access unavailable, 
> > > skipping recovery");
> > > + goto free_meta;
> > > + }
> > > + f2fs_info(sbi, "write access unavailable, skipping 
> > > recovery");
> > >   goto reset_checkpoint;
> > >   }
> > > -- 
> > > 2.29.2
> > .
> > 


Re: [PATCH v10] i2c: virtio: add a virtio i2c frontend driver

2021-03-23 Thread Viresh Kumar
On 23-03-21, 22:19, Jie Deng wrote:
> +static int virtio_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, 
> int num)
> +{
> + struct virtio_i2c *vi = i2c_get_adapdata(adap);
> + struct virtqueue *vq = vi->vq;
> + struct virtio_i2c_req *reqs;
> + unsigned long time_left;
> + int ret, nr;
> +
> + reqs = kcalloc(num, sizeof(*reqs), GFP_KERNEL);
> + if (!reqs)
> + return -ENOMEM;
> +
> + mutex_lock(>lock);
> +
> + ret = virtio_i2c_send_reqs(vq, reqs, msgs, num);
> + if (ret == 0)
> + goto err_unlock_free;
> +
> + nr = ret;
> + reinit_completion(>completion);
> + virtqueue_kick(vq);

Coming back to this again, what is the expectation from the other side for this
? I mean there is no obvious relation between the *msgs* which we are going to
transfer (from the other side's or host's point of view). When should the host
OS call its virtqueue_kick() counterpart ?

Lemme give an example for this. Lets say that we need to transfer 3 messages
here in this routine. What we did was we prepared virtqueue for all 3 messages
together and then called virtqueue_kick().

Now if the other side (host) processes the first message and sends its reply
(with virtqueue_kick() counterpart) before processing the other two messages,
then it will end up calling virtio_i2c_msg_done() here. That will make us call
virtio_i2c_complete_reqs(), while only the first messages is processed until
now and so we will fail for the other two messages straight away.

Should we send only 1 message from i2c-virtio linux driver and then wait for
virtio_i2c_msg_done() to be called, before sending the next message to make sure
it doesn't break ?

-- 
viresh


Re: [PATCH] mm: memcontrol: fix memsw uncharge for root_mem_cgroup

2021-03-23 Thread Muchun Song
On Tue, Mar 23, 2021 at 11:04 PM Muchun Song  wrote:
>
> The pages aren't accounted at the root level, so we cannot uncharge the
> page to the memsw counter for the root memcg. Fix this.
>
> Fixes: 1f47b61fb407 ("mm: memcontrol: fix swap counter leak on swapout from 
> offline cgroup")
> Signed-off-by: Muchun Song 

I am very sorry. I should repent. I suddenly realise the fix is totally
wrong. Because the @memcg cannot be root memcg when
@memcg != @swap_memcg. Please ignore this patch. I am very
sorry for the noise. And sorry to Michal.


> ---
>  mm/memcontrol.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index 533b4b31b464..7d765a106684 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -7155,7 +7155,8 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t 
> entry)
> if (!cgroup_memory_noswap && memcg != swap_memcg) {
> if (!mem_cgroup_is_root(swap_memcg))
> page_counter_charge(_memcg->memsw, nr_entries);
> -   page_counter_uncharge(>memsw, nr_entries);
> +   if (!mem_cgroup_is_root(memcg))
> +   page_counter_uncharge(>memsw, nr_entries);
> }
>
> /*
> --
> 2.11.0
>


[tip:x86/urgent] BUILD SUCCESS 9fcb51c14da2953de585c5c6e50697b8a6e91a7b

2021-03-23 Thread kernel test robot
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git 
x86/urgent
branch HEAD: 9fcb51c14da2953de585c5c6e50697b8a6e91a7b  x86/build: Turn off 
-fcf-protection for realmode targets

elapsed time: 725m

configs tested: 136
configs skipped: 49

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm defconfig
arm64allyesconfig
arm64   defconfig
arm  allyesconfig
arm  allmodconfig
x86_64   allyesconfig
riscvallmodconfig
riscvallyesconfig
i386 allyesconfig
mipsworkpad_defconfig
powerpc mpc8313_rdb_defconfig
mips cu1000-neo_defconfig
armmini2440_defconfig
powerpc redwood_defconfig
mipsar7_defconfig
m68kmac_defconfig
arm  imote2_defconfig
mips  bmips_stb_defconfig
arm   milbeaut_m10v_defconfig
arm mv78xx0_defconfig
arm   h5000_defconfig
armspear3xx_defconfig
m68k   m5208evb_defconfig
powerpc ksi8560_defconfig
armmps2_defconfig
arm shannon_defconfig
arm   omap2plus_defconfig
arm  tct_hammer_defconfig
powerpc  cm5200_defconfig
powerpc  iss476-smp_defconfig
arm  pxa255-idp_defconfig
armhisi_defconfig
arm  exynos_defconfig
powerpc  mpc866_ads_defconfig
powerpc  mgcoge_defconfig
mips   ip32_defconfig
xtensa   common_defconfig
riscv  rv32_defconfig
s390defconfig
mips tb0287_defconfig
sh  sdk7780_defconfig
powerpc  storcenter_defconfig
powerpc kilauea_defconfig
mips   sb1250_swarm_defconfig
powerpc   bluestone_defconfig
arc haps_hs_smp_defconfig
s390 alldefconfig
mipse55_defconfig
sh sh7710voipgw_defconfig
m68kstmark2_defconfig
nios2 3c120_defconfig
sh  landisk_defconfig
sh   secureedge5410_defconfig
arm  integrator_defconfig
powerpc mpc836x_mds_defconfig
mips cu1830-neo_defconfig
armshmobile_defconfig
powerpc ep8248e_defconfig
powerpc  makalu_defconfig
arm lpc32xx_defconfig
powerpc mpc834x_mds_defconfig
arm  colibri_pxa300_defconfig
mips   jazz_defconfig
mipsbcm47xx_defconfig
powerpc mpc837x_mds_defconfig
sh   se7619_defconfig
ia64 allmodconfig
ia64defconfig
ia64 allyesconfig
m68k allmodconfig
m68kdefconfig
m68k allyesconfig
nios2   defconfig
arc  allyesconfig
nds32 allnoconfig
nds32   defconfig
nios2allyesconfig
cskydefconfig
alpha   defconfig
alphaallyesconfig
xtensa   allyesconfig
h8300allyesconfig
arc defconfig
sh   allmodconfig
parisc  defconfig
s390 allyesconfig
s390 allmodconfig
parisc   allyesconfig
sparcallyesconfig
sparc   defconfig
i386   tinyconfig
i386defconfig
mips allyesconfig
mips allmodconfig
powerpc  allyesconfig
powerpc  allmodconfig
powerpc   allnoconfig
x86_64   randconfig-a002-20210323
x86_64   randconfig-a003-20210323
x86_64   randconfig-a006-20210323
x86_64

RE: [PATCH 0/7] PCI: layerscape: Add power management support

2021-03-23 Thread Z.q. Hou
Hi Lorenzo,

> -Original Message-
> From: Lorenzo Pieralisi 
> Sent: 2021年3月23日 19:15
> To: Z.q. Hou 
> Cc: linux-...@vger.kernel.org; devicet...@vger.kernel.org;
> linux-kernel@vger.kernel.org; bhelg...@google.com; robh...@kernel.org;
> shawn...@kernel.org; Leo Li ;
> gustavo.pimen...@synopsys.com; M.h. Lian ;
> Mingkai Hu ; Roy Zang 
> Subject: Re: [PATCH 0/7] PCI: layerscape: Add power management support
> 
> On Mon, Sep 07, 2020 at 01:37:54PM +0800, Zhiqiang Hou wrote:
> > From: Hou Zhiqiang 
> >
> > This patch series is to add PCIe power management support for NXP
> > Layerscape platfroms.
> >
> > Hou Zhiqiang (7):
> >   PCI: dwc: Fix a bug of the case dw_pci->ops is NULL
> >   PCI: layerscape: Change to use the DWC common link-up check
> function
> >   dt-bindings: pci: layerscape-pci: Add a optional property big-endian
> >   arm64: dts: layerscape: Add big-endian property for PCIe nodes
> >   dt-bindings: pci: layerscape-pci: Update the description of SCFG
> > property
> >   dts: arm64: ls1043a: Add SCFG phandle for PCIe nodes
> >   PCI: layerscape: Add power management support
> >
> >  .../bindings/pci/layerscape-pci.txt   |   6 +-
> >  .../arm64/boot/dts/freescale/fsl-ls1012a.dtsi |   1 +
> >  .../arm64/boot/dts/freescale/fsl-ls1043a.dtsi |   6 +
> >  .../arm64/boot/dts/freescale/fsl-ls1046a.dtsi |   3 +
> >  drivers/pci/controller/dwc/pci-layerscape.c   | 473
> ++
> >  drivers/pci/controller/dwc/pcie-designware.c  |  12 +-
> >  drivers/pci/controller/dwc/pcie-designware.h  |   1 +
> >  7 files changed, 388 insertions(+), 114 deletions(-)
> 
> I don't know which patches are still applicable, I will mark this series as
> superseded since you will have to rebase it anyway - please let me know
> what's the plan.

I'll rebase this series on the latest base.

Thanks,
Zhiqiang

> 
> Thanks,
> Lorenzo


[PATCH v4 4/5] arm64: kaslr: support randomized module area with KASAN_VMALLOC

2021-03-23 Thread Lecopzer Chen
After KASAN_VMALLOC works in arm64, we can randomize module region
into vmalloc area now.

Test:
VMALLOC area ffc01000 fffdf000

before the patch:
module_alloc_base/end ffc008b8 ffc01000
after the patch:
module_alloc_base/end ffdcf4bed000 ffc01000

And the function that insmod some modules is fine.

Suggested-by: Ard Biesheuvel 
Signed-off-by: Lecopzer Chen 
---
 arch/arm64/kernel/kaslr.c  | 18 ++
 arch/arm64/kernel/module.c | 16 +---
 2 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c
index 27f8939deb1b..341342b207f6 100644
--- a/arch/arm64/kernel/kaslr.c
+++ b/arch/arm64/kernel/kaslr.c
@@ -128,15 +128,17 @@ u64 __init kaslr_early_init(void)
/* use the top 16 bits to randomize the linear region */
memstart_offset_seed = seed >> 48;
 
-   if (IS_ENABLED(CONFIG_KASAN_GENERIC) ||
-   IS_ENABLED(CONFIG_KASAN_SW_TAGS))
+   if (!IS_ENABLED(CONFIG_KASAN_VMALLOC) &&
+   (IS_ENABLED(CONFIG_KASAN_GENERIC) ||
+IS_ENABLED(CONFIG_KASAN_SW_TAGS)))
/*
-* KASAN does not expect the module region to intersect the
-* vmalloc region, since shadow memory is allocated for each
-* module at load time, whereas the vmalloc region is shadowed
-* by KASAN zero pages. So keep modules out of the vmalloc
-* region if KASAN is enabled, and put the kernel well within
-* 4 GB of the module region.
+* KASAN without KASAN_VMALLOC does not expect the module region
+* to intersect the vmalloc region, since shadow memory is
+* allocated for each module at load time, whereas the vmalloc
+* region is shadowed by KASAN zero pages. So keep modules
+* out of the vmalloc region if KASAN is enabled without
+* KASAN_VMALLOC, and put the kernel well within 4 GB of the
+* module region.
 */
return offset % SZ_2G;
 
diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
index fe21e0f06492..b5ec010c481f 100644
--- a/arch/arm64/kernel/module.c
+++ b/arch/arm64/kernel/module.c
@@ -40,14 +40,16 @@ void *module_alloc(unsigned long size)
NUMA_NO_NODE, __builtin_return_address(0));
 
if (!p && IS_ENABLED(CONFIG_ARM64_MODULE_PLTS) &&
-   !IS_ENABLED(CONFIG_KASAN_GENERIC) &&
-   !IS_ENABLED(CONFIG_KASAN_SW_TAGS))
+   (IS_ENABLED(CONFIG_KASAN_VMALLOC) ||
+(!IS_ENABLED(CONFIG_KASAN_GENERIC) &&
+ !IS_ENABLED(CONFIG_KASAN_SW_TAGS
/*
-* KASAN can only deal with module allocations being served
-* from the reserved module region, since the remainder of
-* the vmalloc region is already backed by zero shadow pages,
-* and punching holes into it is non-trivial. Since the module
-* region is not randomized when KASAN is enabled, it is even
+* KASAN without KASAN_VMALLOC can only deal with module
+* allocations being served from the reserved module region,
+* since the remainder of the vmalloc region is already
+* backed by zero shadow pages, and punching holes into it
+* is non-trivial. Since the module region is not randomized
+* when KASAN is enabled without KASAN_VMALLOC, it is even
 * less likely that the module region gets exhausted, so we
 * can simply omit this fallback in that case.
 */
-- 
2.25.1



[PATCH v4 1/5] arm64: kasan: don't populate vmalloc area for CONFIG_KASAN_VMALLOC

2021-03-23 Thread Lecopzer Chen
Linux support KAsan for VMALLOC since commit 3c5c3cfb9ef4da9
("kasan: support backing vmalloc space with real shadow memory")

Like how the MODULES_VADDR does now, just not to early populate
the VMALLOC_START between VMALLOC_END.

Before:

MODULE_VADDR: no mapping, no zero shadow at init
VMALLOC_VADDR: backed with zero shadow at init

After:

MODULE_VADDR: no mapping, no zero shadow at init
VMALLOC_VADDR: no mapping, no zero shadow at init

Thus the mapping will get allocated on demand by the core function
of KASAN_VMALLOC.

  ---  vmalloc_shadow_start
 |   |
 |   |
 |   | <= non-mapping
 |   |
 |   |
 |---|
 |///|<- kimage shadow with page table mapping.
 |---|
 |   |
 |   | <= non-mapping
 |   |
 - vmalloc_shadow_end
 |000|
 |000| <= Zero shadow
 |000|
 - KASAN_SHADOW_END

Signed-off-by: Lecopzer Chen 
Acked-by: Andrey Konovalov 
Tested-by: Andrey Konovalov 
Tested-by: Ard Biesheuvel 
---
 arch/arm64/mm/kasan_init.c | 18 +-
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
index d8e66c78440e..20d06008785f 100644
--- a/arch/arm64/mm/kasan_init.c
+++ b/arch/arm64/mm/kasan_init.c
@@ -214,6 +214,7 @@ static void __init kasan_init_shadow(void)
 {
u64 kimg_shadow_start, kimg_shadow_end;
u64 mod_shadow_start, mod_shadow_end;
+   u64 vmalloc_shadow_end;
phys_addr_t pa_start, pa_end;
u64 i;
 
@@ -223,6 +224,8 @@ static void __init kasan_init_shadow(void)
mod_shadow_start = (u64)kasan_mem_to_shadow((void *)MODULES_VADDR);
mod_shadow_end = (u64)kasan_mem_to_shadow((void *)MODULES_END);
 
+   vmalloc_shadow_end = (u64)kasan_mem_to_shadow((void *)VMALLOC_END);
+
/*
 * We are going to perform proper setup of shadow memory.
 * At first we should unmap early shadow (clear_pgds() call below).
@@ -241,12 +244,17 @@ static void __init kasan_init_shadow(void)
 
kasan_populate_early_shadow(kasan_mem_to_shadow((void *)PAGE_END),
   (void *)mod_shadow_start);
-   kasan_populate_early_shadow((void *)kimg_shadow_end,
-  (void *)KASAN_SHADOW_END);
 
-   if (kimg_shadow_start > mod_shadow_end)
-   kasan_populate_early_shadow((void *)mod_shadow_end,
-   (void *)kimg_shadow_start);
+   if (IS_ENABLED(CONFIG_KASAN_VMALLOC))
+   kasan_populate_early_shadow((void *)vmalloc_shadow_end,
+   (void *)KASAN_SHADOW_END);
+   else {
+   kasan_populate_early_shadow((void *)kimg_shadow_end,
+   (void *)KASAN_SHADOW_END);
+   if (kimg_shadow_start > mod_shadow_end)
+   kasan_populate_early_shadow((void *)mod_shadow_end,
+   (void *)kimg_shadow_start);
+   }
 
for_each_mem_range(i, _start, _end) {
void *start = (void *)__phys_to_virt(pa_start);
-- 
2.25.1



[PATCH v4 5/5] arm64: Kconfig: select KASAN_VMALLOC if KANSAN_GENERIC is enabled

2021-03-23 Thread Lecopzer Chen
Before this patch, someone who wants to use VMAP_STACK when
KASAN_GENERIC enabled must explicitly select KASAN_VMALLOC.

>From Will's suggestion [1]:
  > I would _really_ like to move to VMAP stack unconditionally, and
  > that would effectively force KASAN_VMALLOC to be set if KASAN is in use

Because VMAP_STACK now depends on either HW_TAGS or KASAN_VMALLOC if
KASAN enabled, in order to make VMAP_STACK selected unconditionally,
we bind KANSAN_GENERIC and KASAN_VMALLOC together.

Note that SW_TAGS supports neither VMAP_STACK nor KASAN_VMALLOC now,
so this is the first step to make VMAP_STACK selected unconditionally.

Bind KANSAN_GENERIC and KASAN_VMALLOC together is supposed to cost more
memory at runtime, thus the alternative is using SW_TAGS KASAN instead.

[1]: https://lore.kernel.org/lkml/20210204150100.GE20815@willie-the-truck/

Suggested-by: Will Deacon 
Signed-off-by: Lecopzer Chen 
---
 arch/arm64/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 3e54fa938234..07762359d741 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -195,6 +195,7 @@ config ARM64
select IOMMU_DMA if IOMMU_SUPPORT
select IRQ_DOMAIN
select IRQ_FORCED_THREADING
+   select KASAN_VMALLOC if KASAN_GENERIC
select MODULES_USE_ELF_RELA
select NEED_DMA_MAP_STATE
select NEED_SG_DMA_LENGTH
-- 
2.25.1



[PATCH v4 0/5] arm64: kasan: support CONFIG_KASAN_VMALLOC

2021-03-23 Thread Lecopzer Chen


Linux supports KAsan for VMALLOC since commit 3c5c3cfb9ef4da9
("kasan: support backing vmalloc space with real shadow memory")

Acroding to how x86 ported it [1], they early allocated p4d and pgd,
but in arm64 I just simulate how KAsan supports MODULES_VADDR in arm64
by not to populate the vmalloc area except for kimg address.

  ---  vmalloc_shadow_start
 |   |
 |   | 
 |   | <= non-mapping
 |   |
 |   |
 |---|
 |///|<- kimage shadow with page table mapping.
 |---|
 |   |
 |   | <= non-mapping
 |   |
 - vmalloc_shadow_end
 |000|
 |000| <= Zero shadow
 |000|
 - KASAN_SHADOW_END


Test environment:
4G and 8G Qemu virt, 
39-bit VA + 4k PAGE_SIZE with 3-level page table,
test by lib/test_kasan.ko and lib/test_kasan_module.ko

It works with Kaslr and CONFIG_RANDOMIZE_MODULE_REGION_FULL
and randomize module region inside vmalloc area.

Also work on VMAP_STACK, thanks Ard for testing it.


[1]: commit 0609ae011deb41c ("x86/kasan: support KASAN_VMALLOC")


---
Thanks Will Deacon, Ard Biesheuvel and Andrey Konovalov
for reviewing and suggestion.

v4:
1. rebase on 5.12-rc4
2. tweak commit message

v3:
rebase on 5.11-rc6
1. remove always true condition in kasan_init() and remove unsed
   vmalloc_shadow_start.
2. select KASAN_VMALLOC if KANSAN_GENERIC is enabled
   for VMAP_STACK.
3. tweak commit message

v2:
1. kasan_init.c tweak indent
2. change Kconfig depends only on HAVE_ARCH_KASAN
3. support randomized module region.



v3:
https://lore.kernel.org/lkml/20210206083552.24394-1-lecopzer.c...@mediatek.com/
v2:
https://lkml.org/lkml/2021/1/9/49
v1:
https://lore.kernel.org/lkml/20210103171137.153834-1-lecop...@gmail.com/
---
Lecopzer Chen (5):
  arm64: kasan: don't populate vmalloc area for CONFIG_KASAN_VMALLOC
  arm64: kasan: abstract _text and _end to KERNEL_START/END
  arm64: Kconfig: support CONFIG_KASAN_VMALLOC
  arm64: kaslr: support randomized module area with KASAN_VMALLOC
  arm64: Kconfig: select KASAN_VMALLOC if KANSAN_GENERIC is enabled

 arch/arm64/Kconfig |  2 ++
 arch/arm64/kernel/kaslr.c  | 18 ++
 arch/arm64/kernel/module.c | 16 +---
 arch/arm64/mm/kasan_init.c | 24 
 4 files changed, 37 insertions(+), 23 deletions(-)

-- 
2.25.1



[PATCH v4 2/5] arm64: kasan: abstract _text and _end to KERNEL_START/END

2021-03-23 Thread Lecopzer Chen
Arm64 provides defined macro for KERNEL_START and KERNEL_END,
thus replace them by the abstration instead of using _text and _end.

Signed-off-by: Lecopzer Chen 
Acked-by: Andrey Konovalov 
Tested-by: Andrey Konovalov 
Tested-by: Ard Biesheuvel 
---
 arch/arm64/mm/kasan_init.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
index 20d06008785f..cd2653b7b174 100644
--- a/arch/arm64/mm/kasan_init.c
+++ b/arch/arm64/mm/kasan_init.c
@@ -218,8 +218,8 @@ static void __init kasan_init_shadow(void)
phys_addr_t pa_start, pa_end;
u64 i;
 
-   kimg_shadow_start = (u64)kasan_mem_to_shadow(_text) & PAGE_MASK;
-   kimg_shadow_end = PAGE_ALIGN((u64)kasan_mem_to_shadow(_end));
+   kimg_shadow_start = (u64)kasan_mem_to_shadow(KERNEL_START) & PAGE_MASK;
+   kimg_shadow_end = PAGE_ALIGN((u64)kasan_mem_to_shadow(KERNEL_END));
 
mod_shadow_start = (u64)kasan_mem_to_shadow((void *)MODULES_VADDR);
mod_shadow_end = (u64)kasan_mem_to_shadow((void *)MODULES_END);
@@ -240,7 +240,7 @@ static void __init kasan_init_shadow(void)
clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END);
 
kasan_map_populate(kimg_shadow_start, kimg_shadow_end,
-  early_pfn_to_nid(virt_to_pfn(lm_alias(_text;
+  
early_pfn_to_nid(virt_to_pfn(lm_alias(KERNEL_START;
 
kasan_populate_early_shadow(kasan_mem_to_shadow((void *)PAGE_END),
   (void *)mod_shadow_start);
-- 
2.25.1



[PATCH v4 3/5] arm64: Kconfig: support CONFIG_KASAN_VMALLOC

2021-03-23 Thread Lecopzer Chen
We can backed shadow memory in vmalloc area after vmalloc area
isn't populated at kasan_init(), thus make KASAN_VMALLOC selectable.

Signed-off-by: Lecopzer Chen 
Acked-by: Andrey Konovalov 
Tested-by: Andrey Konovalov 
Tested-by: Ard Biesheuvel 
---
 arch/arm64/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 5656e7aacd69..3e54fa938234 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -138,6 +138,7 @@ config ARM64
select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_JUMP_LABEL_RELATIVE
select HAVE_ARCH_KASAN if !(ARM64_16K_PAGES && ARM64_VA_BITS_48)
+   select HAVE_ARCH_KASAN_VMALLOC if HAVE_ARCH_KASAN
select HAVE_ARCH_KASAN_SW_TAGS if HAVE_ARCH_KASAN
select HAVE_ARCH_KASAN_HW_TAGS if (HAVE_ARCH_KASAN && ARM64_MTE)
select HAVE_ARCH_KFENCE
-- 
2.25.1



Re: [PATCH v4 RESEND 3/5] perf/x86/lbr: Move cpuc->lbr_xsave allocation out of sleeping region

2021-03-23 Thread Namhyung Kim
On Wed, Mar 24, 2021 at 12:47 PM Like Xu  wrote:
>
> Hi Namhyung,
>
> On 2021/3/24 9:32, Namhyung Kim wrote:
> > Hello,
> >
> > On Mon, Mar 22, 2021 at 3:14 PM Like Xu  wrote:
> >> +void reserve_lbr_buffers(struct perf_event *event)
> >> +{
> >> +   struct kmem_cache *kmem_cache = x86_get_pmu()->task_ctx_cache;
> >> +   struct cpu_hw_events *cpuc;
> >> +   int cpu;
> >> +
> >> +   if (!static_cpu_has(X86_FEATURE_ARCH_LBR))
> >> +   return;
> >> +
> >> +   for_each_possible_cpu(cpu) {
> >> +   cpuc = per_cpu_ptr(_hw_events, cpu);
> >> +   if (kmem_cache && !cpuc->lbr_xsave && 
> >> !event->attr.precise_ip)
> >> +   cpuc->lbr_xsave = kmem_cache_alloc(kmem_cache, 
> >> GFP_KERNEL);
> >> +   }
> >> +}
> >
> > I think we should use kmem_cache_alloc_node().
>
> "kmem_cache_alloc_node - Allocate an object on the specified node"
>
> The reserve_lbr_buffers() is called in __x86_pmu_event_init().
> When the LBR perf_event is scheduled to another node, it seems
> that we will not call init() and allocate again.
>
> Do you mean use kmem_cache_alloc_node() for each numa_nodes_parsed ?

I assume cpuc->lbr_xsave will be accessed for that cpu only.
Then it needs to allocate it in the node that cpu belongs to.
Something like below..

cpuc->lbr_xsave = kmem_cache_alloc_node(kmem_cache, GFP_KERNEL,
   cpu_to_node(cpu));

Thanks,
Namhyung


Re: [PATCH v10] i2c: virtio: add a virtio i2c frontend driver

2021-03-23 Thread Viresh Kumar
On 24-03-21, 12:00, Jie Deng wrote:
> 
> On 2021/3/24 11:52, Viresh Kumar wrote:
> > On 24-03-21, 08:53, Jie Deng wrote:
> > > On 2021/3/23 17:38, Viresh Kumar wrote:
> > > > On 23-03-21, 14:31, Viresh Kumar wrote:
> > > > > On 23-03-21, 22:19, Jie Deng wrote:
> > > > > > +static int virtio_i2c_xfer(struct i2c_adapter *adap, struct 
> > > > > > i2c_msg *msgs, int num)
> > > > > > +{
> > > > > > +   struct virtio_i2c *vi = i2c_get_adapdata(adap);
> > > > > > +   struct virtqueue *vq = vi->vq;
> > > > > > +   struct virtio_i2c_req *reqs;
> > > > > > +   unsigned long time_left;
> > > > > > +   int ret, nr;
> > > > > > +
> > > > > > +   reqs = kcalloc(num, sizeof(*reqs), GFP_KERNEL);
> > > > > > +   if (!reqs)
> > > > > > +   return -ENOMEM;
> > > > > > +
> > > > > > +   mutex_lock(>lock);
> > > > > > +
> > > > > > +   ret = virtio_i2c_send_reqs(vq, reqs, msgs, num);
> > > > > > +   if (ret == 0)
> > > > > > +   goto err_unlock_free;
> > > > > > +
> > > > > > +   nr = ret;
> > > > > > +   reinit_completion(>completion);
> > > > > I think I may have found a possible bug here. This 
> > > > > reinit_completion() must
> > > > > happen before we call virtio_i2c_send_reqs(). It is certainly 
> > > > > possible (surely
> > > > > in corner cases) that virtio_i2c_msg_done() may get called right after
> > > > > virtio_i2c_send_reqs() and before we were able to call 
> > > > > reinit_completion(). And
> > > > > in that case we will never see the completion happen at all.
> > > > > 
> > > > > > +   virtqueue_kick(vq);
> > > > I may have misread this. Can the actually start before virtqueue_kick() 
> > > > is
> > > > called ?
> > I didn't write it properly here. I wanted to say,
> > 
> > "Can the _transfer_ actually start before virtqueue_kick() is called ?"
> 
> 
> It can't start until the virtqueue_kick() is called. Call virtqueue_kick
> then wait.

Great, thanks for the confirmation. The code is fine then.

-- 
viresh


Re: [PATCH v10] i2c: virtio: add a virtio i2c frontend driver

2021-03-23 Thread Viresh Kumar
On 24-03-21, 09:17, Jie Deng wrote:
> I didn't see the "struct virtio_driver" has a member "struct dev_pm_ops *pm"
> 
> It defines its own hooks (freeze and restore) though it includes "struct
> device_driver"
> 
> which has a "struct dev_pm_ops *pm".
> 
> I just follow other virtio drivers to directly use the hooks defined in
> "struct virtio_driver".

Right, I think we can't use the SIMPLE PM OPS for virtio yet, the core calls
only the freeze and restore callbacks which are part of struct virtio_driver.

> For this driver, Both __maybe_unused and #ifdef are OK to me.

Yes, and so you should use only #ifdef here as Arnd confirmed. You shouldn't be
using __maybe_unused as there is nothing confusing here related to the macros.

-- 
viresh


Re: [PATCH v10] i2c: virtio: add a virtio i2c frontend driver

2021-03-23 Thread Jie Deng



On 2021/3/24 11:52, Viresh Kumar wrote:

On 24-03-21, 08:53, Jie Deng wrote:

On 2021/3/23 17:38, Viresh Kumar wrote:

On 23-03-21, 14:31, Viresh Kumar wrote:

On 23-03-21, 22:19, Jie Deng wrote:

+static int virtio_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int 
num)
+{
+   struct virtio_i2c *vi = i2c_get_adapdata(adap);
+   struct virtqueue *vq = vi->vq;
+   struct virtio_i2c_req *reqs;
+   unsigned long time_left;
+   int ret, nr;
+
+   reqs = kcalloc(num, sizeof(*reqs), GFP_KERNEL);
+   if (!reqs)
+   return -ENOMEM;
+
+   mutex_lock(>lock);
+
+   ret = virtio_i2c_send_reqs(vq, reqs, msgs, num);
+   if (ret == 0)
+   goto err_unlock_free;
+
+   nr = ret;
+   reinit_completion(>completion);

I think I may have found a possible bug here. This reinit_completion() must
happen before we call virtio_i2c_send_reqs(). It is certainly possible (surely
in corner cases) that virtio_i2c_msg_done() may get called right after
virtio_i2c_send_reqs() and before we were able to call reinit_completion(). And
in that case we will never see the completion happen at all.


+   virtqueue_kick(vq);

I may have misread this. Can the actually start before virtqueue_kick() is
called ?

I didn't write it properly here. I wanted to say,

"Can the _transfer_ actually start before virtqueue_kick() is called ?"
  



It can't start until the virtqueue_kick() is called. Call virtqueue_kick 
then wait.





Re: [PATCH v6 02/10] scsi: ufshpb: Add host control mode support to rsp_upiu

2021-03-23 Thread Can Guo

On 2021-03-24 11:31, Zang Leigang wrote:

On Mon, Mar 22, 2021 at 10:10:36AM +0200, Avri Altman wrote:

In device control mode, the device may recommend the host to either
activate or inactivate a region, and the host should follow. Meaning
those are not actually recommendations, but more of instructions.

On the contrary, in host control mode, the recommendation protocol is
slightly changed:
a) The device may only recommend the host to update a subregion of an
   already-active region. And,
b) The device may *not* recommend to inactivate a region.

Furthermore, in host control mode, the host may choose not to follow 
any
of the device's recommendations. However, in case of a recommendation 
to

update an active and clean subregion, it is better to follow those
recommendation because otherwise the host has no other way to know 
that

some internal relocation took place.

Signed-off-by: Avri Altman 
---
 drivers/scsi/ufs/ufshpb.c | 34 +-
 drivers/scsi/ufs/ufshpb.h |  2 ++
 2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c
index fb10afcbb49f..d4f0bb6d8fa1 100644
--- a/drivers/scsi/ufs/ufshpb.c
+++ b/drivers/scsi/ufs/ufshpb.c
@@ -166,6 +166,8 @@ static void ufshpb_set_ppn_dirty(struct ufshpb_lu 
*hpb, int rgn_idx,

else
set_bit_len = cnt;

+   set_bit(RGN_FLAG_DIRTY, >rgn_flags);
+
if (rgn->rgn_state != HPB_RGN_INACTIVE &&
srgn->srgn_state == HPB_SRGN_VALID)
bitmap_set(srgn->mctx->ppn_dirty, srgn_offset, set_bit_len);
@@ -235,6 +237,11 @@ static bool ufshpb_test_ppn_dirty(struct 
ufshpb_lu *hpb, int rgn_idx,

return false;
 }

+static inline bool is_rgn_dirty(struct ufshpb_region *rgn)
+{
+   return test_bit(RGN_FLAG_DIRTY, >rgn_flags);
+}
+
 static int ufshpb_fill_ppn_from_page(struct ufshpb_lu *hpb,
 struct ufshpb_map_ctx *mctx, int pos,
 int len, u64 *ppn_buf)
@@ -713,6 +720,7 @@ static void ufshpb_put_map_req(struct ufshpb_lu 
*hpb,

 static int ufshpb_clear_dirty_bitmap(struct ufshpb_lu *hpb,
 struct ufshpb_subregion *srgn)
 {
+   struct ufshpb_region *rgn;
u32 num_entries = hpb->entries_per_srgn;

if (!srgn->mctx) {
@@ -726,6 +734,10 @@ static int ufshpb_clear_dirty_bitmap(struct 
ufshpb_lu *hpb,

num_entries = hpb->last_srgn_entries;

bitmap_zero(srgn->mctx->ppn_dirty, num_entries);
+
+   rgn = hpb->rgn_tbl + srgn->rgn_idx;
+   clear_bit(RGN_FLAG_DIRTY, >rgn_flags);
+
return 0;
 }

@@ -1245,6 +1257,18 @@ static void ufshpb_rsp_req_region_update(struct 
ufshpb_lu *hpb,

srgn_i =
be16_to_cpu(rsp_field->hpb_active_field[i].active_srgn);

+   rgn = hpb->rgn_tbl + rgn_i;
+   if (hpb->is_hcm &&
+   (rgn->rgn_state != HPB_RGN_ACTIVE || is_rgn_dirty(rgn))) {
+   /*
+* in host control mode, subregion activation
+* recommendations are only allowed to active regions.
+* Also, ignore recommendations for dirty regions - the
+* host will make decisions concerning those by himself
+*/
+   continue;
+   }
+


Hi Avri, host control mode also need the recommendations from device,
because the bkops would make the ppn invalid, is that right?


Right, but ONLY recommandations to ACTIVE regions are of host's interest
in host control mode. For those inactive regions, host makes its own 
decisions.


Can Guo.




dev_dbg(>sdev_ufs_lu->sdev_dev,
"activate(%d) region %d - %d\n", i, rgn_i, srgn_i);

@@ -1252,7 +1276,6 @@ static void ufshpb_rsp_req_region_update(struct 
ufshpb_lu *hpb,

ufshpb_update_active_info(hpb, rgn_i, srgn_i);
spin_unlock(>rsp_list_lock);

-   rgn = hpb->rgn_tbl + rgn_i;
srgn = rgn->srgn_tbl + srgn_i;

/* blocking HPB_READ */
@@ -1263,6 +1286,14 @@ static void ufshpb_rsp_req_region_update(struct 
ufshpb_lu *hpb,

hpb->stats.rb_active_cnt++;
}

+   if (hpb->is_hcm) {
+   /*
+* in host control mode the device is not allowed to inactivate
+* regions
+*/
+   goto out;
+   }
+
for (i = 0; i < rsp_field->inactive_rgn_cnt; i++) {
rgn_i = be16_to_cpu(rsp_field->hpb_inactive_field[i]);
dev_dbg(>sdev_ufs_lu->sdev_dev,
@@ -1287,6 +1318,7 @@ static void ufshpb_rsp_req_region_update(struct 
ufshpb_lu *hpb,

hpb->stats.rb_inactive_cnt++;
}

+out:
dev_dbg(>sdev_ufs_lu->sdev_dev, "Noti: #ACT %u #INACT %u\n",
rsp_field->active_rgn_cnt, 

Re: [PATCH v2] drivers/media/pci/bt8xx/bttv-cards: fix typos

2021-03-23 Thread Randy Dunlap
On 3/23/21 8:29 PM, Xiaofeng Cao wrote:
> change 'vodeo' to 'video'
> change 'nevery'to 'never'
> change 'is'to 'it'
> change 'connevted' to 'connected'
> change 'swichers'  to 'switchers'
> change 'strucure'  to 'structure'
> change 'unblanced' to 'unbalanced'
> change 'fonctionality' to 'functionality'
> 
> Signed-off-by: Xiaofeng Cao 

LGTM. Thanks.

Acked-by: Randy Dunlap 

> ---
> v2: resume space and change 'USED' to 'USE'
>  drivers/media/pci/bt8xx/bttv-cards.c | 20 ++--
>  1 file changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/media/pci/bt8xx/bttv-cards.c 
> b/drivers/media/pci/bt8xx/bttv-cards.c
> index ca20b806e82d..c2b5ab287dd7 100644
> --- a/drivers/media/pci/bt8xx/bttv-cards.c
> +++ b/drivers/media/pci/bt8xx/bttv-cards.c
> @@ -2011,7 +2011,7 @@ struct tvcard bttv_tvcards[] = {
>   /* .audio_inputs= 0, */
>   .svhs   = 9,
>   .gpiomask   = 0x00,
> - .gpiomask2  = 0x03, /* used for external vodeo mux */
> + .gpiomask2  = 0x03, /* used for external video mux */
>   .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 0),
>   .muxsel_hook= phytec_muxsel,
>   .gpiomux= { 0, 0, 0, 0 }, /* card has no audio */
> @@ -2025,7 +2025,7 @@ struct tvcard bttv_tvcards[] = {
>   /* .audio_inputs= 0, */
>   .svhs   = 9,
>   .gpiomask   = 0x00,
> - .gpiomask2  = 0x03, /* used for external vodeo mux */
> + .gpiomask2  = 0x03, /* used for external video mux */
>   .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 1),
>   .muxsel_hook= phytec_muxsel,
>   .gpiomux= { 0, 0, 0, 0 }, /* card has no audio */
> @@ -2180,8 +2180,8 @@ struct tvcard bttv_tvcards[] = {
>   [BTTV_BOARD_PICOLO_TETRA_CHIP] = {
>   /*Eric DEBIEF */
>   /*EURESYS Picolo Tetra : 4 Conexant Fusion 878A, no audio, 
> video input set with analog multiplexers GPIO controlled*/
> - /* adds picolo_tetra_muxsel(), picolo_tetra_init(), the 
> following declaration strucure, and #define BTTV_BOARD_PICOLO_TETRA_CHIP*/
> - /*0x79 in bttv.h*/
> + /*adds picolo_tetra_muxsel(), picolo_tetra_init(), the 
> following declaration*/
> + /*structure and #define BTTV_BOARD_PICOLO_TETRA_CHIP 0x79 in 
> bttv.h*/
>   .name   = "Euresys Picolo Tetra",
>   .video_inputs   = 4,
>   /* .audio_inputs= 0, */
> @@ -2506,7 +2506,7 @@ struct tvcard bttv_tvcards[] = {
>one external BNC composite input (mux 2)
>three internal composite inputs (unknown muxes)
>an 18-bit stereo A/D (CS5331A), which has:
> -one external stereo unblanced (RCA) audio connection
> +one external stereo unbalanced (RCA) audio connection
>  one (or 3?) internal stereo balanced (XLR) audio connection
>  input is selected via gpio to a 14052B mux
>(mask=0x300, unbal=0x000, bal=0x100, ??=0x200,0x300)
> @@ -3924,7 +3924,7 @@ static void osprey_eeprom(struct bttv *btv, const u8 
> ee[256])
>   u32 serial = 0;
>   int cardid = -1;
>  
> - /* This code will nevery actually get called in this case */
> + /* This code will never actually get called in this case */
>   if (btv->c.type == BTTV_BOARD_UNKNOWN) {
>   /* this might be an antique... check for MMAC label in eeprom */
>   if (!strncmp(ee, "MMAC", 4)) {
> @@ -4086,7 +4086,7 @@ static void avermedia_eeprom(struct bttv *btv)
>  /*
>   * For Voodoo TV/FM and Voodoo 200.  These cards' tuners use a TDA9880
>   * analog demod, which is not I2C controlled like the newer and more common
> - * TDA9887 series.  Instead is has two tri-state input pins, S0 and S1,
> + * TDA9887 series.  Instead it has two tri-state input pins, S0 and S1,
>   * that control the IF for the video and audio.  Apparently, bttv GPIO
>   * 0x1 is connected to S0.  S0 low selects a 38.9 MHz VIF for B/G/D/K/I
>   * (i.e., PAL) while high selects 45.75 MHz for M/N (i.e., NTSC).
> @@ -4144,7 +4144,7 @@ static void init_PXC200(struct bttv *btv)
>   int tmp;
>   u32 val;
>  
> - /* Initialise GPIO-connevted stuff */
> + /* Initialise GPIO-connected stuff */
>   gpio_inout(0xff, (1<<13));
>   gpio_write(0);
>   udelay(3);
> @@ -4580,7 +4580,7 @@ static void xguard_muxsel(struct bttv *btv, unsigned 
> int input)
>  }
>  static void picolo_tetra_init(struct bttv *btv)
>  {
> - /*This is the video input redirection fonctionality : I DID NOT USED 
> IT. */
> + /*This is the video input redirection functionality : I DID NOT USE IT. 
> */
>   btwrite (0x08<<16,BT848_GPIO_DATA);/*GPIO[19] [==> 4053 B+C] set to 1 */
>   btwrite (0x04<<16,BT848_GPIO_DATA);/*GPIO[18] [==> 4053 A]  set 

Re: [PATCH v10] i2c: virtio: add a virtio i2c frontend driver

2021-03-23 Thread Viresh Kumar
On 24-03-21, 08:53, Jie Deng wrote:
> 
> On 2021/3/23 17:38, Viresh Kumar wrote:
> > On 23-03-21, 14:31, Viresh Kumar wrote:
> > > On 23-03-21, 22:19, Jie Deng wrote:
> > > > +static int virtio_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg 
> > > > *msgs, int num)
> > > > +{
> > > > +   struct virtio_i2c *vi = i2c_get_adapdata(adap);
> > > > +   struct virtqueue *vq = vi->vq;
> > > > +   struct virtio_i2c_req *reqs;
> > > > +   unsigned long time_left;
> > > > +   int ret, nr;
> > > > +
> > > > +   reqs = kcalloc(num, sizeof(*reqs), GFP_KERNEL);
> > > > +   if (!reqs)
> > > > +   return -ENOMEM;
> > > > +
> > > > +   mutex_lock(>lock);
> > > > +
> > > > +   ret = virtio_i2c_send_reqs(vq, reqs, msgs, num);
> > > > +   if (ret == 0)
> > > > +   goto err_unlock_free;
> > > > +
> > > > +   nr = ret;
> > > > +   reinit_completion(>completion);
> > > I think I may have found a possible bug here. This reinit_completion() 
> > > must
> > > happen before we call virtio_i2c_send_reqs(). It is certainly possible 
> > > (surely
> > > in corner cases) that virtio_i2c_msg_done() may get called right after
> > > virtio_i2c_send_reqs() and before we were able to call 
> > > reinit_completion(). And
> > > in that case we will never see the completion happen at all.
> > > 
> > > > +   virtqueue_kick(vq);
> > I may have misread this. Can the actually start before virtqueue_kick() is
> > called ?

I didn't write it properly here. I wanted to say,

"Can the _transfer_ actually start before virtqueue_kick() is called ?"
 
> No. It starts when wait_for_completion_timeout is called.

No, the transfer doesn't have anything to do with wait_for_completion_timeout().
And if complete() gets called before wait_for_completion_timeout() is called,
then wait_for_completion_timeout() will simply return back.

> So it should be fine here.
> 
> 
> >   If not, then completion may be fine where it is.
> > 

-- 
viresh


Re: [PATCH] mm, thp: Relax the VM_DENYWRITE constraint on file-backed THPs

2021-03-23 Thread William Kucharski
I like this, it reminds me of the changes I proposed a few years ago to try
to automatically map read-only text regions of appropriate sizes and
alignment with THPs.

My concern had always been whether commercial software and distro vendors
would buy into supplying the appropriate linker flags when compiling; your
solution is at the very least a good head start down that road.

Matthew Wilcox and I had noticed a lot of ordinary apps such as gcc, Chrome
and Firefox would benefit from such mappings; have you tried building any
of those with the appropriate linker flag to see how they might benefit
from the change?

Thanks,
-- Bill


> On Mar 22, 2021, at 3:58 PM, Collin Fijalkovich  
> wrote:
> 
> Transparent huge pages are supported for read-only non-shmem filesystems,
> but are only used for vmas with VM_DENYWRITE. This condition ensures that
> file THPs are protected from writes while an application is running
> (ETXTBSY).  Any existing file THPs are then dropped from the page cache
> when a file is opened for write in do_dentry_open(). Since sys_mmap
> ignores MAP_DENYWRITE, this constrains the use of file THPs to vmas
> produced by execve().
> 
> Systems that make heavy use of shared libraries (e.g. Android) are unable
> to apply VM_DENYWRITE through the dynamic linker, preventing them from
> benefiting from the resultant reduced contention on the TLB.
> 
> This patch reduces the constraint on file THPs allowing use with any
> executable mapping from a file not opened for write (see
> inode_is_open_for_write()). It also introduces additional conditions to
> ensure that files opened for write will never be backed by file THPs.
> 
> Restricting the use of THPs to executable mappings eliminates the risk that
> a read-only file later opened for write would encounter significant
> latencies due to page cache truncation.
> 
> The ld linker flag '-z max-page-size=(hugepage size)' can be used to
> produce executables with the necessary layout. The dynamic linker must
> map these file's segments at a hugepage size aligned vma for the mapping to
> be backed with THPs.
> 
> Signed-off-by: Collin Fijalkovich 
> ---
> fs/open.c   | 13 +++--
> mm/khugepaged.c | 16 +++-
> 2 files changed, 26 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/open.c b/fs/open.c
> index e53af13b5835..f76e960d10ea 100644
> --- a/fs/open.c
> +++ b/fs/open.c
> @@ -852,8 +852,17 @@ static int do_dentry_open(struct file *f,
>* XXX: Huge page cache doesn't support writing yet. Drop all page
>* cache for this file before processing writes.
>*/
> - if ((f->f_mode & FMODE_WRITE) && filemap_nr_thps(inode->i_mapping))
> - truncate_pagecache(inode, 0);
> + if (f->f_mode & FMODE_WRITE) {
> + /*
> +  * Paired with smp_mb() in collapse_file() to ensure nr_thps
> +  * is up to date and the update to i_writecount by
> +  * get_write_access() is visible. Ensures subsequent insertion
> +  * of THPs into the page cache will fail.
> +  */
> + smp_mb();
> + if (filemap_nr_thps(inode->i_mapping))
> + truncate_pagecache(inode, 0);
> + }
> 
>   return 0;
> 
> diff --git a/mm/khugepaged.c b/mm/khugepaged.c
> index a7d6cb912b05..4c7cc877d5e3 100644
> --- a/mm/khugepaged.c
> +++ b/mm/khugepaged.c
> @@ -459,7 +459,8 @@ static bool hugepage_vma_check(struct vm_area_struct *vma,
> 
>   /* Read-only file mappings need to be aligned for THP to work. */
>   if (IS_ENABLED(CONFIG_READ_ONLY_THP_FOR_FS) && vma->vm_file &&
> - (vm_flags & VM_DENYWRITE)) {
> + !inode_is_open_for_write(vma->vm_file->f_inode) &&
> + (vm_flags & VM_EXEC)) {
>   return IS_ALIGNED((vma->vm_start >> PAGE_SHIFT) - vma->vm_pgoff,
>   HPAGE_PMD_NR);
>   }
> @@ -1872,6 +1873,19 @@ static void collapse_file(struct mm_struct *mm,
>   else {
>   __mod_lruvec_page_state(new_page, NR_FILE_THPS, nr);
>   filemap_nr_thps_inc(mapping);
> + /*
> +  * Paired with smp_mb() in do_dentry_open() to ensure
> +  * i_writecount is up to date and the update to nr_thps is
> +  * visible. Ensures the page cache will be truncated if the
> +  * file is opened writable.
> +  */
> + smp_mb();
> + if (inode_is_open_for_write(mapping->host)) {
> + result = SCAN_FAIL;
> + __mod_lruvec_page_state(new_page, NR_FILE_THPS, -nr);
> + filemap_nr_thps_dec(mapping);
> + goto xa_locked;
> + }
>   }
> 
>   if (nr_none) {
> -- 
> 2.31.0.rc2.261.g7f71774620-goog
> 
> 



Re: [PATCH v2 0/5] arm64: sunxi: Enable the sun4i timer

2021-03-23 Thread Samuel Holland
On 3/22/21 9:18 AM, Daniel Lezcano wrote:
> On 22/03/2021 05:47, Samuel Holland wrote:
>> In preparation for adding CPU idle states, hook up the sun4i timer.
>> Having a non-c3stop clockevent source available is necessary for all
>> CPUs to simultaneously enter a local-timer-stop idle state.
> 
> Why simultaneously ?
Because the CPU providing (the hrtimer providing) the broadcast timer
cannot enter an idle state which would stop that timer. So in my case,
with 4 CPUs, I was seeing at most 3 CPUs enter idle at any given time.
This prevented any cluster-level idle states from doing anything. After
applying this series, I was able to observe the whole cluster powering
down when appropriate.

Regards,
Samuel

>> Changes from v1:
>>   - Removed H616 changes (depends on an unmerged patch set)
>>   - Reworded the patch 4-5 commit messages for clarity
>>   - Added Acked-by tags
>>
>> Samuel Holland (5):
>>   dt-bindings: timer: Simplify conditional expressions
>>   dt-bindings: timer: Add compatibles for sun50i timers
>>   arm64: dts: allwinner: a64: Sort watchdog node
>>   arm64: dts: allwinner: Add sun4i MMIO timer nodes
>>   arm64: sunxi: Build the sun4i timer driver
>>
>>  .../timer/allwinner,sun4i-a10-timer.yaml  | 42 +--
>>  arch/arm64/Kconfig.platforms  |  1 +
>>  arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 25 +++
>>  arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi  |  9 
>>  4 files changed, 46 insertions(+), 31 deletions(-)
>>
> 
> 



Re: [PATCH v4 RESEND 3/5] perf/x86/lbr: Move cpuc->lbr_xsave allocation out of sleeping region

2021-03-23 Thread Like Xu

Hi Namhyung,

On 2021/3/24 9:32, Namhyung Kim wrote:

Hello,

On Mon, Mar 22, 2021 at 3:14 PM Like Xu  wrote:

+void reserve_lbr_buffers(struct perf_event *event)
+{
+   struct kmem_cache *kmem_cache = x86_get_pmu()->task_ctx_cache;
+   struct cpu_hw_events *cpuc;
+   int cpu;
+
+   if (!static_cpu_has(X86_FEATURE_ARCH_LBR))
+   return;
+
+   for_each_possible_cpu(cpu) {
+   cpuc = per_cpu_ptr(_hw_events, cpu);
+   if (kmem_cache && !cpuc->lbr_xsave && !event->attr.precise_ip)
+   cpuc->lbr_xsave = kmem_cache_alloc(kmem_cache, 
GFP_KERNEL);
+   }
+}


I think we should use kmem_cache_alloc_node().


"kmem_cache_alloc_node - Allocate an object on the specified node"

The reserve_lbr_buffers() is called in __x86_pmu_event_init().
When the LBR perf_event is scheduled to another node, it seems
that we will not call init() and allocate again.

Do you mean use kmem_cache_alloc_node() for each numa_nodes_parsed ?



Thanks,
Namhyung





Re: [PATCH 0/6] i2c: mpc: Refactor to improve responsiveness

2021-03-23 Thread Chris Packham

On 23/03/21 5:33 pm, Chris Packham wrote:
> The "meat" of this series is in the last patch which is the change that
> actually starts making use of the interrupts to drive a state machine.
> The dt-bindings patches can probably go in at any time. The rest of the
> series isn't dependent on them.
>
> I've tested it on a T2081 based system with a number of i2c and smbus
> devices.  Its the end of my work day so I figured I'd get this out now
> but I'll do some more testing on a P2041 board and a few different i2c
> devices tomorrow.

I've done more testing on a T2081 and P2041 board. Both look good.

I've had some feedback from Rob on the dt-bindings which I think I've 
got sorted now. I've got a couple of minor cosmetic changes to 6/6 but 
I'll hold fire on sending a v2 to give people a chance to look at the 
functional changes.

> Chris Packham (6):
>dt-bindings: i2c-mpc: Document interrupt property as required
>dt-bindings: i2c: convert i2c-mpc to json-schema
>i2c: mpc: Make use of i2c_recover_bus()
>i2c: mpc: make interrupt mandatory and remove polling code
>i2c: mpc: use device managed APIs
>i2c: mpc: Interrupt driven transfer
>
>   .../devicetree/bindings/i2c/i2c-mpc.txt   |  62 ---
>   .../devicetree/bindings/i2c/i2c-mpc.yaml  |  99 
>   drivers/i2c/busses/i2c-mpc.c  | 513 ++
>   3 files changed, 373 insertions(+), 301 deletions(-)
>   delete mode 100644 Documentation/devicetree/bindings/i2c/i2c-mpc.txt
>   create mode 100644 Documentation/devicetree/bindings/i2c/i2c-mpc.yaml
>

Re: [PATCH v7 2/2] ARM: ftrace: Add MODULE_PLTS support

2021-03-23 Thread Florian Fainelli
Hi Qais,

On 3/23/2021 3:22 PM, Qais Yousef wrote:
> Hi Alexander
> 
> On 03/22/21 18:02, Alexander Sverdlin wrote:
>> Hi Qais,
>>
>> On 22/03/2021 17:32, Qais Yousef wrote:
>>> Yes you're right. I was a bit optimistic on CONFIG_DYNAMIC_FTRACE will imply
>>> CONFIG_ARM_MODULE_PLTS is enabled too.
>>>
>>> It only has an impact on reducing ifdefery when calling
>>>
>>> ftrace_call_replace_mod(rec->arch.mod, ...)
>>>
>>> Should be easy to wrap rec->arch.mod with its own accessor that will return
>>> NULL if !CONFIG_ARM_MODULE_PLTS or just ifdef the functions.
>>>
>>> Up to Alexander to pick what he prefers :-)
>>
>> well, I of course prefer v7 as-is, because this review is running longer 
>> than two
>> years and I actually hope these patches to be finally merged at some point.
>> But you are welcome to optimize them with follow up patches :)
> 
> I appreciate that and thanks a lot for your effort. My attempt to review and
> test here is to help in getting this merged.
> 
> FWIW my main concern is about duplicating the range check in
> ftrace_call_replace() and using magic values that already exist in
> __arm_gen_branch_{arm, thumb2}() and better remain encapsulated there.

Your patch in addition to Alexander's patch work for me as well, so feel
free to add a:

Tested-by: Florian Fainelli 

FWIW, what is nice about Alexander's original patch is that it applies
relatively cleanly to older kernels as well where this is equally
needed. There is not currently any Fixes: tag being provided but maybe
we should amend the second patch with one?

Thanks!

> 
> Thanks
> 
> --
> Qais Yousef
> 
> ->8--
> 
> 
> diff --git a/arch/arm/include/asm/ftrace.h b/arch/arm/include/asm/ftrace.h
> index a4dbac07e4ef..8545b3ff8317 100644
> --- a/arch/arm/include/asm/ftrace.h
> +++ b/arch/arm/include/asm/ftrace.h
> @@ -25,6 +25,27 @@ static inline unsigned long ftrace_call_adjust(unsigned 
> long addr)
>   /* With Thumb-2, the recorded addresses have the lsb set */
>   return addr & ~1;
>  }
> +
> +#ifdef CONFIG_ARM_MODULE_PLTS
> +static inline void ftrace_set_mod(struct dyn_arch_ftrace *arch, struct 
> module *mod)
> +{
> + arch->mod = mod;
> +}
> +
> +static inline struct module *ftrace_get_mod(struct dyn_arch_ftrace *arch)
> +{
> + return arch->mod;
> +}
> +#else
> +static inline void ftrace_set_mod(struct dyn_arch_ftrace *arch, struct 
> module *mod)
> +{
> +}
> +
> +static inline struct module *ftrace_get_mod(struct dyn_arch_ftrace *arch)
> +{
> + return NULL;
> +}
> +#endif
>  #endif
>  
>  #endif
> diff --git a/arch/arm/include/asm/insn.h b/arch/arm/include/asm/insn.h
> index f20e08ac85ae..71c3edefe629 100644
> --- a/arch/arm/include/asm/insn.h
> +++ b/arch/arm/include/asm/insn.h
> @@ -13,18 +13,24 @@ arm_gen_nop(void)
>  }
>  
>  unsigned long
> -__arm_gen_branch(unsigned long pc, unsigned long addr, bool link);
> +__arm_gen_branch(unsigned long pc, unsigned long addr, bool link, bool 
> check);
>  
>  static inline unsigned long
>  arm_gen_branch(unsigned long pc, unsigned long addr)
>  {
> - return __arm_gen_branch(pc, addr, false);
> + return __arm_gen_branch(pc, addr, false, true);
>  }
>  
>  static inline unsigned long
>  arm_gen_branch_link(unsigned long pc, unsigned long addr)
>  {
> - return __arm_gen_branch(pc, addr, true);
> + return __arm_gen_branch(pc, addr, true, true);
> +}
> +
> +static inline unsigned long
> +arm_gen_branch_link_nocheck(unsigned long pc, unsigned long addr)
> +{
> + return __arm_gen_branch(pc, addr, true, false);
>  }
>  
>  #endif
> diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
> index fa867a57100f..63ea34edd222 100644
> --- a/arch/arm/kernel/ftrace.c
> +++ b/arch/arm/kernel/ftrace.c
> @@ -70,20 +70,28 @@ int ftrace_arch_code_modify_post_process(void)
>  
>  static unsigned long ftrace_call_replace(unsigned long pc, unsigned long 
> addr)
>  {
> - s32 offset = addr - pc;
> - s32 blim = 0xfe08;
> - s32 flim = 0x0204;
> + return arm_gen_branch_link(pc, addr);
> +}
>  
> - if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
> - blim = 0xff04;
> - flim = 0x0102;
> - }
> +static unsigned long
> +ftrace_call_replace_mod(struct module *mod, unsigned long pc, unsigned long 
> addr)
> +{
> +#ifdef CONFIG_ARM_MODULE_PLTS
> + unsigned long new;
>  
> - if (IS_ENABLED(CONFIG_ARM_MODULE_PLTS) &&
> - (offset < blim || offset > flim))
> - return 0;
> + if (likely(!mod))
> + return arm_gen_branch_link(pc, addr);
>  
> + new = arm_gen_branch_link_nocheck(pc, addr);
> + if (!new) {
> + addr = get_module_plt(mod, pc, addr);
> + new = arm_gen_branch_link(pc, addr);
> + }
> +
> + return new;
> +#else
>   return arm_gen_branch_link(pc, addr);
> +#endif
>  }
>  
>  static int ftrace_modify_code(unsigned long pc, unsigned long old,
> @@ -141,18 +149,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned 

[tip:sched/core] BUILD SUCCESS acb4decc1e900468d51b33c5f1ee445278e716a7

2021-03-23 Thread kernel test robot
allyesconfig
arc defconfig
sh   allmodconfig
parisc  defconfig
s390 allyesconfig
s390 allmodconfig
parisc   allyesconfig
sparcallyesconfig
sparc   defconfig
i386   tinyconfig
i386defconfig
mips allyesconfig
mips allmodconfig
powerpc  allyesconfig
powerpc  allmodconfig
powerpc   allnoconfig
x86_64   randconfig-a002-20210323
x86_64   randconfig-a003-20210323
x86_64   randconfig-a006-20210323
x86_64   randconfig-a001-20210323
x86_64   randconfig-a004-20210323
x86_64   randconfig-a005-20210323
i386 randconfig-a003-20210323
i386 randconfig-a004-20210323
i386 randconfig-a001-20210323
i386 randconfig-a002-20210323
i386 randconfig-a006-20210323
i386 randconfig-a005-20210323
i386 randconfig-a014-20210323
i386 randconfig-a011-20210323
i386 randconfig-a015-20210323
i386 randconfig-a016-20210323
i386 randconfig-a012-20210323
i386 randconfig-a013-20210323
riscvnommu_k210_defconfig
riscvnommu_virt_defconfig
riscv allnoconfig
riscv   defconfig
x86_64rhel-7.6-kselftests
x86_64  defconfig
x86_64   rhel-8.3
x86_64  rhel-8.3-kbuiltin
x86_64  kexec

clang tested configs:
x86_64   randconfig-a012-20210323
x86_64   randconfig-a015-20210323
x86_64   randconfig-a013-20210323
x86_64   randconfig-a014-20210323
x86_64   randconfig-a011-20210323
x86_64   randconfig-a016-20210323

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


[tip:x86/core] BUILD SUCCESS 6256e668b7af9d81472e03c6a171630c08f8858a

2021-03-23 Thread kernel test robot
 allmodconfig
parisc   allyesconfig
sparcallyesconfig
sparc   defconfig
i386   tinyconfig
i386defconfig
mips allyesconfig
mips allmodconfig
powerpc  allyesconfig
powerpc  allmodconfig
powerpc   allnoconfig
x86_64   randconfig-a002-20210323
x86_64   randconfig-a003-20210323
x86_64   randconfig-a006-20210323
x86_64   randconfig-a001-20210323
x86_64   randconfig-a004-20210323
x86_64   randconfig-a005-20210323
i386 randconfig-a003-20210323
i386 randconfig-a004-20210323
i386 randconfig-a001-20210323
i386 randconfig-a002-20210323
i386 randconfig-a006-20210323
i386 randconfig-a005-20210323
i386 randconfig-a004-20210324
i386 randconfig-a003-20210324
i386 randconfig-a001-20210324
i386 randconfig-a002-20210324
i386 randconfig-a006-20210324
i386 randconfig-a005-20210324
i386 randconfig-a014-20210323
i386 randconfig-a011-20210323
i386 randconfig-a015-20210323
i386 randconfig-a016-20210323
i386 randconfig-a012-20210323
i386 randconfig-a013-20210323
riscvnommu_k210_defconfig
riscvnommu_virt_defconfig
riscv allnoconfig
riscv   defconfig
x86_64rhel-7.6-kselftests
x86_64  defconfig
x86_64   rhel-8.3
x86_64  rhel-8.3-kbuiltin
x86_64  kexec

clang tested configs:
x86_64   randconfig-a012-20210323
x86_64   randconfig-a015-20210323
x86_64   randconfig-a013-20210323
x86_64   randconfig-a014-20210323
x86_64   randconfig-a011-20210323
x86_64   randconfig-a016-20210323

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


Re: [PATCH 2/6] dt-bindings: i2c: convert i2c-mpc to json-schema

2021-03-23 Thread Chris Packham

On 24/03/21 10:59 am, Chris Packham wrote:
>
> On 24/03/21 10:15 am, Rob Herring wrote:
>> On Tue, Mar 23, 2021 at 05:33:27PM +1300, Chris Packham wrote:
>>> Convert i2c-mpc to YAML.
>>>
>>> Signed-off-by: Chris Packham 
>>> ---

>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/i2c/i2c-mpc.yaml
>>> @@ -0,0 +1,99 @@
>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>> +%YAML 1.2
>>> +---
>>> +$id: http://devicetree.org/schemas/i2c/i2c-mpc.yaml#
>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>> +
>>> +title: I2C-Bus adapter for MPC824x/83xx/85xx/86xx/512x/52xx SoCs
>>> +
>>> +maintainers:
>>> +  - Chris Packham 
>>> +
>>> +allOf:
>>> +  - $ref: /schemas/i2c/i2c-controller.yaml#
>>> +
>>> +properties:
>>> +  compatible:
>>> +    anyOf:
>>> +  - items:
>>> +    - enum:
>>> +  - mpc5200-i2c
>>> +  - fsl,mpc5200b-i2c
>>> +  - fsl,mpc5200-i2c
>>> +  - fsl,mpc5121-i2c
>>> +  - fsl,mpc8313-i2c
>>> +  - fsl,mpc8543-i2c
>>> +  - fsl,mpc8544-i2c
>>> +
>>> +    - const: fsl-i2c
>>> +
>>> +  - contains:
>>> +  const: fsl-i2c
>>> +    minItems: 1
>>> +    maxItems: 4
>> Can't we drop this and list out any other compatibles?
>
> I'm struggling a little bit with how to get the schema right to allow 
> one or more of a set of compatible values.
>
> Basically I want to allow 'compatible = "fsl-i2c";' or 'compatible = 
> "fsl,mpc8544-i2c", "fsl-i2c";' but disallow 'compatible = "foobar", 
> "fsl-i2c";'

This is what I've ended up with

properties:
compatible:
oneOf:
   - items:
   - enum:
   - mpc5200-i2c
   - fsl,mpc5200-i2c
   - fsl,mpc5121-i2c
   - fsl,mpc8313-i2c
   - fsl,mpc8543-i2c
   - fsl,mpc8544-i2c
   - fsl-i2c
   - const: fsl-i2c
   - items:
   - const: fsl,mpc5200b-i2c
   - const: fsl,mpc5200-i2c
   - const: fsl-i2c

It passes `make dt_binding_check` and rejects things when I add other 
non-documented values to the compatible property. I did struggle with it 
so I'm not confident it's the best approach but it seems to work.


Re: [PATCH v4 RESEND 4/5] perf/x86/lbr: Skip checking for the existence of LBR_TOS for Arch LBR

2021-03-23 Thread Like Xu

On 2021/3/24 5:49, Peter Zijlstra wrote:

On Mon, Mar 22, 2021 at 02:06:34PM +0800, Like Xu wrote:

The Architecture LBR does not have MSR_LBR_TOS (0x01c9). KVM will
generate #GP for this MSR access, thereby preventing the initialization
of the guest LBR.

Fixes: 47125db27e47 ("perf/x86/intel/lbr: Support Architectural LBR")
Signed-off-by: Like Xu 
Reviewed-by: Kan Liang 
Reviewed-by: Andi Kleen 
---
  arch/x86/events/intel/core.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 382dd3994463..7f6d748421f2 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -5740,7 +5740,8 @@ __init int intel_pmu_init(void)
 * Check all LBR MSR here.
 * Disable LBR access if any LBR MSRs can not be accessed.
 */
-   if (x86_pmu.lbr_nr && !check_msr(x86_pmu.lbr_tos, 0x3UL))
+   if (x86_pmu.lbr_nr && !boot_cpu_has(X86_FEATURE_ARCH_LBR) &&
+   !check_msr(x86_pmu.lbr_tos, 0x3UL))
x86_pmu.lbr_nr = 0;


But when ARCH_LBR we don't set lbr_tos, so we check MSR 0x000, not 0x1c9.


It's true.



Do we want check_msr() to ignore msr==0 ?


Considering another target of check_msr() is for uncore msrs,
how about this change:

diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 759226919a36..06fa31a01a5b 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -4704,10 +4704,10 @@ static bool check_msr(unsigned long msr, u64 mask)
u64 val_old, val_new, val_tmp;

/*
-* Disable the check for real HW, so we don't
+* Disable the check for real HW or non-sense msr, so we don't
 * mess with potentionaly enabled registers:
 */
-   if (!boot_cpu_has(X86_FEATURE_HYPERVISOR))
+   if (!boot_cpu_has(X86_FEATURE_HYPERVISOR) || !msr)
return true;

/*



Additionally, do we want a check for lbr_info ?


I am not inclined to do this because we may have
virtualized model-specific guest LBR support
which may break the cpu_model assumption.




for (i = 0; i < x86_pmu.lbr_nr; i++) {
if (!(check_msr(x86_pmu.lbr_from + i, 0xUL) &&
--
2.29.2





Re: [PATCH] drm/imx: fix out of bounds array access warning

2021-03-23 Thread Liu Ying
Hi Arnd,

Thanks for your patch.

It would be good to improve the patch's head line to something like:
drm/imx: imx-ldb: fix out of bounds array access warning

Regards,
Liu Ying

On Tue, 2021-03-23 at 14:05 +0100, Arnd Bergmann wrote:
> From: Arnd Bergmann 
> 
> When CONFIG_OF is disabled, building with 'make W=1' produces warnings
> about out of bounds array access:
> 
> drivers/gpu/drm/imx/imx-ldb.c: In function 'imx_ldb_set_clock.constprop':
> drivers/gpu/drm/imx/imx-ldb.c:186:8: error: array subscript -22 is below 
> array bounds of 'struct clk *[4]' [-Werror=array-bounds]
> 
> Add an error check before the index is used, which helps with the
> warning, as well as any possible other error condition that may be
> triggered at runtime.
> 
> Signed-off-by: Arnd Bergmann 
> ---
>  drivers/gpu/drm/imx/imx-ldb.c | 12 
>  1 file changed, 12 insertions(+)
> 
> diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
> index dbfe39e2f7f6..1210360cec8a 100644
> --- a/drivers/gpu/drm/imx/imx-ldb.c
> +++ b/drivers/gpu/drm/imx/imx-ldb.c
> @@ -197,6 +197,12 @@ static void imx_ldb_encoder_enable(struct drm_encoder 
> *encoder)
>   int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN;
>   int mux = drm_of_encoder_active_port_id(imx_ldb_ch->child, encoder);
>  
> + if (mux < 0) {
> + dev_warn(ldb->dev,
> +  "%s: invalid mux\n", __func__);
> + return;
> + }
> +
>   drm_panel_prepare(imx_ldb_ch->panel);
>  
>   if (dual) {
> @@ -255,6 +261,12 @@ imx_ldb_encoder_atomic_mode_set(struct drm_encoder 
> *encoder,
>   int mux = drm_of_encoder_active_port_id(imx_ldb_ch->child, encoder);
>   u32 bus_format = imx_ldb_ch->bus_format;
>  
> + if (mux < 0) {
> + dev_warn(ldb->dev,
> +  "%s: invalid mux\n", __func__);
> + return;
> + }
> +
>   if (mode->clock > 17) {
>   dev_warn(ldb->dev,
>"%s: mode exceeds 170 MHz pixel clock\n", __func__);



Re: [PATCH v6 02/10] scsi: ufshpb: Add host control mode support to rsp_upiu

2021-03-23 Thread Zang Leigang
On Mon, Mar 22, 2021 at 10:10:36AM +0200, Avri Altman wrote:
> In device control mode, the device may recommend the host to either
> activate or inactivate a region, and the host should follow. Meaning
> those are not actually recommendations, but more of instructions.
> 
> On the contrary, in host control mode, the recommendation protocol is
> slightly changed:
> a) The device may only recommend the host to update a subregion of an
>already-active region. And,
> b) The device may *not* recommend to inactivate a region.
> 
> Furthermore, in host control mode, the host may choose not to follow any
> of the device's recommendations. However, in case of a recommendation to
> update an active and clean subregion, it is better to follow those
> recommendation because otherwise the host has no other way to know that
> some internal relocation took place.
> 
> Signed-off-by: Avri Altman 
> ---
>  drivers/scsi/ufs/ufshpb.c | 34 +-
>  drivers/scsi/ufs/ufshpb.h |  2 ++
>  2 files changed, 35 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c
> index fb10afcbb49f..d4f0bb6d8fa1 100644
> --- a/drivers/scsi/ufs/ufshpb.c
> +++ b/drivers/scsi/ufs/ufshpb.c
> @@ -166,6 +166,8 @@ static void ufshpb_set_ppn_dirty(struct ufshpb_lu *hpb, 
> int rgn_idx,
>   else
>   set_bit_len = cnt;
>  
> + set_bit(RGN_FLAG_DIRTY, >rgn_flags);
> +
>   if (rgn->rgn_state != HPB_RGN_INACTIVE &&
>   srgn->srgn_state == HPB_SRGN_VALID)
>   bitmap_set(srgn->mctx->ppn_dirty, srgn_offset, set_bit_len);
> @@ -235,6 +237,11 @@ static bool ufshpb_test_ppn_dirty(struct ufshpb_lu *hpb, 
> int rgn_idx,
>   return false;
>  }
>  
> +static inline bool is_rgn_dirty(struct ufshpb_region *rgn)
> +{
> + return test_bit(RGN_FLAG_DIRTY, >rgn_flags);
> +}
> +
>  static int ufshpb_fill_ppn_from_page(struct ufshpb_lu *hpb,
>struct ufshpb_map_ctx *mctx, int pos,
>int len, u64 *ppn_buf)
> @@ -713,6 +720,7 @@ static void ufshpb_put_map_req(struct ufshpb_lu *hpb,
>  static int ufshpb_clear_dirty_bitmap(struct ufshpb_lu *hpb,
>struct ufshpb_subregion *srgn)
>  {
> + struct ufshpb_region *rgn;
>   u32 num_entries = hpb->entries_per_srgn;
>  
>   if (!srgn->mctx) {
> @@ -726,6 +734,10 @@ static int ufshpb_clear_dirty_bitmap(struct ufshpb_lu 
> *hpb,
>   num_entries = hpb->last_srgn_entries;
>  
>   bitmap_zero(srgn->mctx->ppn_dirty, num_entries);
> +
> + rgn = hpb->rgn_tbl + srgn->rgn_idx;
> + clear_bit(RGN_FLAG_DIRTY, >rgn_flags);
> +
>   return 0;
>  }
>  
> @@ -1245,6 +1257,18 @@ static void ufshpb_rsp_req_region_update(struct 
> ufshpb_lu *hpb,
>   srgn_i =
>   be16_to_cpu(rsp_field->hpb_active_field[i].active_srgn);
>  
> + rgn = hpb->rgn_tbl + rgn_i;
> + if (hpb->is_hcm &&
> + (rgn->rgn_state != HPB_RGN_ACTIVE || is_rgn_dirty(rgn))) {
> + /*
> +  * in host control mode, subregion activation
> +  * recommendations are only allowed to active regions.
> +  * Also, ignore recommendations for dirty regions - the
> +  * host will make decisions concerning those by himself
> +  */
> + continue;
> + }
> +

Hi Avri, host control mode also need the recommendations from device,
because the bkops would make the ppn invalid, is that right?

>   dev_dbg(>sdev_ufs_lu->sdev_dev,
>   "activate(%d) region %d - %d\n", i, rgn_i, srgn_i);
>  
> @@ -1252,7 +1276,6 @@ static void ufshpb_rsp_req_region_update(struct 
> ufshpb_lu *hpb,
>   ufshpb_update_active_info(hpb, rgn_i, srgn_i);
>   spin_unlock(>rsp_list_lock);
>  
> - rgn = hpb->rgn_tbl + rgn_i;
>   srgn = rgn->srgn_tbl + srgn_i;
>  
>   /* blocking HPB_READ */
> @@ -1263,6 +1286,14 @@ static void ufshpb_rsp_req_region_update(struct 
> ufshpb_lu *hpb,
>   hpb->stats.rb_active_cnt++;
>   }
>  
> + if (hpb->is_hcm) {
> + /*
> +  * in host control mode the device is not allowed to inactivate
> +  * regions
> +  */
> + goto out;
> + }
> +
>   for (i = 0; i < rsp_field->inactive_rgn_cnt; i++) {
>   rgn_i = be16_to_cpu(rsp_field->hpb_inactive_field[i]);
>   dev_dbg(>sdev_ufs_lu->sdev_dev,
> @@ -1287,6 +1318,7 @@ static void ufshpb_rsp_req_region_update(struct 
> ufshpb_lu *hpb,
>   hpb->stats.rb_inactive_cnt++;
>   }
>  
> +out:
>   dev_dbg(>sdev_ufs_lu->sdev_dev, "Noti: #ACT %u #INACT %u\n",
>   rsp_field->active_rgn_cnt, rsp_field->inactive_rgn_cnt);
>  
> diff --git a/drivers/scsi/ufs/ufshpb.h 

Re: [PATCH v5] mm: cma: support sysfs

2021-03-23 Thread Minchan Kim
On Wed, Mar 24, 2021 at 03:02:24AM +, Matthew Wilcox wrote:
> On Tue, Mar 23, 2021 at 12:50:50PM -0700, Minchan Kim wrote:
> > +   /* the number of CMA page successful allocations */
> > +   atomic64_t nr_pages_succeeded;
> 
> > +void cma_sysfs_alloc_pages_count(struct cma *cma, size_t count)
> > +{
> > +   atomic64_add(count, >nr_pages_succeeded);
> > +}
> 
> I don't understand.  A size_t is a byte count.  But the variable is called
> 'nr_pages'.  So which is it, a byte count or a page count?

It's page count. I followed the cma_alloc interface since it has
size_t count variable for nr_pages.

Let's go with unsigned long nr_pages:
void cma_sysfs_alloc_pages_count(struct cma *cma, unsigned long
nr_pages)

> 
> > +static ssize_t alloc_pages_success_show(struct kobject *kobj,
> > +   struct kobj_attribute *attr, char *buf)
> > +{
> > +   struct cma_kobject *cma_kobj = container_of(kobj,
> > +   struct cma_kobject, kobj);
> > +   struct cma *cma = cma_kobj->cma;
> > +
> > +   return sysfs_emit(buf, "%llu\n",
> > + atomic64_read(>nr_pages_succeeded));
> 
> ... if it's in bytes, it should probably be reported in kilobytes
> and be suffixed with a 'K' like many other stats.
> 


Re: [PATCH v1] usb: dwc3: core: Add shutdown callback for dwc3

2021-03-23 Thread Stephen Boyd
Quoting Sandeep Maheswaram (2021-03-23 12:27:32)
> This patch adds a shutdown callback to USB DWC core driver to ensure that
> it is properly shutdown in reboot/shutdown path. This is required
> where SMMU address translation is enabled like on SC7180
> SoC and few others. If the hardware is still accessing memory after
> SMMU translation is disabled as part of SMMU shutdown callback in
> system reboot or shutdown path, then IOVAs(I/O virtual address)
> which it was using will go on the bus as the physical addresses which
> might result in unknown crashes (NoC/interconnect errors).
> 
> Previously this was added in dwc3 qcom glue driver.
> https://patchwork.kernel.org/project/linux-arm-msm/list/?series=382449
> But observed kernel panic as glue driver shutdown getting called after
> iommu shutdown. As we are adding iommu nodes in dwc core node
> in device tree adding shutdown callback in core driver seems correct.
> 
> Signed-off-by: Sandeep Maheswaram 
> ---
>  drivers/usb/dwc3/core.c | 26 +++---
>  1 file changed, 19 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 94fdbe5..777b2b5 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -1634,11 +1634,9 @@ static int dwc3_probe(struct platform_device *pdev)
> return ret;
>  }
>  
> -static int dwc3_remove(struct platform_device *pdev)
> +static void __dwc3_teardown(struct dwc3 *dwc)
>  {
> -   struct dwc3 *dwc = platform_get_drvdata(pdev);
> -
> -   pm_runtime_get_sync(>dev);
> +   pm_runtime_get_sync(dwc->dev);
>  
> dwc3_debugfs_exit(dwc);
> dwc3_core_exit_mode(dwc);
> @@ -1646,19 +1644,32 @@ static int dwc3_remove(struct platform_device *pdev)
> dwc3_core_exit(dwc);
> dwc3_ulpi_exit(dwc);
>  
> -   pm_runtime_disable(>dev);
> -   pm_runtime_put_noidle(>dev);
> -   pm_runtime_set_suspended(>dev);
> +   pm_runtime_disable(dwc->dev);
> +   pm_runtime_put_noidle(dwc->dev);
> +   pm_runtime_set_suspended(dwc->dev);
>  
> dwc3_free_event_buffers(dwc);
> dwc3_free_scratch_buffers(dwc);
>  
> if (dwc->usb_psy)
> power_supply_put(dwc->usb_psy);
> +}
> +
> +static int dwc3_remove(struct platform_device *pdev)
> +{
> +   struct dwc3 *dwc = platform_get_drvdata(pdev);
> +
> +   __dwc3_teardown(dwc);
>  
> return 0;
>  }
>  
> +static void dwc3_shutdown(struct platform_device *pdev)
> +{
> +   struct dwc3 *dwc = platform_get_drvdata(pdev);
> +
> +   __dwc3_teardown(dwc);
> +}

Can't this be

static void dwc3_shutdown(struct platform_device *pdev)
{
   dwc3_remove(pdev);
}

and then there's nothing else to change? Basically ignore return value
of dwc3_remove() to make shutdown and remove harmonize. I also wonder if
this is more common than we think and a struct driver flag could be set
to say "call remove for shutdown" and then have driver core swizzle on
that and save some duplicate functions.

>  #ifdef CONFIG_PM
>  static int dwc3_core_init_for_resume(struct dwc3 *dwc)
>  {
> @@ -1976,6 +1987,7 @@ MODULE_DEVICE_TABLE(acpi, dwc3_acpi_match);
>  static struct platform_driver dwc3_driver = {
> .probe  = dwc3_probe,
> .remove = dwc3_remove,
> +   .shutdown   = dwc3_shutdown,


Re: [PATCH] mm: vmalloc: Prevent use after free in _vm_unmap_aliases

2021-03-23 Thread Vijayanand Jitta



On 3/18/2021 10:29 PM, Uladzislau Rezki wrote:
> On Thu, Mar 18, 2021 at 03:38:25PM +0530, vji...@codeaurora.org wrote:
>> From: Vijayanand Jitta 
>>
>> A potential use after free can occur in _vm_unmap_aliases
>> where an already freed vmap_area could be accessed, Consider
>> the following scenario:
>>
>> Process 1Process 2
>>
>> __vm_unmap_aliases   __vm_unmap_aliases
>>  purge_fragmented_blocks_allcpus rcu_read_lock()
>>  rcu_read_lock()
>>  list_del_rcu(>free_list)
>>  
>> list_for_each_entry_rcu(vb .. )
>>  __purge_vmap_area_lazy
>>  kmem_cache_free(va)
>>  
>> va_start = vb->va->va_start
> Or maybe we should switch to kfree_rcu() instead of kmem_cache_free()?
> 
> --
> Vlad Rezki
> 

Thanks for suggestion.

I see free_vmap_area_lock (spinlock) is taken in __purge_vmap_area_lazy
while it loops through list and calls kmem_cache_free on va's. So, looks
like we can't replace it with kfree_rcu as it might cause scheduling
within atomic context.

Thanks,
Vijay
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a
member of Code Aurora Forum, hosted by The Linux Foundation


[PATCH v2] drivers/media/pci/bt8xx/bttv-cards: fix typos

2021-03-23 Thread Xiaofeng Cao
change 'vodeo' to 'video'
change 'nevery'to 'never'
change 'is'to 'it'
change 'connevted' to 'connected'
change 'swichers'  to 'switchers'
change 'strucure'  to 'structure'
change 'unblanced' to 'unbalanced'
change 'fonctionality' to 'functionality'

Signed-off-by: Xiaofeng Cao 
---
v2: resume space and change 'USED' to 'USE'
 drivers/media/pci/bt8xx/bttv-cards.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/media/pci/bt8xx/bttv-cards.c 
b/drivers/media/pci/bt8xx/bttv-cards.c
index ca20b806e82d..c2b5ab287dd7 100644
--- a/drivers/media/pci/bt8xx/bttv-cards.c
+++ b/drivers/media/pci/bt8xx/bttv-cards.c
@@ -2011,7 +2011,7 @@ struct tvcard bttv_tvcards[] = {
/* .audio_inputs= 0, */
.svhs   = 9,
.gpiomask   = 0x00,
-   .gpiomask2  = 0x03, /* used for external vodeo mux */
+   .gpiomask2  = 0x03, /* used for external video mux */
.muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 0),
.muxsel_hook= phytec_muxsel,
.gpiomux= { 0, 0, 0, 0 }, /* card has no audio */
@@ -2025,7 +2025,7 @@ struct tvcard bttv_tvcards[] = {
/* .audio_inputs= 0, */
.svhs   = 9,
.gpiomask   = 0x00,
-   .gpiomask2  = 0x03, /* used for external vodeo mux */
+   .gpiomask2  = 0x03, /* used for external video mux */
.muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 1),
.muxsel_hook= phytec_muxsel,
.gpiomux= { 0, 0, 0, 0 }, /* card has no audio */
@@ -2180,8 +2180,8 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_PICOLO_TETRA_CHIP] = {
/*Eric DEBIEF */
/*EURESYS Picolo Tetra : 4 Conexant Fusion 878A, no audio, 
video input set with analog multiplexers GPIO controlled*/
-   /* adds picolo_tetra_muxsel(), picolo_tetra_init(), the 
following declaration strucure, and #define BTTV_BOARD_PICOLO_TETRA_CHIP*/
-   /*0x79 in bttv.h*/
+   /*adds picolo_tetra_muxsel(), picolo_tetra_init(), the 
following declaration*/
+   /*structure and #define BTTV_BOARD_PICOLO_TETRA_CHIP 0x79 in 
bttv.h*/
.name   = "Euresys Picolo Tetra",
.video_inputs   = 4,
/* .audio_inputs= 0, */
@@ -2506,7 +2506,7 @@ struct tvcard bttv_tvcards[] = {
 one external BNC composite input (mux 2)
 three internal composite inputs (unknown muxes)
 an 18-bit stereo A/D (CS5331A), which has:
-  one external stereo unblanced (RCA) audio connection
+  one external stereo unbalanced (RCA) audio connection
   one (or 3?) internal stereo balanced (XLR) audio connection
   input is selected via gpio to a 14052B mux
 (mask=0x300, unbal=0x000, bal=0x100, ??=0x200,0x300)
@@ -3924,7 +3924,7 @@ static void osprey_eeprom(struct bttv *btv, const u8 
ee[256])
u32 serial = 0;
int cardid = -1;
 
-   /* This code will nevery actually get called in this case */
+   /* This code will never actually get called in this case */
if (btv->c.type == BTTV_BOARD_UNKNOWN) {
/* this might be an antique... check for MMAC label in eeprom */
if (!strncmp(ee, "MMAC", 4)) {
@@ -4086,7 +4086,7 @@ static void avermedia_eeprom(struct bttv *btv)
 /*
  * For Voodoo TV/FM and Voodoo 200.  These cards' tuners use a TDA9880
  * analog demod, which is not I2C controlled like the newer and more common
- * TDA9887 series.  Instead is has two tri-state input pins, S0 and S1,
+ * TDA9887 series.  Instead it has two tri-state input pins, S0 and S1,
  * that control the IF for the video and audio.  Apparently, bttv GPIO
  * 0x1 is connected to S0.  S0 low selects a 38.9 MHz VIF for B/G/D/K/I
  * (i.e., PAL) while high selects 45.75 MHz for M/N (i.e., NTSC).
@@ -4144,7 +4144,7 @@ static void init_PXC200(struct bttv *btv)
int tmp;
u32 val;
 
-   /* Initialise GPIO-connevted stuff */
+   /* Initialise GPIO-connected stuff */
gpio_inout(0xff, (1<<13));
gpio_write(0);
udelay(3);
@@ -4580,7 +4580,7 @@ static void xguard_muxsel(struct bttv *btv, unsigned int 
input)
 }
 static void picolo_tetra_init(struct bttv *btv)
 {
-   /*This is the video input redirection fonctionality : I DID NOT USED 
IT. */
+   /*This is the video input redirection functionality : I DID NOT USE IT. 
*/
btwrite (0x08<<16,BT848_GPIO_DATA);/*GPIO[19] [==> 4053 B+C] set to 1 */
btwrite (0x04<<16,BT848_GPIO_DATA);/*GPIO[18] [==> 4053 A]  set to 1*/
 }
@@ -4598,7 +4598,7 @@ static void picolo_tetra_muxsel (struct bttv* btv, 
unsigned int input)
  * ivc120_muxsel [Added by Alan Garfield ]
  *
  * The IVC120G security 

Re: [PATCH RFC] f2fs: fix to avoid selecting full segment w/ {AT,}SSR allocator

2021-03-23 Thread Chao Yu

On 2021/3/24 6:59, Jaegeuk Kim wrote:

On 03/19, Chao Yu wrote:

On 2021/3/19 1:17, Jaegeuk Kim wrote:

On 02/20, Chao Yu wrote:

In cp disabling mode, there could be a condition
- target segment has 128 ckpt valid blocks
- GC migrates 128 valid blocks to other segment (segment is still in
dirty list)
- GC migrates 384 blocks to target segment (segment has 128 cp_vblocks
and 384 vblocks)
- If GC selects target segment via {AT,}SSR allocator, however there is
no free space in targe segment.

Fixes: 4354994f097d ("f2fs: checkpoint disabling")
Fixes: 093749e296e2 ("f2fs: support age threshold based garbage collection")
Signed-off-by: Chao Yu 
---
   fs/f2fs/f2fs.h|  1 +
   fs/f2fs/gc.c  | 17 +
   fs/f2fs/segment.c | 20 
   3 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index ed7807103c8e..9c753eff0814 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -3376,6 +3376,7 @@ block_t f2fs_get_unusable_blocks(struct f2fs_sb_info 
*sbi);
   int f2fs_disable_cp_again(struct f2fs_sb_info *sbi, block_t unusable);
   void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi);
   int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
+bool segment_has_free_slot(struct f2fs_sb_info *sbi, int segno);
   void f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi);
   void f2fs_save_inmem_curseg(struct f2fs_sb_info *sbi);
   void f2fs_restore_inmem_curseg(struct f2fs_sb_info *sbi);
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 86ba8ed0b8a7..a1d8062cdace 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -392,10 +392,6 @@ static void add_victim_entry(struct f2fs_sb_info *sbi,
if (p->gc_mode == GC_AT &&
get_valid_blocks(sbi, segno, true) == 0)
return;
-
-   if (p->alloc_mode == AT_SSR &&
-   get_seg_entry(sbi, segno)->ckpt_valid_blocks == 0)
-   return;
}
for (i = 0; i < sbi->segs_per_sec; i++)
@@ -736,6 +732,19 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi,
if (gc_type == BG_GC && test_bit(secno, dirty_i->victim_secmap))
goto next;
+   if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
+   /*
+* to avoid selecting candidate which has below valid
+* block distribution:
+* partial blocks are valid and all left ones are valid
+* in previous checkpoint.
+*/
+   if (p.alloc_mode == SSR || p.alloc_mode == AT_SSR) {
+   if (!segment_has_free_slot(sbi, segno))
+   goto next;


Do we need to change this to check free_slot instead of get_ckpt_valid_blocks()?


Jaegeuk,

LFS was assigned only for GC case, in this case we are trying to select source
section, rather than target segment for SSR/AT_SSR case, so we don't need to
check free_slot.

- f2fs_gc
  - __get_victim
   - get_victim(sbi, victim, gc_type, NO_CHECK_TYPE, LFS, 0);



   732 if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED) &&
   733 get_ckpt_valid_blocks(sbi, segno) 
&&
   734 p.alloc_mode == LFS))


BTW, in LFS mode, GC wants to find source section rather than segment, so we
should change to check valid ckpt blocks in every segment of targe section here?


Alright. I refactored a bit on this patch with new one. Could you please take a 
look?

https://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git/commit/?h=dev=00152bd7cabd69b4615ebead823ff23887b0e0f7


I see, newly added comment looks good to me.

One more concern is commit title and commit message is out-of-update,
I've revised it in v2:

https://lore.kernel.org/linux-f2fs-devel/20210324031828.67133-1-yuch...@huawei.com/T/#u

Thanks,



Thanks,



Thanks,





+   }
+   }
+
if (is_atgc) {
add_victim_entry(sbi, , segno);
goto next;
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 2d5a82c4ca15..deaf57e13125 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2650,6 +2650,26 @@ static void __refresh_next_blkoff(struct f2fs_sb_info 
*sbi,
seg->next_blkoff++;
   }
+bool segment_has_free_slot(struct f2fs_sb_info *sbi, int segno)
+{
+   struct sit_info *sit = SIT_I(sbi);
+   struct seg_entry *se = get_seg_entry(sbi, segno);
+   int entries = SIT_VBLOCK_MAP_SIZE / sizeof(unsigned long);
+   unsigned long *target_map = SIT_I(sbi)->tmp_map;
+   unsigned long *ckpt_map = (unsigned long *)se->ckpt_valid_map;
+   unsigned long *cur_map = (unsigned long *)se->cur_valid_map;
+   int i, pos;
+
+   down_write(>sentry_lock);
+   for (i = 0; i < 

Re: [PATCH v6] mm: cma: support sysfs

2021-03-23 Thread Minchan Kim
On Tue, Mar 23, 2021 at 07:34:12PM -0700, John Hubbard wrote:
> On 3/23/21 6:05 PM, Minchan Kim wrote:
> ...> diff --git a/mm/cma_sysfs.c b/mm/cma_sysfs.c
> > new file mode 100644
> > index ..c3791a032dc5
> > --- /dev/null
> > +++ b/mm/cma_sysfs.c
> > @@ -0,0 +1,107 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * CMA SysFS Interface
> > + *
> > + * Copyright (c) 2021 Minchan Kim 
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include "cma.h"
> > +
> > +void cma_sysfs_account_success_pages(struct cma *cma, size_t count)
> > +{
> > +   atomic64_add(count, >nr_pages_succeeded);
> > +}
> > +
> > +void cma_sysfs_account_fail_pages(struct cma *cma, size_t count)
> > +{
> > +   atomic64_add(count, >nr_pages_failed);
> > +}
> > +
> > +#define CMA_ATTR_RO(_name) \
> > +   static struct kobj_attribute _name##_attr = __ATTR_RO(_name)
> > +
> > +#define to_cma_kobject(x) container_of(x, struct cma_kobject, kobj)
> 
> I really don't think that helps. container_of() is so widely used and
> understood that it is not a good move make people read one more wrapper
> for it. Instead, see below...
> 
> > +
> > +static ssize_t alloc_pages_success_show(struct kobject *kobj,
> > +   struct kobj_attribute *attr, char *buf)
> > +{
> > +   struct cma_kobject *cma_kobj = to_cma_kobject(kobj);
> > +   struct cma *cma = cma_kobj->cma;
> 
> ...if you're looking to get rid of the real code duplication, then you
> could put *both* of those lines into a wrapper function, instead, like this:
> 
> static inline struct cma* cma_from_kobj(struct kobject *kobj)
> {
>   struct cma_kobject *cma_kobj = container_of(kobj, struct cma_kobject,
>   kobj);
>   struct cma *cma = cma_kobj->cma;
> 
>   return cma;
> }
> 
> static ssize_t alloc_pages_success_show(struct kobject *kobj,
>   struct kobj_attribute *attr, char *buf)
> {
>   struct cma *cma = cma_from_kobj(kobj);
> 
>   return sysfs_emit(buf, "%llu\n",
> atomic64_read(>nr_pages_succeeded));
> }
> CMA_ATTR_RO(alloc_pages_success);
> 
> static ssize_t alloc_pages_fail_show(struct kobject *kobj,
>struct kobj_attribute *attr, char *buf)
> {
>   struct cma *cma = cma_from_kobj(kobj);
> 
>   return sysfs_emit(buf, "%llu\n", atomic64_read(>nr_pages_failed));
> }
> CMA_ATTR_RO(alloc_pages_fail);
> 
> static void cma_kobj_release(struct kobject *kobj)
> {
>   struct cma_kobject *cma_kobj = container_of(kobj, struct cma_kobject,
>   kobj);
>   struct cma *cma = cma_kobj->cma;
> 
>   kfree(cma_kobj);
>   cma->kobj = NULL;
> }
> 
> ...isn't that nicer? Saves a little code, gets rid of a macro.

Yub.

> 
> > +
> > +   return sysfs_emit(buf, "%llu\n",
> > + atomic64_read(>nr_pages_succeeded));
> > +}
> > +CMA_ATTR_RO(alloc_pages_success);
> > +
> > +static ssize_t alloc_pages_fail_show(struct kobject *kobj,
> > +struct kobj_attribute *attr, char *buf)
> > +{
> > +   struct cma_kobject *cma_kobj = to_cma_kobject(kobj);
> > +   struct cma *cma = cma_kobj->cma;
> > +
> > +   return sysfs_emit(buf, "%llu\n", atomic64_read(>nr_pages_failed));
> > +}
> > +CMA_ATTR_RO(alloc_pages_fail);
> > +
> > +static void cma_kobj_release(struct kobject *kobj)
> > +{
> > +   struct cma_kobject *cma_kobj = to_cma_kobject(kobj);
> > +   struct cma *cma = cma_kobj->cma;
> > +
> > +   kfree(cma_kobj);
> > +   cma->kobj = NULL;
> > +}
> > +
> > +static struct attribute *cma_attrs[] = {
> > +   _pages_success_attr.attr,
> > +   _pages_fail_attr.attr,
> > +   NULL,
> > +};
> > +ATTRIBUTE_GROUPS(cma);
> > +
> > +static struct kobject *cma_kobj_root;
> > +
> > +static struct kobj_type cma_ktype = {
> > +   .release = cma_kobj_release,
> > +   .sysfs_ops = _sysfs_ops,
> > +   .default_groups = cma_groups
> > +};
> > +
> > +static int __init cma_sysfs_init(void)
> > +{
> > +   unsigned int i;
> > +
> > +   cma_kobj_root = kobject_create_and_add("cma", mm_kobj);
> > +   if (!cma_kobj_root)
> > +   return -ENOMEM;
> > +
> > +   for (i = 0; i < cma_area_count; i++) {
> > +   int err;
> > +   struct cma *cma;
> > +   struct cma_kobject *cma_kobj;
> > +
> > +   cma_kobj = kzalloc(sizeof(*cma_kobj), GFP_KERNEL);
> > +   if (!cma_kobj) {
> > +   kobject_put(cma_kobj_root);
> > +   return -ENOMEM;
> 
> This leaks little cma_kobj's all over the floor. :)

I thought kobject_put(cma_kobj_root) should deal with it. No?

> 
> What you might want here is a separate routine to clean up, because
> it has to loop through and free whatever was allocated on previous
> iterations of this loop here.
> 
> > +   }
> > +
> > +   cma = _areas[i];
> > +   cma->kobj = cma_kobj;
> > +   

[PATCH] f2fs: fix to update last i_size if fallocate partially succeeds

2021-03-23 Thread Chao Yu
In the case of expanding pinned file, map.m_lblk and map.m_len
will update in each round of section allocation, so in error
path, last i_size will be calculated with wrong m_lblk and m_len,
fix it.

Fixes: f5a53edcf01e ("f2fs: support aligned pinned file")
Signed-off-by: Chao Yu 
---
 fs/f2fs/file.c | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index bd5a77091d23..dc79694e512c 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -1619,9 +1619,10 @@ static int expand_inode_data(struct inode *inode, loff_t 
offset,
struct f2fs_map_blocks map = { .m_next_pgofs = NULL,
.m_next_extent = NULL, .m_seg_type = NO_CHECK_TYPE,
.m_may_create = true };
-   pgoff_t pg_end;
+   pgoff_t pg_start, pg_end;
loff_t new_size = i_size_read(inode);
loff_t off_end;
+   block_t expanded = 0;
int err;
 
err = inode_newsize_ok(inode, (len + offset));
@@ -1634,11 +1635,12 @@ static int expand_inode_data(struct inode *inode, 
loff_t offset,
 
f2fs_balance_fs(sbi, true);
 
+   pg_start = ((unsigned long long)offset) >> PAGE_SHIFT;
pg_end = ((unsigned long long)offset + len) >> PAGE_SHIFT;
off_end = (offset + len) & (PAGE_SIZE - 1);
 
-   map.m_lblk = ((unsigned long long)offset) >> PAGE_SHIFT;
-   map.m_len = pg_end - map.m_lblk;
+   map.m_lblk = pg_start;
+   map.m_len = pg_end - pg_start;
if (off_end)
map.m_len++;
 
@@ -1648,7 +1650,6 @@ static int expand_inode_data(struct inode *inode, loff_t 
offset,
if (f2fs_is_pinned_file(inode)) {
block_t sec_blks = BLKS_PER_SEC(sbi);
block_t sec_len = roundup(map.m_len, sec_blks);
-   block_t done = 0;
 
map.m_len = sec_blks;
 next_alloc:
@@ -1656,10 +1657,8 @@ static int expand_inode_data(struct inode *inode, loff_t 
offset,
GET_SEC_FROM_SEG(sbi, overprovision_segments(sbi {
down_write(>gc_lock);
err = f2fs_gc(sbi, true, false, false, NULL_SEGNO);
-   if (err && err != -ENODATA && err != -EAGAIN) {
-   map.m_len = done;
+   if (err && err != -ENODATA && err != -EAGAIN)
goto out_err;
-   }
}
 
down_write(>pin_sem);
@@ -1673,24 +1672,25 @@ static int expand_inode_data(struct inode *inode, 
loff_t offset,
 
up_write(>pin_sem);
 
-   done += map.m_len;
+   expanded += map.m_len;
sec_len -= map.m_len;
map.m_lblk += map.m_len;
if (!err && sec_len)
goto next_alloc;
 
-   map.m_len = done;
+   map.m_len = expanded;
} else {
err = f2fs_map_blocks(inode, , 1, F2FS_GET_BLOCK_PRE_AIO);
+   expanded = map.m_len;
}
 out_err:
if (err) {
pgoff_t last_off;
 
-   if (!map.m_len)
+   if (!expanded)
return err;
 
-   last_off = map.m_lblk + map.m_len - 1;
+   last_off = pg_start + expanded - 1;
 
/* update new size to the failed position */
new_size = (last_off == pg_end) ? offset + len :
-- 
2.29.2



[PATCH v3 0/3] soc: rockchip: power-domain: add rk3568 powerdomains

2021-03-23 Thread Elaine Zhang
Support power domain function for RK3568 Soc.

Change in V3:
[PATCH v3 1/3]: No change.
[PATCH v3 2/3]: Fix up the code styles and add rk3568 base on:
https://patchwork.kernel.org/project/linux-rockchip/patch/20210225102643.653095-1-enric.balle...@collabora.com/
[PATCH v3 3/3]: No change.

Change in V2:
[PATCH v2 1/3]: No change.
[PATCH v2 2/3]: Fix up yaml code styles.
[PATCH v2 3/3]: No change.

Elaine Zhang (3):
  dt-bindings: add power-domain header for RK3568 SoCs
  dt-bindings: Convert the rockchip power_domain to YAML and extend
  soc: rockchip: power-domain: add rk3568 powerdomains

 .../power/rockchip,power-controller.yaml  | 286 ++
 .../bindings/soc/rockchip/power_domain.txt| 136 -
 drivers/soc/rockchip/pm_domains.c |  31 ++
 include/dt-bindings/power/rk3568-power.h  |  32 ++
 4 files changed, 349 insertions(+), 136 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/power/rockchip,power-controller.yaml
 delete mode 100644 
Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
 create mode 100644 include/dt-bindings/power/rk3568-power.h

-- 
2.17.1





[PATCH v3 3/3] soc: rockchip: power-domain: add rk3568 powerdomains

2021-03-23 Thread Elaine Zhang
Add power-domains found on rk3568 socs.

Signed-off-by: Elaine Zhang 
---
 drivers/soc/rockchip/pm_domains.c | 31 +++
 1 file changed, 31 insertions(+)

diff --git a/drivers/soc/rockchip/pm_domains.c 
b/drivers/soc/rockchip/pm_domains.c
index 54eb6cfc5d5b..a2c19c845cf2 100644
--- a/drivers/soc/rockchip/pm_domains.c
+++ b/drivers/soc/rockchip/pm_domains.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 struct rockchip_domain_info {
int pwr_mask;
@@ -131,6 +132,9 @@ struct rockchip_pmu {
 #define DOMAIN_RK3399(pwr, status, req, wakeup)\
DOMAIN(pwr, status, req, req, req, wakeup)
 
+#define DOMAIN_RK3568(pwr, req, wakeup)\
+   DOMAIN_M(pwr, pwr, req, req, req, wakeup)
+
 static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd)
 {
struct rockchip_pmu *pmu = pd->pmu;
@@ -841,6 +845,18 @@ static const struct rockchip_domain_info 
rk3399_pm_domains[] = {
[RK3399_PD_SDIOAUDIO]   = DOMAIN_RK3399(BIT(31), BIT(31), BIT(29), 
true),
 };
 
+static const struct rockchip_domain_info rk3568_pm_domains[] = {
+   [RK3568_PD_NPU] = DOMAIN_RK3568(BIT(1), BIT(2), false),
+   [RK3568_PD_GPU] = DOMAIN_RK3568(BIT(0), BIT(1), false),
+   [RK3568_PD_VI]  = DOMAIN_RK3568(BIT(6), BIT(3), false),
+   [RK3568_PD_VO]  = DOMAIN_RK3568(BIT(7),  BIT(4), false),
+   [RK3568_PD_RGA] = DOMAIN_RK3568(BIT(5),  BIT(5), false),
+   [RK3568_PD_VPU] = DOMAIN_RK3568(BIT(2), BIT(6), false),
+   [RK3568_PD_RKVDEC]  = DOMAIN_RK3568(BIT(4), BIT(8), false),
+   [RK3568_PD_RKVENC]  = DOMAIN_RK3568(BIT(3), BIT(7), false),
+   [RK3568_PD_PIPE]= DOMAIN_RK3568(BIT(8), BIT(11), false),
+};
+
 static const struct rockchip_pmu_info px30_pmu = {
.pwr_offset = 0x18,
.status_offset = 0x20,
@@ -976,6 +992,17 @@ static const struct rockchip_pmu_info rk3399_pmu = {
.domain_info = rk3399_pm_domains,
 };
 
+static const struct rockchip_pmu_info rk3568_pmu = {
+   .pwr_offset = 0xa0,
+   .status_offset = 0x98,
+   .req_offset = 0x50,
+   .idle_offset = 0x68,
+   .ack_offset = 0x60,
+
+   .num_domains = ARRAY_SIZE(rk3568_pm_domains),
+   .domain_info = rk3568_pm_domains,
+};
+
 static const struct of_device_id rockchip_pm_domain_dt_match[] = {
{
.compatible = "rockchip,px30-power-controller",
@@ -1021,6 +1048,10 @@ static const struct of_device_id 
rockchip_pm_domain_dt_match[] = {
.compatible = "rockchip,rk3399-power-controller",
.data = (void *)_pmu,
},
+   {
+   .compatible = "rockchip,rk3568-power-controller",
+   .data = (void *)_pmu,
+   },
{ /* sentinel */ },
 };
 
-- 
2.17.1





[PATCH v3 2/3] dt-bindings: power: rockchip: Convert to json-schema and extend

2021-03-23 Thread Elaine Zhang
Convert the soc/rockchip/power_domain.txt binding document to
json-schema and move to the power bindings directory.
Add RK3568 SoCs for rockchip power binding document.

Signed-off-by: Enric Balletbo i Serra 
Signed-off-by: Elaine Zhang 
---
 .../power/rockchip,power-controller.yaml  | 286 ++
 .../bindings/soc/rockchip/power_domain.txt| 136 -
 2 files changed, 286 insertions(+), 136 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/power/rockchip,power-controller.yaml
 delete mode 100644 
Documentation/devicetree/bindings/soc/rockchip/power_domain.txt

diff --git 
a/Documentation/devicetree/bindings/power/rockchip,power-controller.yaml 
b/Documentation/devicetree/bindings/power/rockchip,power-controller.yaml
new file mode 100644
index ..0d6b8962d098
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/rockchip,power-controller.yaml
@@ -0,0 +1,286 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/power/rockchip,power-controller.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip Power Domains
+
+maintainers:
+  - Elaine Zhang 
+  - Rob Herring 
+  - Heiko Stuebner 
+
+description: |
+  Rockchip processors include support for multiple power domains which can be
+  powered up/down by software based on different application scenes to save 
power.
+
+  Power domains contained within power-controller node are generic power domain
+  providers documented in 
Documentation/devicetree/bindings/power/power-domain.yaml.
+
+  IP cores belonging to a power domain should contain a 'power-domains'
+  property that is a phandle for the power domain node representing the domain.
+
+properties:
+  $nodename:
+const: power-controller
+
+  compatible:
+enum:
+  - rockchip,px30-power-controller
+  - rockchip,rk3036-power-controller
+  - rockchip,rk3066-power-controller
+  - rockchip,rk3128-power-controller
+  - rockchip,rk3188-power-controller
+  - rockchip,rk3228-power-controller
+  - rockchip,rk3288-power-controller
+  - rockchip,rk3328-power-controller
+  - rockchip,rk3366-power-controller
+  - rockchip,rk3368-power-controller
+  - rockchip,rk3399-power-controller
+  - rockchip,rk3568-power-controller
+
+  '#power-domain-cells':
+const: 1
+
+  '#address-cells':
+const: 1
+
+  '#size-cells':
+const: 0
+
+patternProperties:
+  "^pd_[0-9a-z_]{2,10}@[0-9a-f]+$":
+type: object
+description: |
+  Represents the power domains within the power controller node as 
documented
+  in Documentation/devicetree/bindings/power/power-domain.yaml.
+
+properties:
+
+  '#power-domain-cells':
+description:
+  Must be 0 for nodes representing a single PM domain and 1 for nodes
+  providing multiple PM domains.
+
+  '#address-cells':
+const: 1
+
+  '#size-cells':
+const: 0
+
+  reg:
+maxItems: 1
+description: |
+  Power domain index. Valid values are defined in:
+  "include/dt-bindings/power/px30-power.h"
+  "include/dt-bindings/power/rk3036-power.h"
+  "include/dt-bindings/power/rk3066-power.h"
+  "include/dt-bindings/power/rk3128-power.h"
+  "include/dt-bindings/power/rk3188-power.h"
+  "include/dt-bindings/power/rk3228-power.h"
+  "include/dt-bindings/power/rk3288-power.h"
+  "include/dt-bindings/power/rk3328-power.h"
+  "include/dt-bindings/power/rk3366-power.h"
+  "include/dt-bindings/power/rk3368-power.h"
+  "include/dt-bindings/power/rk3399-power.h"
+  "include/dt-bindings/power/rk3399-power.h"
+
+  clocks:
+description: |
+  A number of phandles to clocks that need to be enabled while power 
domain
+  switches state.
+
+  pm_qos:
+description: |
+  A number of phandles to qos blocks which need to be saved and 
restored
+  while power domain switches state.
+
+patternProperties:
+  "^pd_[0-9a-z_]{2,10}@[0-9a-f]+$":
+type: object
+description: |
+  Represents a power domain child within a power domain parent node.
+
+properties:
+
+  '#power-domain-cells':
+description:
+  Must be 0 for nodes representing a single PM domain and 1 for 
nodes
+  providing multiple PM domains.
+
+  '#address-cells':
+const: 1
+
+  '#size-cells':
+const: 0
+
+  reg:
+maxItems: 1
+
+  clocks:
+description: |
+  A number of phandles to clocks that need to be enabled while 
power domain
+  switches state.
+
+  pm_qos:
+description: |
+  A number of phandles to qos blocks which need to be saved and 
restored
+  while power domain switches state.
+
+patternProperties:
+  

[PATCH v3 1/3] dt-bindings: add power-domain header for RK3568 SoCs

2021-03-23 Thread Elaine Zhang
According to a description from TRM, add all the power domains

Signed-off-by: Elaine Zhang 
---
 include/dt-bindings/power/rk3568-power.h | 32 
 1 file changed, 32 insertions(+)
 create mode 100644 include/dt-bindings/power/rk3568-power.h

diff --git a/include/dt-bindings/power/rk3568-power.h 
b/include/dt-bindings/power/rk3568-power.h
new file mode 100644
index ..6cc1af1a9d26
--- /dev/null
+++ b/include/dt-bindings/power/rk3568-power.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __DT_BINDINGS_POWER_RK3568_POWER_H__
+#define __DT_BINDINGS_POWER_RK3568_POWER_H__
+
+/* VD_CORE */
+#define RK3568_PD_CPU_00
+#define RK3568_PD_CPU_11
+#define RK3568_PD_CPU_22
+#define RK3568_PD_CPU_33
+#define RK3568_PD_CORE_ALIVE   4
+
+/* VD_PMU */
+#define RK3568_PD_PMU  5
+
+/* VD_NPU */
+#define RK3568_PD_NPU  6
+
+/* VD_GPU */
+#define RK3568_PD_GPU  7
+
+/* VD_LOGIC */
+#define RK3568_PD_VI   8
+#define RK3568_PD_VO   9
+#define RK3568_PD_RGA  10
+#define RK3568_PD_VPU  11
+#define RK3568_PD_CENTER   12
+#define RK3568_PD_RKVDEC   13
+#define RK3568_PD_RKVENC   14
+#define RK3568_PD_PIPE 15
+#define RK3568_PD_LOGIC_ALIVE  16
+
+#endif
-- 
2.17.1





[PATCH v2] f2fs: fix to avoid touching checkpointed data in get_victim()

2021-03-23 Thread Chao Yu
In CP disabling mode, there are two issues when using LFS or SSR | AT_SSR
mode to select victim:

1. LFS is set to find source section during GC, the victim should have
no checkpointed data, since after GC, section could not be set free for
reuse.

Previously, we only check valid chpt blocks in current segment rather
than section, fix it.

2. SSR | AT_SSR are set to find target segment for writes which can be
fully filled by checkpointed and newly written blocks, we should never
select such segment, otherwise it can cause panic or data corruption
during allocation, potential case is described as below:

 a) target segment has 128 ckpt valid blocks
 b) GC migrates 'n' (n < 512) valid blocks to other segment (segment is
still in dirty list)
 c) GC migrates '512 - n' blocks to target segment (segment has 'n'
cp_vblocks and '512 - n' vblocks)
 d) If GC selects target segment via {AT,}SSR allocator, however there
is no free space in targe segment.

Fixes: 4354994f097d ("f2fs: checkpoint disabling")
Fixes: 093749e296e2 ("f2fs: support age threshold based garbage collection")
Signed-off-by: Chao Yu 
---
v2:
- fix to check checkpointed data in section rather than segment for
LFS mode.
- update commit title and message.
 fs/f2fs/f2fs.h|  1 +
 fs/f2fs/gc.c  | 28 
 fs/f2fs/segment.c | 39 ---
 fs/f2fs/segment.h | 14 +-
 4 files changed, 58 insertions(+), 24 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index eb154d9cb063..29e634d08a27 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -3387,6 +3387,7 @@ block_t f2fs_get_unusable_blocks(struct f2fs_sb_info 
*sbi);
 int f2fs_disable_cp_again(struct f2fs_sb_info *sbi, block_t unusable);
 void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi);
 int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
+bool segment_has_free_slot(struct f2fs_sb_info *sbi, int segno);
 void f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi);
 void f2fs_save_inmem_curseg(struct f2fs_sb_info *sbi);
 void f2fs_restore_inmem_curseg(struct f2fs_sb_info *sbi);
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index d96acc6531f2..4d9616373a4a 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -392,10 +392,6 @@ static void add_victim_entry(struct f2fs_sb_info *sbi,
if (p->gc_mode == GC_AT &&
get_valid_blocks(sbi, segno, true) == 0)
return;
-
-   if (p->alloc_mode == AT_SSR &&
-   get_seg_entry(sbi, segno)->ckpt_valid_blocks == 0)
-   return;
}
 
for (i = 0; i < sbi->segs_per_sec; i++)
@@ -728,11 +724,27 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi,
 
if (sec_usage_check(sbi, secno))
goto next;
+
/* Don't touch checkpointed data */
-   if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED) &&
-   get_ckpt_valid_blocks(sbi, segno) &&
-   p.alloc_mode == LFS))
-   goto next;
+   if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
+   if (p.alloc_mode == LFS) {
+   /*
+* LFS is set to find source section during GC.
+* The victim should have no checkpointed data.
+*/
+   if (get_ckpt_valid_blocks(sbi, segno, true))
+   goto next;
+   } else {
+   /*
+* SSR | AT_SSR are set to find target segment
+* for writes which can be full by checkpointed
+* and newly written blocks.
+*/
+   if (!segment_has_free_slot(sbi, segno))
+   goto next;
+   }
+   }
+
if (gc_type == BG_GC && test_bit(secno, dirty_i->victim_secmap))
goto next;
 
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 6e1a5f5657bf..f6a30856ceda 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -865,7 +865,7 @@ static void locate_dirty_segment(struct f2fs_sb_info *sbi, 
unsigned int segno)
mutex_lock(_i->seglist_lock);
 
valid_blocks = get_valid_blocks(sbi, segno, false);
-   ckpt_valid_blocks = get_ckpt_valid_blocks(sbi, segno);
+   ckpt_valid_blocks = get_ckpt_valid_blocks(sbi, segno, false);
 
if (valid_blocks == 0 && (!is_sbi_flag_set(sbi, SBI_CP_DISABLED) ||
ckpt_valid_blocks == usable_blocks)) {
@@ -950,7 +950,7 @@ static unsigned int get_free_segment(struct f2fs_sb_info 
*sbi)
for_each_set_bit(segno, dirty_i->dirty_segmap[DIRTY], 

Re: [PATCH v4 14/22] x86/fpu/xstate: Expand the xstate buffer on the first use of dynamic user state

2021-03-23 Thread Liu, Jing2




On 3/24/2021 5:01 AM, Len Brown wrote:

I have an obnoxious question: do we really want to use the XFD mechanism?

Obnoxious questions are often the most valuable! :-)

[...]
cheers,
Len Brown, Intel Open Source Technology Center

ps. I agree that un-necessary XINUSE=1 is possible.
Notwithstanding the issues initially deploying AVX512, I am skeptical
that it is common today.

Sorry, I'm trying to understand from...

IMO, the problem with AVX512 state
is that we guaranteed it will be zero for XINUSE=0.
That means we have to write 0's on saves.

why "we have to write 0's on saves" when XINUSE=0.

Since due to SDM, if XINUSE=0, the XSAVES will *not* save the data and
xstate_bv bit is 0; if use XSAVE, it need save the state but
xstate_bv bit is also 0.

  It would be better
to be able to skip the write -- even if we can't save the space
we can save the data transfer.  (This is what we did for AMX).

With XFD feature that XFD=1, XSAVE command still has to save INIT state
to the area. So it seems with XINUSE=0 and XFD=1, the XSAVE(S) commands
do the same that both can help save the data transfer.

The reason I'm interested in XINUSE denotation is that it might be helpful
for the XFD MSRs context switch cost during vmexit and vmenter.

Thanks,
Jing


pps. your idea of requiring the user to allocate their own signal stack
is interesting.   It isn't really about allocating the stack, though --
the stack of the task that uses the feature is generally fine already.
The opportunity is to allow tasks that do *not* use the new feature to
get away with minimal data transfer and stack size.  As we don't
have the 0's guarantee for AMX, we bought the important part
of that back.




Re: [V2][PATCH] drm: xlnx: zynqmp: release reset to DP controller before accessing DP registers

2021-03-23 Thread Laurent Pinchart
Hi Quanyang,

Thank you for the patch.

On Tue, Mar 23, 2021 at 10:55:01AM +0800, quanyang.w...@windriver.com wrote:
> From: Quanyang Wang 
> 
> When insmod zynqmp-dpsub.ko after rmmod it, system will hang with the
> error log as below:
> 
> root@xilinx-zynqmp:~# insmod zynqmp-dpsub.ko
> [   88.391289] [drm] Initialized zynqmp-dpsub 1.0.0 20130509 for 
> fd4a.display on minor 0
> [   88.529906] Console: switching to colour frame buffer device 128x48
> [   88.549402] zynqmp-dpsub fd4a.display: [drm] fb0: zynqmp-dpsubdrm 
> frame buffer device
> [   88.571624] zynqmp-dpsub fd4a.display: ZynqMP DisplayPort Subsystem 
> driver probed
> root@xilinx-zynqmp:~# rmmod zynqmp_dpsub
> [   94.023404] Console: switching to colour dummy device 80x25
> root@xilinx-zynqmp:~# insmod zynqmp-dpsub.ko
>   
> 
> This is because that in zynqmp_dp_probe it tries to access some DP
> registers while the DP controller is still in the reset state. When
> running "rmmod zynqmp_dpsub", zynqmp_dp_reset(dp, true) in
> zynqmp_dp_phy_exit is called to force the DP controller into the reset
> state. Then insmod will call zynqmp_dp_probe to program the DP registers,
> but at this moment the DP controller hasn't been brought out of the reset
> state yet since the function zynqmp_dp_reset(dp, false) is called later and
> this will result the system hang.
> 
> Releasing the reset to DP controller before any read/write operation to it
> will fix this issue. And for symmetry, move zynqmp_dp_reset() call from
> zynqmp_dp_phy_exit() to zynqmp_dp_remove().
> 
> Signed-off-by: Quanyang Wang 

Reviewed-by: Laurent Pinchart 

> ---
> 
> V2:
> According to Laurent's comments:
> - add zynqmp_dp_reset(dp, true) in error path in zynqmp_dp_probe
> - move the zynqmp_dp_reset() call from zynqmp_dp_phy_exit() to 
> zynqmp_dp_remove() 
> 
> ---
>  drivers/gpu/drm/xlnx/zynqmp_dp.c | 22 --
>  1 file changed, 12 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c 
> b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> index 99158ee67d02..337adf0769ad 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
> +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> @@ -402,10 +402,6 @@ static int zynqmp_dp_phy_init(struct zynqmp_dp *dp)
>   }
>   }
>  
> - ret = zynqmp_dp_reset(dp, false);
> - if (ret < 0)
> - return ret;
> -
>   zynqmp_dp_clr(dp, ZYNQMP_DP_PHY_RESET, ZYNQMP_DP_PHY_RESET_ALL_RESET);
>  
>   /*
> @@ -441,8 +437,6 @@ static void zynqmp_dp_phy_exit(struct zynqmp_dp *dp)
>   ret);
>   }
>  
> - zynqmp_dp_reset(dp, true);
> -
>   for (i = 0; i < dp->num_lanes; i++) {
>   ret = phy_exit(dp->phy[i]);
>   if (ret)
> @@ -1682,9 +1676,13 @@ int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub, struct 
> drm_device *drm)
>   return PTR_ERR(dp->reset);
>   }
>  
> + ret = zynqmp_dp_reset(dp, false);
> + if (ret < 0)
> + return ret;
> +
>   ret = zynqmp_dp_phy_probe(dp);
>   if (ret)
> - return ret;
> + goto err_reset;
>  
>   /* Initialize the hardware. */
>   zynqmp_dp_write(dp, ZYNQMP_DP_TX_PHY_POWER_DOWN,
> @@ -1696,7 +1694,7 @@ int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub, struct 
> drm_device *drm)
>  
>   ret = zynqmp_dp_phy_init(dp);
>   if (ret)
> - return ret;
> + goto err_reset;
>  
>   zynqmp_dp_write(dp, ZYNQMP_DP_TRANSMITTER_ENABLE, 1);
>  
> @@ -1708,15 +1706,18 @@ int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub, 
> struct drm_device *drm)
>   zynqmp_dp_irq_handler, IRQF_ONESHOT,
>   dev_name(dp->dev), dp);
>   if (ret < 0)
> - goto error;
> + goto err_phy_exit;
>  
>   dev_dbg(dp->dev, "ZynqMP DisplayPort Tx probed with %u lanes\n",
>   dp->num_lanes);
>  
>   return 0;
>  
> -error:
> +err_phy_exit:
>   zynqmp_dp_phy_exit(dp);
> +err_reset:
> + zynqmp_dp_reset(dp, true);
> +
>   return ret;
>  }
>  
> @@ -1734,4 +1735,5 @@ void zynqmp_dp_remove(struct zynqmp_dpsub *dpsub)
>   zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, 0x);
>  
>   zynqmp_dp_phy_exit(dp);
> + zynqmp_dp_reset(dp, true);
>  }

-- 
Regards,

Laurent Pinchart


[RESEND] regulator: mt6360: remove redundant error print

2021-03-23 Thread Jian Dong
From: Jian Dong 

fixes coccicheck warning:

drivers/regulator/mt6360-regulator.c:384:3-10: line 384 is
redundant because platform_get_irq() already prints an error

in fact it is not platform_get_irq but platform_get_irq_byname print error

Signed-off-by: Jian Dong 
---
 drivers/regulator/mt6360-regulator.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/regulator/mt6360-regulator.c 
b/drivers/regulator/mt6360-regulator.c
index 15308ee..4d34be9 100644
--- a/drivers/regulator/mt6360-regulator.c
+++ b/drivers/regulator/mt6360-regulator.c
@@ -380,10 +380,8 @@ static int mt6360_regulator_irq_register(struct 
platform_device *pdev,
const struct mt6360_irq_mapping *irq_desc = tbls + i;
 
irq = platform_get_irq_byname(pdev, irq_desc->name);
-   if (irq < 0) {
-   dev_err(>dev, "Fail to get %s irq\n", 
irq_desc->name);
+   if (irq < 0)
return irq;
-   }
 
ret = devm_request_threaded_irq(>dev, irq, NULL, 
irq_desc->handler, 0,
irq_desc->name, rdev);
-- 
1.9.1




Re: drivers/staging/qlge/qlge_main.c:4564 qlge_probe() warn: missing error code 'err'

2021-03-23 Thread Coiby Xu

On Mon, Mar 22, 2021 at 06:14:08PM +0300, Dan Carpenter wrote:

On Wed, Mar 10, 2021 at 08:21:37AM +0800, Coiby Xu wrote:

Hi Dan,

Thanks for finding this issue! I'll submit all the patches including the
one for the previous issue reported by you ("[bug report] staging: qlge:
Initialize devlink health dump framework") after finishing all items listed
in drivers/staging/qlge/TODO.



I just sent a patch for this.

Part of my QC process before I send a patch is to search my inbox to
see if I have already sent the patch before.  I have the memory of a
gnat and static checker warnings all look the same after a while so I
once wrote the same patch three times before I implemented this as part
of my QC process.

Anyway, it turns out that I did report this bug already but since you
hadn't sent a fix, I decided to just send my fix instead of deleting it.



Thank you for sharing the info about your QC process. 


When kbuild detects a bug in your patch then please fix it as soon as
you can.  Certainly don't wait until "all the TODO items" are done.  (0_0)


Thanks for the suggestion! The reason I haven't sent the patch for this
bug is I haven't tested the patch on a system using this qlge driver.
Red Hat has a system where I can do testing but I need to borrow it and
return it asap. So I want to test all the patches together when finishing 
"all the TODO items". 


Just do what I do and promise to "fix it tomorrow morning" and then
forget about it forever.  ;)



Sorry for keeping you waiting. I'll fix a bug detected by kbuild as soon
as possible next time especially when a fix is unlikely to introduce
another issue.


regards,
dan carpenter


On Thu, Feb 25, 2021 at 01:03:03PM +0300, Dan Carpenter wrote:
> tree:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git  
master
> head:   29c395c77a9a514c5857c45ceae2665e9bd99ac7
> commit: 953b94009377419f28fd0153f91fcd5b5a347608 staging: qlge: Initialize 
devlink health dump framework
> config: i386-randconfig-m021-20210225 (attached as .config)
> compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
>
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot 
> Reported-by: Dan Carpenter 
>
> smatch warnings:
> drivers/staging/qlge/qlge_main.c:4564 qlge_probe() warn: missing error code 
'err'
>
> vim +/err +4564 drivers/staging/qlge/qlge_main.c
>
> 5d8e87265715a1 drivers/net/ethernet/qlogic/qlge/qlge_main.c Bill Pemberton
 2012-12-03  4544  static int qlge_probe(struct pci_dev *pdev,
> c4e84bde1d595d drivers/net/qlge/qlge_main.c Ron Mercer
 2008-09-18  4545  const struct pci_device_id *pci_entry)
> c4e84bde1d595d drivers/net/qlge/qlge_main.c Ron Mercer
 2008-09-18  4546  {
> 953b9400937741 drivers/staging/qlge/qlge_main.c Coiby Xu  
 2021-01-23  4547struct qlge_netdev_priv *ndev_priv;
> f8c047be540197 drivers/staging/qlge/qlge_main.c Coiby Xu  
 2021-01-23  4548struct qlge_adapter *qdev = NULL;
> 953b9400937741 drivers/staging/qlge/qlge_main.c Coiby Xu  
 2021-01-23  4549struct net_device *ndev = NULL;
> 953b9400937741 drivers/staging/qlge/qlge_main.c Coiby Xu  
 2021-01-23  4550struct devlink *devlink;
> f41e1a0a9462fc drivers/staging/qlge/qlge_main.c Dorothea Ehrl 
 2019-11-27  4551static int cards_found;
> c4e84bde1d595d drivers/net/qlge/qlge_main.c Ron Mercer
 2008-09-18  4552int err = 0;
> c4e84bde1d595d drivers/net/qlge/qlge_main.c Ron Mercer
 2008-09-18  4553
> 953b9400937741 drivers/staging/qlge/qlge_main.c Coiby Xu   
2021-01-23  4554devlink = devlink_alloc(_devlink_ops, sizeof(struct 
qlge_adapter));
> 953b9400937741 drivers/staging/qlge/qlge_main.c Coiby Xu  
 2021-01-23  4555if (!devlink)
> 953b9400937741 drivers/staging/qlge/qlge_main.c Coiby Xu  
 2021-01-23  4556return -ENOMEM;
> 953b9400937741 drivers/staging/qlge/qlge_main.c Coiby Xu  
 2021-01-23  4557
> 953b9400937741 drivers/staging/qlge/qlge_main.c Coiby Xu  
 2021-01-23  4558qdev = devlink_priv(devlink);
> 953b9400937741 drivers/staging/qlge/qlge_main.c Coiby Xu  
 2021-01-23  4559
> 953b9400937741 drivers/staging/qlge/qlge_main.c Coiby Xu  
 2021-01-23  4560ndev = alloc_etherdev_mq(sizeof(struct qlge_netdev_priv),
> 1b998958b301fb drivers/staging/qlge/qlge_main.c Scott Schafer 
 2019-12-11  4561 min(MAX_CPUS,
> 1b998958b301fb drivers/staging/qlge/qlge_main.c Scott Schafer 
 2019-12-11  4562 
netif_get_num_default_rss_queues()));
> c4e84bde1d595d drivers/net/qlge/qlge_main.c Ron Mercer
 2008-09-18  4563if (!ndev)
> 953b9400937741 

Re: [PATCH] arm64: dts: qcom: trogdor: Add no-hpd to DSI bridge node

2021-03-23 Thread Laurent Pinchart
Hi Stephen,

Thank you for the patch.

On Tue, Mar 23, 2021 at 07:55:34PM -0700, Stephen Boyd wrote:
> We should indicate that we're not using the HPD pin on this device, per
> the binding document. Otherwise if code in the future wants to enable
> HPD in the bridge when this property is absent we'll be wasting power
> powering hpd when we don't use it on trogdor boards. We didn't notice
> this before because the kernel driver blindly disables hpd, but that
> won't be true for much longer.
> 
> Cc: Laurent Pinchart 
> Cc: Douglas Anderson 
> Fixes: 7ec3e67307f8 ("arm64: dts: qcom: sc7180-trogdor: add initial trogdor 
> and lazor dt")
> Signed-off-by: Stephen Boyd 

Reviewed-by: Laurent Pinchart 

> ---
>  arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi 
> b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
> index 07c8b2c926c0..298af6d7fb4a 100644
> --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
> @@ -595,6 +595,8 @@ sn65dsi86_bridge: bridge@2d {
>   clocks = < RPMH_LN_BB_CLK3>;
>   clock-names = "refclk";
>  
> + no-hpd;
> +
>   ports {
>   #address-cells = <1>;
>   #size-cells = <0>;

-- 
Regards,

Laurent Pinchart


[PATCH 2/2] net: ipv4: route.c: Remove unnecessary if()

2021-03-23 Thread Yejune Deng
negative_advice handler is only called when dst is non-NULL hence the
'if (rt)' check can be removed. 'if' and 'else if' can be merged together.
And use container_of() instead of (struct rtable *).

Signed-off-by: Yejune Deng 
---
 net/ipv4/route.c | 16 ++--
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 5762d9bc671c..f4ba07c5c1b1 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -814,19 +814,15 @@ static void ip_do_redirect(struct dst_entry *dst, struct 
sock *sk, struct sk_buf
 
 static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
 {
-   struct rtable *rt = (struct rtable *)dst;
+   struct rtable *rt = container_of(dst, struct rtable, dst);
struct dst_entry *ret = dst;
 
-   if (rt) {
-   if (dst->obsolete > 0) {
-   ip_rt_put(rt);
-   ret = NULL;
-   } else if ((rt->rt_flags & RTCF_REDIRECTED) ||
-  rt->dst.expires) {
-   ip_rt_put(rt);
-   ret = NULL;
-   }
+   if (dst->obsolete > 0 || rt->dst.expires ||
+   (rt->rt_flags & RTCF_REDIRECTED)) {
+   ip_rt_put(rt);
+   ret = NULL;
}
+
return ret;
 }
 
-- 
2.29.0



Re: [PATCH v30 07/12] landlock: Support filesystem access-control

2021-03-23 Thread Jann Horn
On Tue, Mar 23, 2021 at 8:22 PM Mickaël Salaün  wrote:
> On 23/03/2021 18:49, Jann Horn wrote:
> > On Tue, Mar 23, 2021 at 4:54 PM Mickaël Salaün  wrote:
> >> On 23/03/2021 01:13, Jann Horn wrote:
> >>>  On Tue, Mar 16, 2021 at 9:43 PM Mickaël Salaün  wrote:
>  Using Landlock objects and ruleset, it is possible to tag inodes
>  according to a process's domain.
> >>> [...]
>  +static void release_inode(struct landlock_object *const object)
>  +   __releases(object->lock)
>  +{
>  +   struct inode *const inode = object->underobj;
>  +   struct super_block *sb;
>  +
>  +   if (!inode) {
>  +   spin_unlock(>lock);
>  +   return;
>  +   }
>  +
>  +   /*
>  +* Protects against concurrent use by hook_sb_delete() of the 
>  reference
>  +* to the underlying inode.
>  +*/
>  +   object->underobj = NULL;
>  +   /*
>  +* Makes sure that if the filesystem is concurrently unmounted,
>  +* hook_sb_delete() will wait for us to finish iput().
>  +*/
>  +   sb = inode->i_sb;
>  +   atomic_long_inc(_superblock(sb)->inode_refs);
>  +   spin_unlock(>lock);
>  +   /*
>  +* Because object->underobj was not NULL, hook_sb_delete() and
>  +* get_inode_object() guarantee that it is safe to reset
>  +* landlock_inode(inode)->object while it is not NULL.  It is 
>  therefore
>  +* not necessary to lock inode->i_lock.
>  +*/
>  +   rcu_assign_pointer(landlock_inode(inode)->object, NULL);
>  +   /*
>  +* Now, new rules can safely be tied to @inode with 
>  get_inode_object().
>  +*/
>  +
>  +   iput(inode);
>  +   if 
>  (atomic_long_dec_and_test(_superblock(sb)->inode_refs))
>  +   wake_up_var(_superblock(sb)->inode_refs);
>  +}
> >>> [...]
>  +static struct landlock_object *get_inode_object(struct inode *const 
>  inode)
>  +{
>  +   struct landlock_object *object, *new_object;
>  +   struct landlock_inode_security *inode_sec = 
>  landlock_inode(inode);
>  +
>  +   rcu_read_lock();
>  +retry:
>  +   object = rcu_dereference(inode_sec->object);
>  +   if (object) {
>  +   if (likely(refcount_inc_not_zero(>usage))) {
>  +   rcu_read_unlock();
>  +   return object;
>  +   }
>  +   /*
>  +* We are racing with release_inode(), the object is 
>  going
>  +* away.  Wait for release_inode(), then retry.
>  +*/
>  +   spin_lock(>lock);
>  +   spin_unlock(>lock);
>  +   goto retry;
>  +   }
>  +   rcu_read_unlock();
>  +
>  +   /*
>  +* If there is no object tied to @inode, then create a new one 
>  (without
>  +* holding any locks).
>  +*/
>  +   new_object = landlock_create_object(_fs_underops, 
>  inode);
>  +   if (IS_ERR(new_object))
>  +   return new_object;
>  +
>  +   /* Protects against concurrent get_inode_object() calls. */
>  +   spin_lock(>i_lock);
>  +   object = rcu_dereference_protected(inode_sec->object,
>  +   lockdep_is_held(>i_lock));
> >>>
> >>> rcu_dereference_protected() requires that inode_sec->object is not
> >>> concurrently changed, but I think another thread could call
> >>> get_inode_object() while we're in landlock_create_object(), and then
> >>> we could race with the NULL write in release_inode() here? (It
> >>> wouldn't actually be a UAF though because we're not actually accessing
> >>> `object` here.) Or am I missing a lock that prevents this?
> >>>
> >>> In v28 this wasn't an issue because release_inode() was holding
> >>> inode->i_lock (and object->lock) during the NULL store; but in v29 and
> >>> this version the NULL store in release_inode() moved out of the locked
> >>> region. I think you could just move the NULL store in release_inode()
> >>> back up (and maybe add a comment explaining the locking rules for
> >>> landlock_inode(...)->object)?
> >>>
> >>> (Or alternatively you could use rcu_dereference_raw() with a comment
> >>> explaining that the read pointer is only used to check for NULL-ness,
> >>> and that it is guaranteed that the pointer can't change if it is NULL
> >>> and we're holding the lock. But that'd be needlessly complicated, I
> >>> think.)
> >>
> >> To reach rcu_assign_pointer(landlock_inode(inode)->object, NULL) in
> >> release_inode() or in hook_sb_delete(), the
> >> landlock_inode(inode)->object need to be non-NULL,
> >
> > Yes.
> >
> >> which implies that a
> >> call to 

[PATCH 1/2] net: ipv4: route.c: add likely() statements

2021-03-23 Thread Yejune Deng
Add likely() statements in ipv4_confirm_neigh() for 'rt->rt_gw_family
== AF_INET'.

Signed-off-by: Yejune Deng 
---
 net/ipv4/route.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index fa68c2612252..5762d9bc671c 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -440,7 +440,7 @@ static void ipv4_confirm_neigh(const struct dst_entry *dst, 
const void *daddr)
struct net_device *dev = dst->dev;
const __be32 *pkey = daddr;
 
-   if (rt->rt_gw_family == AF_INET) {
+   if (likely(rt->rt_gw_family == AF_INET)) {
pkey = (const __be32 *)>rt_gw4;
} else if (rt->rt_gw_family == AF_INET6) {
return __ipv6_confirm_neigh_stub(dev, >rt_gw6);
-- 
2.29.0



  1   2   3   4   5   6   7   8   9   10   >