RE: [EXT] Re: [v3 2/2] clk: ls1028a: Add clock driver for Display output interface

2019-08-28 Thread Wen He


> -Original Message-
> From: Stephen Boyd 
> Sent: 2019年8月23日 9:27
> To: Mark Rutland ; Michael Turquette
> ; Rob Herring ; Wen He
> ; devicet...@vger.kernel.org; linux-...@vger.kernel.org;
> linux-de...@linux.nxdi.nxp.com; linux-kernel@vger.kernel.org
> Cc: Leo Li ; liviu.du...@arm.com; Wen He
> 
> Subject: [EXT] Re: [v3 2/2] clk: ls1028a: Add clock driver for Display output
> interface
> 
> Caution: EXT Email
> 
> Quoting Wen He (2019-08-21 19:08:47)
> > Add clock driver for QorIQ LS1028A Display output interfaces(LCD,
> > DPHY), as implemented in TSMC CLN28HPM PLL, this PLL supports the
> > programmable integer division and range of the display output pixel clock's
> 27-594MHz.
> >
> > Signed-off-by: Wen He 
> > ---
> > change in v3:
> > - remove the OF dependency
> > - use clk_parent_data instead of parent_name
> >
> >  drivers/clk/Kconfig  |  10 ++
> >  drivers/clk/Makefile |   1 +
> >  drivers/clk/clk-plldig.c | 283
> > +++
> >  3 files changed, 294 insertions(+)
> >  create mode 100644 drivers/clk/clk-plldig.c
> >
> > diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index
> > 801fa1cd0321..ab05f342af04 100644
> > --- a/drivers/clk/Kconfig
> > +++ b/drivers/clk/Kconfig
> > @@ -223,6 +223,16 @@ config CLK_QORIQ
> >   This adds the clock driver support for Freescale QorIQ platforms
> >   using common clock framework.
> >
> > +config CLK_LS1028A_PLLDIG
> > +bool "Clock driver for LS1028A Display output"
> > +depends on ARCH_LAYERSCAPE || COMPILE_TEST
> > +default ARCH_LAYERSCAPE
> > +help
> > +  This driver support the Display output interfaces(LCD, DPHY)
> pixel clocks
> > +  of the QorIQ Layerscape LS1028A, as implemented TSMC
> CLN28HPM PLL. Not all
> > +  features of the PLL are currently supported by the driver. By
> default,
> > +  configured bypass mode with this PLL.
> > +
> >  config COMMON_CLK_XGENE
> > bool "Clock driver for APM XGene SoC"
> > default ARCH_XGENE
> > diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index
> > 0cad76021297..c8e22a764c4d 100644
> > --- a/drivers/clk/Makefile
> > +++ b/drivers/clk/Makefile
> > @@ -44,6 +44,7 @@ obj-$(CONFIG_COMMON_CLK_OXNAS)
> += clk-oxnas.o
> >  obj-$(CONFIG_COMMON_CLK_PALMAS)+= clk-palmas.o
> >  obj-$(CONFIG_COMMON_CLK_PWM)   += clk-pwm.o
> >  obj-$(CONFIG_CLK_QORIQ)+= clk-qoriq.o
> > +obj-$(CONFIG_CLK_LS1028A_PLLDIG)   += clk-plldig.o
> >  obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o
> >  obj-$(CONFIG_COMMON_CLK_HI655X)+= clk-hi655x.o
> >  obj-$(CONFIG_COMMON_CLK_S2MPS11)   += clk-s2mps11.o
> > diff --git a/drivers/clk/clk-plldig.c b/drivers/clk/clk-plldig.c new
> > file mode 100644 index ..c5ce80a46fd4
> > --- /dev/null
> > +++ b/drivers/clk/clk-plldig.c
> > @@ -0,0 +1,283 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +// Copyright 2019 NXP
> 
> Please leave this as C style /* */ comment for the NXP part, but comply with
> the SPDX comment style of // on the first line.
> 
> > +
> > +static long plldig_round_rate(struct clk_hw *hw, unsigned long rate,
> > +   unsigned long *parent) {
> > +   unsigned long parent_rate = *parent;
> > +   unsigned long round_rate;
> > +   u32 mult = 0, rfdphi1 = 0;
> > +   bool found = false;
> > +
> > +   found = plldig_is_valid_range(rate, parent_rate, ,
> > +   , _rate);
> > +   if (!found) {
> > +   pr_warn("%s: unable to round rate %lu, parent
> rate :%lu\n",
> > +   clk_hw_get_name(hw), rate,
> parent_rate);
> > +   return 0;
> 
> This can return an error instead? In fact, you may want to use determine_rate
> clk op instead.
> 
> > +   }
> > +
> > +   return round_rate / rfdphi1;
> > +}
> > +
> > +static int plldig_set_rate(struct clk_hw *hw, unsigned long rate,
> > +   unsigned long parent_rate) {
> > +   struct clk_plldig *data = to_clk_plldig(hw);
> > +   bool valid = false;
> > +   unsigned long round_rate = 0;
> > +   u32 rfdphi1 = 0, val, mult = 0, cond = 0;
> > +   int ret = -ETIMEDOUT;
> > +
> > +   valid = plldig_is_valid_range(rate, parent_rate, ,
> > +   , _rate);
> > +   if (!valid) {
> > +   pr_warn("%s: unable to support rate %lu,
> parent_rate: %lu\n",
> > +   clk_hw_get_name(hw), rate,
> > + parent_rate);
> 
> Shouldn't determine_rate or round_rate make this impossible to hit in 
> practice?
> I mean that those ops should prevent the rate from being rounded to such a
> frequency that it becomes invalid.
> 
> > +   return -EINVAL;
> > +   }
> > +
> > +   val = readl(data->regs + PLLDIG_REG_PLLDV);
> > +   val = mult;
> > +   rfdphi1 = 

RE: [PATCH 2/2] clk: imx: disable i.mx7ulp composite clock during initialization

2019-08-28 Thread Anson Huang
Hi, Stephen

> Subject: RE: [PATCH 2/2] clk: imx: disable i.mx7ulp composite clock during
> initialization
> 
> Hi, Stephen
>   I think we should resume this thread, without this patch, mainline
> kernel boot up will cause mmc timeout all the time. If it is NOT good to
> disabling those peripheral devices' clock in i.MX7ULP's clock driver, then we
> have to change the core framework to disable clock explicitly if the
> CLK_SET_RATE_GATE/CLK_SET_PARENT_GATE is present, most likely it will
> impact other platforms I think, so the most safe way is just to do it inside 
> our
> i.MX7ULP composite clock driver. What do you think?

What is your opinion on this?

Thanks,
Anson

> 
> Thanks,
> Anson
> 
> > Hi, Stephen
> >
> > > Quoting Anson Huang (2019-04-24 22:19:12)
> > > > i.MX7ULP peripheral clock ONLY allow parent/rate to be changed
> > > > with clock gated, however, during clock tree initialization, the
> > > > peripheral clock could be enabled by bootloader, but the prepare
> > > > count in clock tree is still zero, so clock core driver will allow
> > > > parent/rate changed even with
> > CLK_SET_RATE_GATE/CLK_SET_PARENT_GATE
> > >
> > > That's a bug. Can you send a patch to fix the core framework code to
> > > fail an assigned rate or parent change if those flags are set? Or is
> > > that because the core doesn't respect these flags when they're
> > > buried in the middle of the clk tree and some rate or parent change
> > > comes in and affects the middle of the tree that has the flag set on it?
> >
> > If changing the core framework code to return fail for clk parent/rate
> > assignment, that means clk assignment in DT will NOT work for
> > i.MX7ULP, then all the clk rate/parent settings will be done in
> > driver? That will lead to more issues/changes.
> >
> > It is just because core framework ONLY checks the prepare_count and
> > CLK_SET_PARENT_GATE flag to determine if the parent switch is allowed,
> > however, during clock tree initialization, the prepare_count is always
> > 0 but the HW status could be enabled actually, so the core framework
> > will allow the parent switch while HW status does NOT allow the parent
> > switch, so core framework will treat the parent switch successfully but HW
> is actually NOT.
> >
> > I think we can treat it as platform specific issue, if bootloader can
> > guarantee all peripheral clocks are disabled before jumping to kernel,
> > then there will be no issue, but we can NOT assume that, so I have to
> > find some place in early kernel phase to disable those peripheral clocks.
> >
> > >
> > > > set, but the change will fail due to HW NOT allow parent/rate
> > > > change with clock enabled. It will cause clock HW status mismatch
> > > > with clock tree info and lead to function issue. Below is an example:
> > > >
> > > > usdhc0's pcc clock value is 0xC500 during kernel boot up, it
> > > > means
> > > > usdhc0 clock is enabled, its parent is APLL_PFD1. In DT file, the
> > > > usdhc0 clock settings are as below:
> > > >
> > > > assigned-clocks = < IMX7ULP_CLK_USDHC0>;
> > > > assigned-clock-parents =
> > > > < IMX7ULP_CLK_NIC1_DIV>;
> > > >
> > > > when kernel boot up, the clock tree info is as below, but the
> > > > usdhc0 PCC register is still 0xC500, which means its parent is
> > > > still from APLL_PFD1, which is incorrect and cause usdhc0 NOT work.
> > > >
> > > > nic1_clk   220   17600  0 0  5
> > > > usdhc0   000   17600  0 0  5
> > > >
> > > > After making sure the peripheral clock is disabled during clock
> > > > tree initialization, the usdhc0 is working, and this change is
> > > > necessary for all i.MX7ULP peripheral clocks.
> > > >
> > > > Signed-off-by: Anson Huang 
> > > > ---
> > > >  drivers/clk/imx/clk-composite-7ulp.c | 13 +
> > > >  1 file changed, 13 insertions(+)
> > > >
> > > > diff --git a/drivers/clk/imx/clk-composite-7ulp.c
> > > > b/drivers/clk/imx/clk-composite-7ulp.c
> > > > index 060f860..1a05411 100644
> > > > --- a/drivers/clk/imx/clk-composite-7ulp.c
> > > > +++ b/drivers/clk/imx/clk-composite-7ulp.c
> > > > @@ -32,6 +32,7 @@ struct clk_hw *imx7ulp_clk_composite(const char
> > > *name,
> > > > struct clk_gate *gate = NULL;
> > > > struct clk_mux *mux = NULL;
> > > > struct clk_hw *hw;
> > > > +   u32 val;
> > > >
> > > > if (mux_present) {
> > > > mux = kzalloc(sizeof(*mux), GFP_KERNEL); @@ -70,6
> > > > +71,18 @@ struct clk_hw *imx7ulp_clk_composite(const char *name,
> > > > gate_hw = >hw;
> > > > gate->reg = reg;
> > > > gate->bit_idx = PCG_CGC_SHIFT;
> > > > +   /*
> > > > +* make sure clock is gated during clock tree 
> > > > initialization,
> > > > +* the HW ONLY allow clock parent/rate changed
> > > > + with clock
> > gated,
> > > > +* during clock tree 

[PATCH] Revert "iio: imu: st_lsm6dsx: remove invalid gain value for LSM9DS1"

2019-08-28 Thread Martin Kepplinger
The st_lsm6dsx_sensor_settings struct's fs_avl[] array is expected to
be of size 4. We can't define it to be of size 3 and try to access
the 4th element below.

Commit c8d4066c7246 ("iio: imu: st_lsm6dsx: remove invalid gain value
for LSM9DS1") which is a "cleanup" change, results in an Ooops here
so revert it.

Signed-off-by: Martin Kepplinger 
---
 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 17 ++---
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c 
b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
index 2d3495560136..499745424c1e 100644
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
@@ -151,9 +151,10 @@ static const struct st_lsm6dsx_settings 
st_lsm6dsx_sensor_settings[] = {
.addr = 0x10,
.mask = GENMASK(4, 3),
},
-   .fs_avl[0] = {  IIO_DEGREE_TO_RAD(245), 0x0 },
-   .fs_avl[1] = {  IIO_DEGREE_TO_RAD(500), 0x1 },
-   .fs_avl[2] = { IIO_DEGREE_TO_RAD(2000), 0x3 },
+   .fs_avl[0] = { IIO_DEGREE_TO_RAD(245), 0x0 },
+   .fs_avl[1] = { IIO_DEGREE_TO_RAD(500), 0x1 },
+   .fs_avl[2] = { IIO_DEGREE_TO_RAD(0), 0x2 },
+   .fs_avl[3] = { IIO_DEGREE_TO_RAD(2000), 0x3 },
},
},
},
@@ -1195,19 +1196,13 @@ static ssize_t st_lsm6dsx_sysfs_scale_avail(struct 
device *dev,
char *buf)
 {
struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
-   const struct st_lsm6dsx_fs_table_entry *fs_table;
enum st_lsm6dsx_sensor_id id = sensor->id;
struct st_lsm6dsx_hw *hw = sensor->hw;
int i, len = 0;
 
-   fs_table = >settings->fs_table[id];
-   for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++) {
-   if (!fs_table->fs_avl[i].gain)
-   break;
-
+   for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++)
len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ",
-fs_table->fs_avl[i].gain);
-   }
+hw->settings->fs_table[id].fs_avl[i].gain);
buf[len - 1] = '\n';
 
return len;
-- 
2.20.1



[PATCH] binder: Use kmem_cache for binder_thread

2019-08-28 Thread Peikan Tsai
Hi,

The allocated size for each binder_thread is 512 bytes by kzalloc.
Because the size of binder_thread is fixed and it's only 304 bytes.
It will save 208 bytes per binder_thread when use create a kmem_cache
for the binder_thread.

Signed-off-by: Peikan Tsai 
---
 drivers/android/binder.c | 16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index dc1c83eafc22..043e0ebd0fe7 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -87,6 +87,8 @@ static struct dentry *binder_debugfs_dir_entry_root;
 static struct dentry *binder_debugfs_dir_entry_proc;
 static atomic_t binder_last_id;

+static struct kmem_cache *binder_thread_cachep;
+
 static int proc_show(struct seq_file *m, void *unused);
 DEFINE_SHOW_ATTRIBUTE(proc);

@@ -4696,14 +4698,15 @@ static struct binder_thread *binder_get_thread(struct 
binder_proc *proc)
thread = binder_get_thread_ilocked(proc, NULL);
binder_inner_proc_unlock(proc);
if (!thread) {
-   new_thread = kzalloc(sizeof(*thread), GFP_KERNEL);
+   new_thread = kmem_cache_zalloc(binder_thread_cachep,
+  GFP_KERNEL);
if (new_thread == NULL)
return NULL;
binder_inner_proc_lock(proc);
thread = binder_get_thread_ilocked(proc, new_thread);
binder_inner_proc_unlock(proc);
if (thread != new_thread)
-   kfree(new_thread);
+   kmem_cache_free(binder_thread_cachep, new_thread);
}
return thread;
 }
@@ -4723,7 +4726,7 @@ static void binder_free_thread(struct binder_thread 
*thread)
BUG_ON(!list_empty(>todo));
binder_stats_deleted(BINDER_STAT_THREAD);
binder_proc_dec_tmpref(thread->proc);
-   kfree(thread);
+   kmem_cache_free(binder_thread_cachep, thread);
 }

 static int binder_thread_release(struct binder_proc *proc,
@@ -6095,6 +6098,12 @@ static int __init binder_init(void)
if (ret)
return ret;

+   binder_thread_cachep = kmem_cache_create("binder_thread",
+sizeof(struct binder_thread),
+0, 0, NULL);
+   if (!binder_thread_cachep)
+   return -ENOMEM;
+
atomic_set(_transaction_log.cur, ~0U);
atomic_set(_transaction_log_failed.cur, ~0U);

@@ -6167,6 +6176,7 @@ static int __init binder_init(void)

 err_alloc_device_names_failed:
debugfs_remove_recursive(binder_debugfs_dir_entry_root);
+   kmem_cache_destroy(binder_thread_cachep);

return ret;
 }
--
2.17.1



[PATCH v6 11/11] arm: dts: mediatek: add mt7629 pwm support

2019-08-28 Thread Sam Shih
This adds pwm support for MT7629.

Signed-off-by: Sam Shih 
---
 arch/arm/boot/dts/mt7629.dtsi | 16 
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/boot/dts/mt7629.dtsi b/arch/arm/boot/dts/mt7629.dtsi
index 9608bc2ccb3f..493be9a9453b 100644
--- a/arch/arm/boot/dts/mt7629.dtsi
+++ b/arch/arm/boot/dts/mt7629.dtsi
@@ -241,6 +241,22 @@
status = "disabled";
};
 
+   pwm: pwm@11006000 {
+   compatible = "mediatek,mt7629-pwm",
+"mediatek,mt7622-pwm";
+   reg = <0 0x11006000 0 0x1000>;
+   interrupts = ;
+   clocks = < CLK_TOP_PWM_SEL>,
+< CLK_PERI_PWM_PD>,
+< CLK_PERI_PWM1_PD>;
+   clock-names = "top", "main", "pwm1";
+   assigned-clocks = < CLK_TOP_PWM_SEL>;
+   assigned-clock-parents =
+   < CLK_TOP_UNIVPLL2_D4>;
+   num-pwms = <1>;
+   status = "disabled";
+   };
+
i2c: i2c@11007000 {
compatible = "mediatek,mt7629-i2c",
 "mediatek,mt2712-i2c";
-- 
2.17.1



[PATCH v6 10/11] dt-bindings: pwm: update bindings for MT7629 SoC

2019-08-28 Thread Sam Shih
From: Ryder Lee 

This updates bindings for MT7629 pwm controller.

Signed-off-by: Ryder Lee 
Signed-off-by: Sam Shih 
Reviewed-by: Matthias Brugger 
---
Changes since v1:
- add a Reviewed-by tag

---
 Documentation/devicetree/bindings/pwm/pwm-mediatek.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pwm/pwm-mediatek.txt 
b/Documentation/devicetree/bindings/pwm/pwm-mediatek.txt
index ea95b490a913..c7bd5633d1eb 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-mediatek.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-mediatek.txt
@@ -6,6 +6,7 @@ Required properties:
- "mediatek,mt7622-pwm": found on mt7622 SoC.
- "mediatek,mt7623-pwm": found on mt7623 SoC.
- "mediatek,mt7628-pwm": found on mt7628 SoC.
+   - "mediatek,mt7629-pwm", "mediatek,mt7622-pwm": found on mt7629 SoC.
  - reg: physical base address and length of the controller's registers.
  - #pwm-cells: must be 2. See pwm.txt in this directory for a description of
the cell format.
-- 
2.17.1



[PATCH v6 09/11] arm: dts: mt7623: add a property "num-pwms" for PWM

2019-08-28 Thread Sam Shih
From: Ryder Lee 

This adds a property "num-pwms" for PWM controller.

Signed-off-by: Ryder Lee 
Signed-off-by: Sam Shih 
---
 arch/arm/boot/dts/mt7623.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi
index a79f0b6c3429..208e0d19a575 100644
--- a/arch/arm/boot/dts/mt7623.dtsi
+++ b/arch/arm/boot/dts/mt7623.dtsi
@@ -452,6 +452,7 @@
 < CLK_PERI_PWM5>;
clock-names = "top", "main", "pwm1", "pwm2",
  "pwm3", "pwm4", "pwm5";
+   num-pwms = <5>;
status = "disabled";
};
 
-- 
2.17.1



[PATCH v6 08/11] arm64: dts: mt7622: add a property "num-pwms" for PWM

2019-08-28 Thread Sam Shih
From: Ryder Lee 

This adds a property "num-pwms" for PWM controller.

Signed-off-by: Ryder Lee 
Signed-off-by: Sam Shih 
---
 arch/arm64/boot/dts/mediatek/mt7622.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi 
b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
index d1e13d340e26..9a043938881f 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
@@ -439,6 +439,7 @@
 < CLK_PERI_PWM6_PD>;
clock-names = "top", "main", "pwm1", "pwm2", "pwm3", "pwm4",
  "pwm5", "pwm6";
+   num-pwms = <6>;
status = "disabled";
};
 
-- 
2.17.1



[PATCH v6 07/11] dt-bindings: pwm: pwm-mediatek: add a property "num-pwms"

2019-08-28 Thread Sam Shih
From: Ryder Lee 

This adds a property "num-pwms" in example so that we could
specify the number of PWM channels via device tree.

Signed-off-by: Ryder Lee 
Signed-off-by: Sam Shih 
Reviewed-by: Matthias Brugger 
Acked-by: Uwe Kleine-König 
---
Changes since v6:
Follow reviewers's comments:
- The subject should indicate this is for Mediatek

Changes since v5:
- Add an Acked-by tag
- This file is original v4 patch 5/10
(https://patchwork.kernel.org/patch/11102577/)

---
 Documentation/devicetree/bindings/pwm/pwm-mediatek.txt | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/pwm/pwm-mediatek.txt 
b/Documentation/devicetree/bindings/pwm/pwm-mediatek.txt
index 991728cb46cb..ea95b490a913 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-mediatek.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-mediatek.txt
@@ -14,12 +14,12 @@ Required properties:
 has no clocks
- "top": the top clock generator
- "main": clock used by the PWM core
-   - "pwm1-8": the eight per PWM clocks for mt2712
-   - "pwm1-6": the six per PWM clocks for mt7622
-   - "pwm1-5": the five per PWM clocks for mt7623
+   - "pwm1-N": the PWM clocks for each channel
+   where N starting from 1 to the maximum number of PWM channels
  - pinctrl-names: Must contain a "default" entry.
  - pinctrl-0: One property must exist for each entry in pinctrl-names.
See pinctrl/pinctrl-bindings.txt for details of the property values.
+ - num-pwms: the number of PWM channels.
 
 Example:
pwm0: pwm@11006000 {
@@ -37,4 +37,5 @@ Example:
  "pwm3", "pwm4", "pwm5";
pinctrl-names = "default";
pinctrl-0 = <_pins>;
+   num-pwms = <5>;
};
-- 
2.17.1



[PATCH v6 06/11] pwm: mediatek: update license and switch to SPDX tag

2019-08-28 Thread Sam Shih
Add SPDX identifiers to pwm-mediatek.c
Update license to GNU General Public License v2.0

Signed-off-by: Ryder Lee 
Signed-off-by: Sam Shih 
Reviewed-by: Uwe Kleine-König 
---
Changes since v6:
Add a Reviewed-by tag

Changes since v5:
- Follow reviewers's comments
The license stuff is a separate change

---
 drivers/pwm/pwm-mediatek.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
index 11f9cc446f14..9a61829766fc 100644
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
@@ -1,12 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
- * Mediatek Pulse Width Modulator driver
+ * MediaTek Pulse Width Modulator driver
  *
  * Copyright (C) 2015 John Crispin 
  * Copyright (C) 2017 Zhi Mao 
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #include 
@@ -331,4 +329,4 @@ static struct platform_driver pwm_mediatek_driver = {
 module_platform_driver(pwm_mediatek_driver);
 
 MODULE_AUTHOR("John Crispin ");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
-- 
2.17.1



[PATCH v6 05/11] pwm: mediatek: use pwm_mediatek as common prefix

2019-08-28 Thread Sam Shih
Use pwm_mediatek as common prefix to match the filename.
No functional change intended.

Signed-off-by: Ryder Lee 
Signed-off-by: Sam Shih 
Acked-by: Uwe Kleine-König 
---
Changes since v6:
Add an Acked-by tag

Changes since v5:
- Follow reviewers's comments
The license stuff is a separate change

---
 drivers/pwm/pwm-mediatek.c | 116 +++--
 1 file changed, 59 insertions(+), 57 deletions(-)

diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
index 71bfab7e2e19..11f9cc446f14 100644
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
@@ -34,14 +34,13 @@
 #define PWM45THRES_FIXUP   0x34
 
 #define PWM_CLK_DIV_MAX7
-
-struct mtk_pwm_platform_data {
+struct pwm_mediatek_of_data {
unsigned int fallback_npwms;
bool pwm45_fixup;
 };
 
 /**
- * struct mtk_pwm_chip - struct representing PWM chip
+ * struct pwm_mediatek_chip - struct representing PWM chip
  * @chip: linux PWM chip representation
  * @regs: base address of PWM chip
  * @clk_top: the top clock generator
@@ -49,27 +48,29 @@ struct mtk_pwm_platform_data {
  * @clk_pwms: the clock used by each PWM channel
  * @clk_freq: the fix clock frequency of legacy MIPS SoC
  */
-struct mtk_pwm_chip {
+struct pwm_mediatek_chip {
struct pwm_chip chip;
void __iomem *regs;
struct clk *clk_top;
struct clk *clk_main;
struct clk **clk_pwms;
-   const struct mtk_pwm_platform_data *soc;
+   const struct pwm_mediatek_of_data *soc;
 };
 
-static const unsigned int mtk_pwm_reg_offset[] = {
+static const unsigned int pwm_mediatek_reg_offset[] = {
0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
 };
 
-static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
+static inline struct pwm_mediatek_chip *
+to_pwm_mediatek_chip(struct pwm_chip *chip)
 {
-   return container_of(chip, struct mtk_pwm_chip, chip);
+   return container_of(chip, struct pwm_mediatek_chip, chip);
 }
 
-static int mtk_pwm_clk_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+static int pwm_mediatek_clk_enable(struct pwm_chip *chip,
+  struct pwm_device *pwm)
 {
-   struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
+   struct pwm_mediatek_chip *pc = to_pwm_mediatek_chip(chip);
int ret;
 
ret = clk_prepare_enable(pc->clk_top);
@@ -94,45 +95,46 @@ static int mtk_pwm_clk_enable(struct pwm_chip *chip, struct 
pwm_device *pwm)
return ret;
 }
 
-static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+static void pwm_mediatek_clk_disable(struct pwm_chip *chip,
+struct pwm_device *pwm)
 {
-   struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
+   struct pwm_mediatek_chip *pc = to_pwm_mediatek_chip(chip);
 
clk_disable_unprepare(pc->clk_pwms[pwm->hwpwm]);
clk_disable_unprepare(pc->clk_main);
clk_disable_unprepare(pc->clk_top);
 }
 
-static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
-   unsigned int offset)
+static inline u32 pwm_mediatek_readl(struct pwm_mediatek_chip *chip,
+unsigned int num, unsigned int offset)
 {
-   return readl(chip->regs + mtk_pwm_reg_offset[num] + offset);
+   return readl(chip->regs + pwm_mediatek_reg_offset[num] + offset);
 }
 
-static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
- unsigned int num, unsigned int offset,
- u32 value)
+static inline void pwm_mediatek_writel(struct pwm_mediatek_chip *chip,
+  unsigned int num, unsigned int offset,
+  u32 value)
 {
-   writel(value, chip->regs + mtk_pwm_reg_offset[num] + offset);
+   writel(value, chip->regs + pwm_mediatek_reg_offset[num] + offset);
 }
 
-static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
- int duty_ns, int period_ns)
+static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm,
+  int duty_ns, int period_ns)
 {
-   struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
-   struct clk *clk = pc->clks[MTK_CLK_PWM1 + pwm->hwpwm];
+   struct pwm_mediatek_chip *pc = to_pwm_mediatek_chip(chip);
u32 clkdiv = 0, cnt_period, cnt_duty, reg_width = PWMDWIDTH,
reg_thres = PWMTHRES;
u64 resolution;
int ret;
 
-   ret = mtk_pwm_clk_enable(chip, pwm);
+   ret = pwm_mediatek_clk_enable(chip, pwm);
+
if (ret < 0)
return ret;
 
/* Using resolution in picosecond gets accuracy higher */
resolution = (u64)NSEC_PER_SEC * 1000;
-   do_div(resolution, clk_get_rate(clk));
+   do_div(resolution, clk_get_rate(pc->clk_pwms[pwm->hwpwm]));
 
cnt_period = 

[PATCH v6 04/11] pwm: mediatek: allocate the clks array dynamically

2019-08-28 Thread Sam Shih
Instead of using fixed size of arrays, allocate the memory for them
based on the information we get from the DT.

Also remove the check for num_pwms, due to dynamically allocate pwm
should not cause array index out of bound.

Signed-off-by: Ryder Lee 
Signed-off-by: Sam Shih 
Reviewed-by: Uwe Kleine-König 
---
Changes since v6:
- Add a Reviewed-by tag

Changes since v5:
- Follow reviewers's comments
Make the changes of allocate the clks array dynamically as a single patch

Changes since v4:
- Follow reviewers's comments
1. use pc->soc->has_clks to check clocks exist or not.
2. Add error message when probe() unable to get clks
- Fixes bug when SoC is old mips which has no complex clock tree.
if clocks not exist, use the new property from DT to apply period caculation;
otherwise, use clk_get_rate to get clock frequency and apply period caculation.

---
 drivers/pwm/pwm-mediatek.c | 84 +++---
 1 file changed, 42 insertions(+), 42 deletions(-)

diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
index 07e843aeddb1..71bfab7e2e19 100644
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
@@ -35,25 +35,6 @@
 
 #define PWM_CLK_DIV_MAX7
 
-enum {
-   MTK_CLK_MAIN = 0,
-   MTK_CLK_TOP,
-   MTK_CLK_PWM1,
-   MTK_CLK_PWM2,
-   MTK_CLK_PWM3,
-   MTK_CLK_PWM4,
-   MTK_CLK_PWM5,
-   MTK_CLK_PWM6,
-   MTK_CLK_PWM7,
-   MTK_CLK_PWM8,
-   MTK_CLK_MAX,
-};
-
-static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
-   "main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
-   "pwm8"
-};
-
 struct mtk_pwm_platform_data {
unsigned int fallback_npwms;
bool pwm45_fixup;
@@ -63,12 +44,17 @@ struct mtk_pwm_platform_data {
  * struct mtk_pwm_chip - struct representing PWM chip
  * @chip: linux PWM chip representation
  * @regs: base address of PWM chip
- * @clks: list of clocks
+ * @clk_top: the top clock generator
+ * @clk_main: the clock used by PWM core
+ * @clk_pwms: the clock used by each PWM channel
+ * @clk_freq: the fix clock frequency of legacy MIPS SoC
  */
 struct mtk_pwm_chip {
struct pwm_chip chip;
void __iomem *regs;
-   struct clk *clks[MTK_CLK_MAX];
+   struct clk *clk_top;
+   struct clk *clk_main;
+   struct clk **clk_pwms;
const struct mtk_pwm_platform_data *soc;
 };
 
@@ -86,24 +72,24 @@ static int mtk_pwm_clk_enable(struct pwm_chip *chip, struct 
pwm_device *pwm)
struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
int ret;
 
-   ret = clk_prepare_enable(pc->clks[MTK_CLK_TOP]);
+   ret = clk_prepare_enable(pc->clk_top);
if (ret < 0)
return ret;
 
-   ret = clk_prepare_enable(pc->clks[MTK_CLK_MAIN]);
+   ret = clk_prepare_enable(pc->clk_main);
if (ret < 0)
goto disable_clk_top;
 
-   ret = clk_prepare_enable(pc->clks[MTK_CLK_PWM1 + pwm->hwpwm]);
+   ret = clk_prepare_enable(pc->clk_pwms[pwm->hwpwm]);
if (ret < 0)
goto disable_clk_main;
 
return 0;
 
 disable_clk_main:
-   clk_disable_unprepare(pc->clks[MTK_CLK_MAIN]);
+   clk_disable_unprepare(pc->clk_main);
 disable_clk_top:
-   clk_disable_unprepare(pc->clks[MTK_CLK_TOP]);
+   clk_disable_unprepare(pc->clk_top);
 
return ret;
 }
@@ -112,9 +98,9 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, 
struct pwm_device *pwm)
 {
struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
 
-   clk_disable_unprepare(pc->clks[MTK_CLK_PWM1 + pwm->hwpwm]);
-   clk_disable_unprepare(pc->clks[MTK_CLK_MAIN]);
-   clk_disable_unprepare(pc->clks[MTK_CLK_TOP]);
+   clk_disable_unprepare(pc->clk_pwms[pwm->hwpwm]);
+   clk_disable_unprepare(pc->clk_main);
+   clk_disable_unprepare(pc->clk_top);
 }
 
 static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
@@ -222,7 +208,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
struct device_node *np = pdev->dev.of_node;
struct mtk_pwm_chip *pc;
struct resource *res;
-   unsigned int i, npwms;
+   unsigned int npwms;
int ret;
 
pc = devm_kzalloc(>dev, sizeof(*pc), GFP_KERNEL);
@@ -248,21 +234,35 @@ static int mtk_pwm_probe(struct platform_device *pdev)
}
}
 
-   /* MAIN + TOP + NPWM < MTK_CLK_MAX */
-   if ((npwms + 2) > MTK_CLK_MAX) {
-   dev_warn(>dev, "number of PWMs is larger than %d\n",
-MTK_CLK_MAX - 2);
-   npwms = MTK_CLK_MAX - 2;
+   int i;
+
+   pc->clk_pwms = devm_kcalloc(>dev, npwms,
+   sizeof(*pc->clk_pwms), GFP_KERNEL);
+   if (!pc->clk_pwms)
+   return -ENOMEM;
+
+   pc->clk_top = devm_clk_get(>dev, "top");
+   if (IS_ERR(pc->clk_top)) {
+   dev_err(>dev, "clock: top fail: %ld\n",
+   

[PATCH v6 03/11] pwm: mediatek: remove a property "has-clks"

2019-08-28 Thread Sam Shih
We can use fixed-clock to repair mt7628 pwm during configure from
userspace. The SoC is legacy MIPS and has no complex clock tree.
Due to we can get clock frequency for period calculation from DT
fixed-clock, so we can remove has-clock property, and directly
use devm_clk_get and clk_get_rate.

Signed-off-by: Ryder Lee 
Signed-off-by: Sam Shih 

---
Changes since v6:
Based on fixed-clock in DT, we can remove has-clks property

Changes since v5:
1. Follow reviewer's comments
Make the changes of fix mt7628 pwm as a single patch

Changes since v4:
- Follow reviewers's comments
1. use pc->soc->has_clks to check clocks exist or not.
2. Add error message when probe() unable to get clks
- Fixes bug when SoC is old mips which has no complex clock tree.
if clocks not exist, use the new property from DT to apply period caculation;
otherwise, use clk_get_rate to get clock frequency and apply period caculation.
---
 drivers/pwm/pwm-mediatek.c | 19 +--
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
index ebd62629e3fe..07e843aeddb1 100644
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
@@ -57,7 +57,6 @@ static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
 struct mtk_pwm_platform_data {
unsigned int fallback_npwms;
bool pwm45_fixup;
-   bool has_clks;
 };
 
 /**
@@ -87,9 +86,6 @@ static int mtk_pwm_clk_enable(struct pwm_chip *chip, struct 
pwm_device *pwm)
struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
int ret;
 
-   if (!pc->soc->has_clks)
-   return 0;
-
ret = clk_prepare_enable(pc->clks[MTK_CLK_TOP]);
if (ret < 0)
return ret;
@@ -116,9 +112,6 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, 
struct pwm_device *pwm)
 {
struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
 
-   if (!pc->soc->has_clks)
-   return;
-
clk_disable_unprepare(pc->clks[MTK_CLK_PWM1 + pwm->hwpwm]);
clk_disable_unprepare(pc->clks[MTK_CLK_MAIN]);
clk_disable_unprepare(pc->clks[MTK_CLK_TOP]);
@@ -262,11 +255,13 @@ static int mtk_pwm_probe(struct platform_device *pdev)
npwms = MTK_CLK_MAX - 2;
}
 
-   for (i = 0; i < npwms + 2 && pc->soc->has_clks; i++) {
-   pc->clks[i] = devm_clk_get(>dev, mtk_pwm_clk_name[i]);
+   for (i = 0; i < npwms + 2 ; i++) {
+   pc->clks[i] = devm_clk_get(>dev,
+ mtk_pwm_clk_name[i]);
if (IS_ERR(pc->clks[i])) {
dev_err(>dev, "clock: %s fail: %ld\n",
-   mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
+   mtk_pwm_clk_name[i],
+   PTR_ERR(pc->clks[i]));
return PTR_ERR(pc->clks[i]);
}
}
@@ -297,25 +292,21 @@ static int mtk_pwm_remove(struct platform_device *pdev)
 static const struct mtk_pwm_platform_data mt2712_pwm_data = {
.fallback_npwms = 8,
.pwm45_fixup = false,
-   .has_clks = true,
 };
 
 static const struct mtk_pwm_platform_data mt7622_pwm_data = {
.fallback_npwms = 6,
.pwm45_fixup = false,
-   .has_clks = true,
 };
 
 static const struct mtk_pwm_platform_data mt7623_pwm_data = {
.fallback_npwms = 5,
.pwm45_fixup = true,
-   .has_clks = true,
 };
 
 static const struct mtk_pwm_platform_data mt7628_pwm_data = {
.fallback_npwms = 4,
.pwm45_fixup = true,
-   .has_clks = false,
 };
 
 static const struct of_device_id mtk_pwm_of_match[] = {
-- 
2.17.1



Re: [PATCH v4 3/3] vfio/pci: make use of irq_update_devid and optimize irq ops

2019-08-28 Thread Ben Luo



在 2019/8/29 上午1:23, Alex Williamson 写道:

On Wed, 28 Aug 2019 18:08:02 +0800
Ben Luo  wrote:


在 2019/8/28 上午4:33, Alex Williamson 写道:

On Thu, 22 Aug 2019 23:34:43 +0800
Ben Luo  wrote:
  

When userspace (e.g. qemu) triggers a switch between KVM
irqfd and userspace eventfd, only dev_id of irq action
(i.e. the "trigger" in this patch's context) will be
changed, but a free-then-request-irq action is taken in
current code. And, irq affinity setting in VM will also
trigger a free-then-request-irq action, which actually
changes nothing, but only fires a producer re-registration
to update irte in case that posted-interrupt is in use.

This patch makes use of irq_update_devid() and optimize
both cases above, which reduces the risk of losing interrupt
and also cuts some overhead.

Signed-off-by: Ben Luo 
---
   drivers/vfio/pci/vfio_pci_intrs.c | 112 
+-
   1 file changed, 74 insertions(+), 38 deletions(-)

diff --git a/drivers/vfio/pci/vfio_pci_intrs.c 
b/drivers/vfio/pci/vfio_pci_intrs.c
index 3fa3f72..60d3023 100644
--- a/drivers/vfio/pci/vfio_pci_intrs.c
+++ b/drivers/vfio/pci/vfio_pci_intrs.c
@@ -284,70 +284,106 @@ static int vfio_msi_enable(struct vfio_pci_device *vdev, 
int nvec, bool msix)
   static int vfio_msi_set_vector_signal(struct vfio_pci_device *vdev,
  int vector, int fd, bool msix)
   {
+   struct eventfd_ctx *trigger = NULL;
struct pci_dev *pdev = vdev->pdev;
-   struct eventfd_ctx *trigger;
int irq, ret;
   
   	if (vector < 0 || vector >= vdev->num_ctx)

return -EINVAL;
   
+	if (fd >= 0) {

+   trigger = eventfd_ctx_fdget(fd);
+   if (IS_ERR(trigger))
+   return PTR_ERR(trigger);
+   }

I think this is a user visible change.  Previously the vector is
disabled first, then if an error occurs re-enabling, we return an errno
with the vector disabled.  Here we instead fail the ioctl and leave the
state as if it had never happened.  For instance with QEMU, if they
were trying to change from KVM to userspace signaling and entered this
condition, previously the interrupt would signal to neither eventfd, now
it would continue signaling to KVM. If QEMU's intent was to emulate
vector masking, this could induce unhandled interrupts in the guest.
Maybe we need a tear-down on fault here to maintain that behavior, or
do you see some justification for the change?

Thanks for your comments, this reminds me to think more about the
effects to users.

After I reviewed the related code in Qemu and VFIO, I think maybe there
is a problem in current behavior
for the signal path changing case. Qemu has neither recovery nor retry
code in case that ioctl with
'VFIO_DEVICE_SET_IRQS' command fails, so if the old signal path has been
disabled on fault of setting
up new path, the corresponding vector may be disabled forever. Following
is an example from qemu's
vfio_msix_vector_do_use():

      ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set);
      g_free(irq_set);
      if (ret) {
      error_report("vfio: failed to modify vector, %d", ret);
      }

I think the singal path before changing should be still working at this
moment and the caller should keep it
working if the changing fails, so that at least we still have the old
path instead of no path.

For masking vector case, the 'fd' should be -1, and the interrupt will
be freed as before this patch.

QEMU doesn't really have an opportunity to signal an error to the
guest, we're emulating the hardware masking of MSI and MSI-X.  The
guest is simply trying to write a mask bit in the vector, there's no
provision in the PCI spec that setting this bit can fail.  The current
behavior is that the vector is disabled on error.  We can argue whether
that's the optimal behavior, but it's the existing behavior and
changing it would require and evaluation of all existing users.


I totally agree with you that masking of MSI and MSI-X should follow 
current behavior, and my code does follow this behavior when 'fd' == -1, 
the interrupt will surely be disabled.


There is another case that 'fd' is not -1, means userspace just want to 
change the singal path, this time we do have a chance of encountering 
error on eventfd_ctx_fdget(fd). So, I think it is better to keep the old 
path working in this case.


But, as you said this may break the expectation of existing users, I 
make it tear-down on fault in next version.





+
irq = pci_irq_vector(pdev, vector);
   
+	/*

+* For KVM-VFIO case, interrupt from passthrough device will be directly
+* delivered to VM after producer and consumer connected successfully.
+* If producer and consumer are disconnected, this interrupt process
+* will fall back to remap mode, where interrupt handler uses 'trigger'
+* to find the right way to deliver the interrupt to VM. So, it is safe
+* to do 

[PATCH v6 02/11] pwm: mediatek: droping the check for of_device_get_match_data

2019-08-28 Thread Sam Shih
This patch drop the check for of_device_get_match_data.
Due to the only way call driver probe is compatible match.
The .data pointer which point to the SoC specify data is
directly set by driver, and it should not be NULL in our case.
We can safety remove the check for of_device_get_match_data.

Signed-off-by: Ryder Lee 
Signed-off-by: Sam Shih 
Acked-by: Uwe Kleine-König 
---
Used:
https://patchwork.kernel.org/patch/11096905/
Changes since v6:
Add an Acked-by tag

Changes since v4:
Follow reviewer's comments:
Move the changes of droping the check for of_device_get_match_data
returning non-NULL to this patch

---
 drivers/pwm/pwm-mediatek.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
index e214f4f57107..ebd62629e3fe 100644
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
@@ -226,7 +226,6 @@ static const struct pwm_ops mtk_pwm_ops = {
 
 static int mtk_pwm_probe(struct platform_device *pdev)
 {
-   const struct mtk_pwm_platform_data *data;
struct device_node *np = pdev->dev.of_node;
struct mtk_pwm_chip *pc;
struct resource *res;
@@ -237,10 +236,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
if (!pc)
return -ENOMEM;
 
-   data = of_device_get_match_data(>dev);
-   if (data == NULL)
-   return -EINVAL;
-   pc->soc = data;
+   pc->soc = of_device_get_match_data(>dev);
 
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pc->regs = devm_ioremap_resource(>dev, res);
-- 
2.17.1



[PATCH v6 01/11] pwm: mediatek: add a property "num-pwms"

2019-08-28 Thread Sam Shih
From: Ryder Lee 

This adds a property "num-pwms" to avoid having an endless
list of compatibles with no differences for the same driver.

Signed-off-by: Ryder Lee 
Signed-off-by: Sam Shih 
Reviewed-by: Uwe Kleine-König 
---
Changes since v6:
Add a Reviewed-by tag

Changes since v5:
Check num-pwms value is no more than MTK_CLK_MAX - 2 (MAIN + TOP)

Changes since v4:
Follow reviewer's comments:
Move the changes of droping the check for of_device_get_match_data returning 
non-NULL to next patch


---
 drivers/pwm/pwm-mediatek.c | 36 
 1 file changed, 28 insertions(+), 8 deletions(-)

diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
index eb6674ce995f..e214f4f57107 100644
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
@@ -55,7 +55,7 @@ static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
 };
 
 struct mtk_pwm_platform_data {
-   unsigned int num_pwms;
+   unsigned int fallback_npwms;
bool pwm45_fixup;
bool has_clks;
 };
@@ -227,9 +227,10 @@ static const struct pwm_ops mtk_pwm_ops = {
 static int mtk_pwm_probe(struct platform_device *pdev)
 {
const struct mtk_pwm_platform_data *data;
+   struct device_node *np = pdev->dev.of_node;
struct mtk_pwm_chip *pc;
struct resource *res;
-   unsigned int i;
+   unsigned int i, npwms;
int ret;
 
pc = devm_kzalloc(>dev, sizeof(*pc), GFP_KERNEL);
@@ -246,7 +247,26 @@ static int mtk_pwm_probe(struct platform_device *pdev)
if (IS_ERR(pc->regs))
return PTR_ERR(pc->regs);
 
-   for (i = 0; i < data->num_pwms + 2 && pc->soc->has_clks; i++) {
+   ret = of_property_read_u32(np, "num-pwms", );
+   if (ret < 0) {
+   /* It's deprecated, we should specify num_pwms via DT now. */
+   if (pc->soc->fallback_npwms) {
+   npwms = pc->soc->fallback_npwms;
+   dev_warn(>dev, "DT is outdated, please update 
it\n");
+   } else {
+   dev_err(>dev, "failed to get number of PWMs\n");
+   return ret;
+   }
+   }
+
+   /* MAIN + TOP + NPWM < MTK_CLK_MAX */
+   if ((npwms + 2) > MTK_CLK_MAX) {
+   dev_warn(>dev, "number of PWMs is larger than %d\n",
+MTK_CLK_MAX - 2);
+   npwms = MTK_CLK_MAX - 2;
+   }
+
+   for (i = 0; i < npwms + 2 && pc->soc->has_clks; i++) {
pc->clks[i] = devm_clk_get(>dev, mtk_pwm_clk_name[i]);
if (IS_ERR(pc->clks[i])) {
dev_err(>dev, "clock: %s fail: %ld\n",
@@ -260,7 +280,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
pc->chip.dev = >dev;
pc->chip.ops = _pwm_ops;
pc->chip.base = -1;
-   pc->chip.npwm = data->num_pwms;
+   pc->chip.npwm = npwms;
 
ret = pwmchip_add(>chip);
if (ret < 0) {
@@ -279,25 +299,25 @@ static int mtk_pwm_remove(struct platform_device *pdev)
 }
 
 static const struct mtk_pwm_platform_data mt2712_pwm_data = {
-   .num_pwms = 8,
+   .fallback_npwms = 8,
.pwm45_fixup = false,
.has_clks = true,
 };
 
 static const struct mtk_pwm_platform_data mt7622_pwm_data = {
-   .num_pwms = 6,
+   .fallback_npwms = 6,
.pwm45_fixup = false,
.has_clks = true,
 };
 
 static const struct mtk_pwm_platform_data mt7623_pwm_data = {
-   .num_pwms = 5,
+   .fallback_npwms = 5,
.pwm45_fixup = true,
.has_clks = true,
 };
 
 static const struct mtk_pwm_platform_data mt7628_pwm_data = {
-   .num_pwms = 4,
+   .fallback_npwms = 4,
.pwm45_fixup = true,
.has_clks = false,
 };
-- 
2.17.1



[PATCH v6 0/11] Add mt7629 and fix mt7628 pwm

2019-08-28 Thread Sam Shih
Changes since v6:
  1. Due to we can use fixed-clock in DT
 We removed has_clks and fixed-clock properties 

Changes since v5:
- Follow reviewer's comments:
  1. the license stuff is a separate change
  2. split fix mt7628 pwm into a single patch
  3. to ensure to not use mtk_pwm_clk_name[10] 
 (After dynamic allocate clock array patch, 
  this is no need to check)
  4. Use clock-frequency property to replace 
 the use of has_clks

Changes since v4:
- Follow reviewer's comments (v3: pwm: mediatek: add a property "num-pwms")
  Move the changes of droping the check for of_device_get_match_data
  returning non-NULL to next patch
- Follow reviewers's comments 
  (v3: pwm: mediatek: allocate the clks array dynamically)
  1. use pc->soc->has_clks to check clocks exist or not.
  2. Add error message when probe() unable to get clks
- Fixes bug when SoC is old mips which has no complex clock tree.
if clocks not exist, use the new property from DT to apply period 
calculation; otherwise, use clk_get_rate to get clock frequency and 
apply period calculation.

Changes since v3:
- add a new property "clock-frequency" and fix mt7628 pwm
- add mt7629 pwm support

Changes since v2:
- use num-pwms instead of mediatek,num-pwms.
- rename the member from num_pwms to fallback_num_pwms to make it 
  more obvious that it doesn't represent the actually used value.
- add a dev_warn and a expressive comment to help other developers 
  to not start adding num_pwms in the compatible_data.

Changes since v1:
- add some checks for backwards compatibility.


Ryder Lee (5):
  pwm: mediatek: add a property "num-pwms"
  dt-bindings: pwm: add a property "num-pwms"
  arm64: dts: mt7622: add a property "num-pwms" for PWM
  arm: dts: mt7623: add a property "num-pwms" for PWM
  dt-bindings: pwm: update bindings for MT7629 SoC

Sam Shih (6):
  pwm: mediatek: droping the check for of_device_get_match_data
  pwm: mediatek: remove a property "has-clks"
  pwm: mediatek: allocate the clks array dynamically
  pwm: mediatek: use pwm_mediatek as common prefix
  pwm: mediatek: update license and switch to SPDX tag
  arm: dts: mediatek: add mt7629 pwm support

 .../devicetree/bindings/pwm/pwm-mediatek.txt  |   8 +-
 arch/arm/boot/dts/mt7623.dtsi |   1 +
 arch/arm64/boot/dts/mediatek/mt7622.dtsi  |   1 +
 drivers/pwm/pwm-mediatek.c| 245 +-
 arch/arm/boot/dts/mt7629.dtsi | 16 
 5 files changed, 149 insertions(+), 122 deletions(-)

-- 
2.17.1



[RFC v1 3/9] KVM: x86: Implement MSR_IA32_PEBS_ENABLE read/write emulation

2019-08-28 Thread Luwei Kang
This patch implements the MSR_IA32_PEBS_ENABLE register
read/write emulation for KVM guest. MSR_IA32_PEBS_ENABLE
register can be accessed only when PEBS is supported in KVM.

VMM need to reprogram the counter when the value of this MSR
changed because some of the counters will be created or destroyed.

Signed-off-by: Luwei Kang 
---
 arch/x86/include/asm/kvm_host.h  |  2 ++
 arch/x86/include/asm/msr-index.h |  3 +++
 arch/x86/kvm/vmx/pmu_intel.c | 42 +---
 3 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 3463326..df966c9 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -471,6 +471,8 @@ struct kvm_pmu {
u64 global_ctrl_mask;
u64 global_ovf_ctrl_mask;
u64 reserved_bits;
+   u64 pebs_enable;
+   u64 pebs_enable_mask;
u8 version;
bool pebs_pt;   /* PEBS output to Intel PT */
struct kvm_pmc gp_counters[INTEL_PMC_MAX_GENERIC];
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 3dd166a..a9e8720 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -131,6 +131,9 @@
 #define LBR_INFO_ABORT BIT_ULL(61)
 #define LBR_INFO_CYCLES0x
 
+#define MSR_IA32_PEBS_PMI_AFTER_REC(1UL << 60)
+#define MSR_IA32_PEBS_OUTPUT_PT(1UL << 61)
+#define MSR_IA32_PEBS_OUTPUT_MASK  (3UL << 61)
 #define MSR_IA32_PEBS_ENABLE   0x03f1
 #define MSR_PEBS_DATA_CFG  0x03f2
 #define MSR_IA32_DS_AREA   0x0600
diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index e1c987f..fc79cc6 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -66,6 +66,20 @@ static void global_ctrl_changed(struct kvm_pmu *pmu, u64 
data)
reprogram_counter(pmu, bit);
 }
 
+static void pebs_enable_changed(struct kvm_pmu *pmu, u64 data)
+{
+   int bit;
+   u64 mask = ((1ull << pmu->nr_arch_gp_counters) - 1) |
+   (((1ull << pmu->nr_arch_fixed_counters) - 1) <<
+   INTEL_PMC_IDX_FIXED);
+   u64 diff = (pmu->pebs_enable ^ data) & mask;
+
+   pmu->pebs_enable = data;
+
+   for_each_set_bit(bit, (unsigned long *), X86_PMC_IDX_MAX)
+   reprogram_counter(pmu, bit);
+}
+
 static unsigned intel_find_arch_event(struct kvm_pmu *pmu,
  u8 event_select,
  u8 unit_mask)
@@ -155,6 +169,9 @@ static bool intel_is_valid_msr(struct kvm_vcpu *vcpu, u32 
msr)
case MSR_CORE_PERF_GLOBAL_OVF_CTRL:
ret = pmu->version > 1;
break;
+   case MSR_IA32_PEBS_ENABLE:
+   ret = pmu->pebs_pt;
+   break;
default:
ret = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0) ||
get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0) ||
@@ -183,6 +200,9 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, u32 
msr, u64 *data)
case MSR_CORE_PERF_GLOBAL_OVF_CTRL:
*data = pmu->global_ovf_ctrl;
return 0;
+   case MSR_IA32_PEBS_ENABLE:
+   *data = pmu->pebs_enable;
+   return 0;
default:
if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0))) {
u64 val = pmc_read_counter(pmc);
@@ -240,6 +260,16 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct 
msr_data *msr_info)
return 0;
}
break;
+   case MSR_IA32_PEBS_ENABLE:
+   if (pmu->pebs_enable == data)
+   return 0;
+   if (!(data & pmu->pebs_enable_mask) &&
+(data & MSR_IA32_PEBS_OUTPUT_MASK) ==
+   MSR_IA32_PEBS_OUTPUT_PT) {
+   pebs_enable_changed(pmu, data);
+   return 0;
+   }
+   break;
default:
if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0))) {
if (msr_info->host_initiated)
@@ -270,6 +300,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
struct kvm_cpuid_entry2 *entry;
union cpuid10_eax eax;
union cpuid10_edx edx;
+   u64 cnts_mask;
 
pmu->nr_arch_gp_counters = 0;
pmu->nr_arch_fixed_counters = 0;
@@ -304,9 +335,10 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
((u64)1 << edx.split.bit_width_fixed) - 1;
}
 
-   pmu->global_ctrl = ((1ull << pmu->nr_arch_gp_counters) - 1) |
+   cnts_mask = ((1ull << pmu->nr_arch_gp_counters) - 1) |
(((1ull << pmu->nr_arch_fixed_counters) - 1) << 
INTEL_PMC_IDX_FIXED);
-   pmu->global_ctrl_mask = ~pmu->global_ctrl;
+
+

[RFC v1 4/9] KVM: x86: Implement counter reload MSRs read/write emulation

2019-08-28 Thread Luwei Kang
This patch implements the counter reload register
MSR_RELOAD_PMCx/FIXED_CTRx read/write emulation. These registers
can be accessed only when PEBS is supported in KVM.

VMM need to reprogram the counters to make the host PMU framework
load the value to real hardware after configuration has been changed.

Signed-off-by: Luwei Kang 
---
 arch/x86/include/asm/kvm_host.h  |  1 +
 arch/x86/include/asm/msr-index.h |  3 +++
 arch/x86/kvm/vmx/pmu_intel.c | 22 +-
 3 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index df966c9..9b930b5 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -454,6 +454,7 @@ struct kvm_pmc {
enum pmc_type type;
u8 idx;
u64 counter;
+   u64 reload_cnt;
u64 eventsel;
struct perf_event *perf_event;
struct kvm_vcpu *vcpu;
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index a9e8720..6321acb 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -141,6 +141,9 @@
 #define MSR_IA32_PERF_CAPABILITIES 0x0345
 #define MSR_PEBS_LD_LAT_THRESHOLD  0x03f6
 
+#define MSR_IA32_RELOAD_PMC0   0x14c1
+#define MSR_IA32_RELOAD_FIXED_CTR0 0x1309
+
 #define MSR_IA32_RTIT_CTL  0x0570
 #define RTIT_CTL_TRACEEN   BIT(0)
 #define RTIT_CTL_CYCLEACC  BIT(1)
diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index fc79cc6..ebd3efc 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -175,7 +175,9 @@ static bool intel_is_valid_msr(struct kvm_vcpu *vcpu, u32 
msr)
default:
ret = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0) ||
get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0) ||
-   get_fixed_pmc(pmu, msr, MSR_CORE_PERF_FIXED_CTR0);
+   get_fixed_pmc(pmu, msr, MSR_CORE_PERF_FIXED_CTR0) ||
+   get_gp_pmc(pmu, msr, MSR_IA32_RELOAD_PMC0) ||
+   get_fixed_pmc(pmu, msr, MSR_IA32_RELOAD_FIXED_CTR0);
break;
}
 
@@ -216,6 +218,11 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, u32 
msr, u64 *data)
} else if ((pmc = get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0))) {
*data = pmc->eventsel;
return 0;
+   } else if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_RELOAD_PMC0)) ||
+  (pmc = get_fixed_pmc(pmu, msr,
+   MSR_IA32_RELOAD_FIXED_CTR0))) {
+   *data = pmc->reload_cnt;
+   return 0;
}
}
 
@@ -288,6 +295,19 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct 
msr_data *msr_info)
reprogram_gp_counter(pmc, data);
return 0;
}
+   } else if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_RELOAD_PMC0)) ||
+  (pmc = get_fixed_pmc(pmu, msr,
+   MSR_IA32_RELOAD_FIXED_CTR0))) {
+   if (data == pmc->reload_cnt)
+   return 0;
+   if (!(data & ~pmc_bitmask(pmc))) {
+   int pmc_idx = pmc_is_fixed(pmc) ?
+   pmc->idx + INTEL_PMC_IDX_FIXED :
+   pmc->idx;
+   pmc->reload_cnt = data;
+   reprogram_counter(pmu, pmc_idx);
+   return 0;
+   }
}
}
 
-- 
1.8.3.1



[RFC v1 9/9] KVM: x86: Expose PEBS feature to guest

2019-08-28 Thread Luwei Kang
Expose PEBS feature to guest by IA32_MISC_ENABLE[bit12].
IA32_MISC_ENABLE[bit12] is Processor Event Based Sampling (PEBS)
Unavailable (RO) flag:
1 = PEBS is not supported; 0 = PEBS is supported.

Signed-off-by: Luwei Kang 
---
 arch/x86/include/asm/kvm_host.h |  1 +
 arch/x86/kvm/svm.c  |  6 ++
 arch/x86/kvm/vmx/vmx.c  |  1 +
 arch/x86/kvm/x86.c  | 22 +-
 4 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 94af338..f6a5630 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1130,6 +1130,7 @@ struct kvm_x86_ops {
bool (*xsaves_supported)(void);
bool (*umip_emulated)(void);
bool (*pt_supported)(void);
+   bool (*pebs_supported)(void);
bool (*pdcm_supported)(void);
 
int (*check_nested_events)(struct kvm_vcpu *vcpu, bool external_intr);
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 8ae6716..2b271fc 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -6005,6 +6005,11 @@ static bool svm_pt_supported(void)
return false;
 }
 
+static bool svm_pebs_supported(void)
+{
+   return false;
+}
+
 static bool svm_pdcm_supported(void)
 {
return false;
@@ -7298,6 +7303,7 @@ static bool svm_need_emulation_on_page_fault(struct 
kvm_vcpu *vcpu)
.xsaves_supported = svm_xsaves_supported,
.umip_emulated = svm_umip_emulated,
.pt_supported = svm_pt_supported,
+   .pebs_supported = svm_pebs_supported,
.pdcm_supported = svm_pdcm_supported,
 
.set_supported_cpuid = svm_set_supported_cpuid,
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 71e3d42..d85f19b 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -7782,6 +7782,7 @@ static __exit void hardware_unsetup(void)
.xsaves_supported = vmx_xsaves_supported,
.umip_emulated = vmx_umip_emulated,
.pt_supported = vmx_pt_supported,
+   .pebs_supported = vmx_pebs_supported,
.pdcm_supported = vmx_pdcm_supported,
 
.request_immediate_exit = vmx_request_immediate_exit,
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 290c3c3..8ad501d 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2483,6 +2483,7 @@ static void record_steal_time(struct kvm_vcpu *vcpu)
 int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 {
bool pr = false;
+   bool update_cpuid = false;
u32 msr = msr_info->index;
u64 data = msr_info->data;
 
@@ -2563,11 +2564,17 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct 
msr_data *msr_info)
((vcpu->arch.ia32_misc_enable_msr ^ data) & 
MSR_IA32_MISC_ENABLE_MWAIT)) {
if (!guest_cpuid_has(vcpu, X86_FEATURE_XMM3))
return 1;
-   vcpu->arch.ia32_misc_enable_msr = data;
-   kvm_update_cpuid(vcpu);
-   } else {
-   vcpu->arch.ia32_misc_enable_msr = data;
+   update_cpuid = true;
}
+
+   if (kvm_x86_ops->pebs_supported())
+   data &=  ~MSR_IA32_MISC_ENABLE_PEBS;
+   else
+   data |= MSR_IA32_MISC_ENABLE_PEBS;
+
+   vcpu->arch.ia32_misc_enable_msr = data;
+   if (update_cpuid)
+   kvm_update_cpuid(vcpu);
break;
case MSR_IA32_SMBASE:
if (!msr_info->host_initiated)
@@ -2875,7 +2882,12 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct 
msr_data *msr_info)
msr_info->data = (u64)vcpu->arch.ia32_tsc_adjust_msr;
break;
case MSR_IA32_MISC_ENABLE:
-   msr_info->data = vcpu->arch.ia32_misc_enable_msr;
+   if (kvm_x86_ops->pebs_supported())
+   msr_info->data = (vcpu->arch.ia32_misc_enable_msr &
+   ~MSR_IA32_MISC_ENABLE_PEBS);
+   else
+   msr_info->data = (vcpu->arch.ia32_misc_enable_msr |
+   MSR_IA32_MISC_ENABLE_PEBS);
break;
case MSR_IA32_SMBASE:
if (!msr_info->host_initiated)
-- 
1.8.3.1



[RFC v1 5/9] KVM: x86: Allocate performance counter for PEBS event

2019-08-28 Thread Luwei Kang
This patch add a new parameter "pebs" that to make the host
PMU framework allocate performance counter for guest PEBS event.

Signed-off-by: Luwei Kang 
---
 arch/x86/kvm/pmu.c   | 23 +++
 arch/x86/kvm/pmu.h   |  5 +++--
 arch/x86/kvm/pmu_amd.c   |  2 +-
 arch/x86/kvm/vmx/pmu_intel.c |  7 +--
 4 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 46875bb..6bdc282 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -99,7 +99,7 @@ static void kvm_perf_overflow_intr(struct perf_event 
*perf_event,
 static void pmc_reprogram_counter(struct kvm_pmc *pmc, u32 type,
  unsigned config, bool exclude_user,
  bool exclude_kernel, bool intr,
- bool in_tx, bool in_tx_cp)
+ bool in_tx, bool in_tx_cp, bool pebs)
 {
struct perf_event *event;
struct perf_event_attr attr = {
@@ -111,9 +111,12 @@ static void pmc_reprogram_counter(struct kvm_pmc *pmc, u32 
type,
.exclude_user = exclude_user,
.exclude_kernel = exclude_kernel,
.config = config,
+   .precise_ip = pebs ? 1 : 0,
+   .aux_output = pebs ? 1 : 0,
};
 
-   attr.sample_period = (-pmc->counter) & pmc_bitmask(pmc);
+   attr.sample_period = pebs ? (-pmc->reload_cnt) & pmc_bitmask(pmc) :
+   (-pmc->counter) & pmc_bitmask(pmc);
 
if (in_tx)
attr.config |= HSW_IN_TX;
@@ -140,7 +143,7 @@ static void pmc_reprogram_counter(struct kvm_pmc *pmc, u32 
type,
clear_bit(pmc->idx, (unsigned long*)_to_pmu(pmc)->reprogram_pmi);
 }
 
-void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel)
+void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel, bool pebs)
 {
unsigned config, type = PERF_TYPE_RAW;
u8 event_select, unit_mask;
@@ -198,11 +201,12 @@ void reprogram_gp_counter(struct kvm_pmc *pmc, u64 
eventsel)
  !(eventsel & ARCH_PERFMON_EVENTSEL_OS),
  eventsel & ARCH_PERFMON_EVENTSEL_INT,
  (eventsel & HSW_IN_TX),
- (eventsel & HSW_IN_TX_CHECKPOINTED));
+ (eventsel & HSW_IN_TX_CHECKPOINTED),
+ pebs);
 }
 EXPORT_SYMBOL_GPL(reprogram_gp_counter);
 
-void reprogram_fixed_counter(struct kvm_pmc *pmc, u8 ctrl, int idx)
+void reprogram_fixed_counter(struct kvm_pmc *pmc, u8 ctrl, int idx, bool pebs)
 {
unsigned en_field = ctrl & 0x3;
bool pmi = ctrl & 0x8;
@@ -228,7 +232,8 @@ void reprogram_fixed_counter(struct kvm_pmc *pmc, u8 ctrl, 
int idx)
  kvm_x86_ops->pmu_ops->find_fixed_event(idx),
  !(en_field & 0x2), /* exclude user */
  !(en_field & 0x1), /* exclude kernel */
- pmi, false, false);
+ pmi, false, false,
+ pebs);
 }
 EXPORT_SYMBOL_GPL(reprogram_fixed_counter);
 
@@ -240,12 +245,14 @@ void reprogram_counter(struct kvm_pmu *pmu, int pmc_idx)
return;
 
if (pmc_is_gp(pmc))
-   reprogram_gp_counter(pmc, pmc->eventsel);
+   reprogram_gp_counter(pmc, pmc->eventsel,
+   (pmu->pebs_enable & (1ul << pmc_idx)));
else {
int idx = pmc_idx - INTEL_PMC_IDX_FIXED;
u8 ctrl = fixed_ctrl_field(pmu->fixed_ctr_ctrl, idx);
 
-   reprogram_fixed_counter(pmc, ctrl, idx);
+   reprogram_fixed_counter(pmc, ctrl, idx,
+   (pmu->pebs_enable & (1ul << pmc_idx)));
}
 }
 EXPORT_SYMBOL_GPL(reprogram_counter);
diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h
index c62a1ff..0c59a15 100644
--- a/arch/x86/kvm/pmu.h
+++ b/arch/x86/kvm/pmu.h
@@ -102,8 +102,9 @@ static inline struct kvm_pmc *get_fixed_pmc(struct kvm_pmu 
*pmu, u32 msr,
return NULL;
 }
 
-void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel);
-void reprogram_fixed_counter(struct kvm_pmc *pmc, u8 ctrl, int fixed_idx);
+void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel, bool pebs);
+void reprogram_fixed_counter(struct kvm_pmc *pmc, u8 ctrl, int fixed_idx,
+   bool pebs);
 void reprogram_counter(struct kvm_pmu *pmu, int pmc_idx);
 
 void kvm_pmu_deliver_pmi(struct kvm_vcpu *vcpu);
diff --git a/arch/x86/kvm/pmu_amd.c b/arch/x86/kvm/pmu_amd.c
index c838838..7b3e307 100644
--- a/arch/x86/kvm/pmu_amd.c
+++ b/arch/x86/kvm/pmu_amd.c
@@ -248,7 +248,7 @@ static int amd_pmu_set_msr(struct kvm_vcpu *vcpu, struct 
msr_data *msr_info)
if (data == pmc->eventsel)
return 0;
if (!(data & 

[RFC v1 8/9] KVM: X86: MSR_IA32_PERF_CAPABILITIES MSR emulation

2019-08-28 Thread Luwei Kang
Expose some bits of definition which relate with enable
PEBS to KVM guest especially PEBS via PT feature.

Signed-off-by: Luwei Kang 
---
 arch/x86/include/asm/kvm_host.h  |  1 +
 arch/x86/include/asm/msr-index.h |  3 +++
 arch/x86/kvm/vmx/vmx.c   | 14 ++
 3 files changed, 18 insertions(+)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 2d9b0f9..94af338 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -576,6 +576,7 @@ struct kvm_vcpu_arch {
u64 ia32_xss;
u64 microcode_version;
u64 arch_capabilities;
+   u64 ia32_perf_capabilities;
 
/*
 * Paging state of the vcpu
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 6321acb..4932dec 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -137,6 +137,9 @@
 #define MSR_IA32_PEBS_ENABLE   0x03f1
 #define MSR_PEBS_DATA_CFG  0x03f2
 #define MSR_IA32_DS_AREA   0x0600
+#define MSR_IA32_PERF_CAP_PEBS_TRAP(1UL << 6)
+#define MSR_IA32_PERF_CAP_PEBS_ARCH_REG(1UL << 7)
+#define MSR_IA32_PERF_CAP_PEBS_REC_FMT (0xfUL << 8)
 #define MSR_IA32_PERF_CAP_PEBS_OUTPUT_PT   (1UL << 16)
 #define MSR_IA32_PERF_CAPABILITIES 0x0345
 #define MSR_PEBS_LD_LAT_THRESHOLD  0x03f6
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index dbff8f0..71e3d42 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -1737,6 +1737,16 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct 
msr_data *msr_info)
return 1;
msr_info->data = vcpu->arch.ia32_xss;
break;
+   case MSR_IA32_PERF_CAPABILITIES:
+   if (!vmx_pdcm_supported() || !vmx_pebs_supported())
+   return 1;
+   rdmsrl(MSR_IA32_PERF_CAPABILITIES, msr_info->data);
+   msr_info->data = msr_info->data &
+   (MSR_IA32_PERF_CAP_PEBS_TRAP |
+MSR_IA32_PERF_CAP_PEBS_ARCH_REG |
+MSR_IA32_PERF_CAP_PEBS_REC_FMT |
+MSR_IA32_PERF_CAP_PEBS_OUTPUT_PT);
+   break;
case MSR_IA32_RTIT_CTL:
if (pt_mode != PT_MODE_HOST_GUEST)
return 1;
@@ -1981,6 +1991,10 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct 
msr_data *msr_info)
else
clear_atomic_switch_msr(vmx, MSR_IA32_XSS);
break;
+   case MSR_IA32_PERF_CAPABILITIES:
+   if (!vmx_pdcm_supported() || !vmx_pebs_supported())
+   return 1;
+   break;
case MSR_IA32_RTIT_CTL:
if ((pt_mode != PT_MODE_HOST_GUEST) ||
vmx_rtit_ctl_check(vcpu, data) ||
-- 
1.8.3.1



[RFC v1 6/9] KVM: x86: Add shadow value of PEBS status

2019-08-28 Thread Luwei Kang
The performance counter used by guest perspective may different
with the counter allocated from real hardware (e.g. Guest driver
get counter 0 for PEBS but the host PMU driver may alloc other
counters for this event).

Introduce a new parameter for the mapping of PEBS enable status from
guest to real hardware. Update the shadow value of PEBS before
VM-entry when PT is enabled in guest.

Signed-off-by: Luwei Kang 
---
 arch/x86/include/asm/kvm_host.h |  1 +
 arch/x86/kvm/pmu.c  | 34 ++
 arch/x86/kvm/pmu.h  |  1 +
 arch/x86/kvm/vmx/vmx.c  |  8 +++-
 4 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 9b930b5..07d3b21 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -473,6 +473,7 @@ struct kvm_pmu {
u64 global_ovf_ctrl_mask;
u64 reserved_bits;
u64 pebs_enable;
+   u64 pebs_enable_shadow;
u64 pebs_enable_mask;
u8 version;
bool pebs_pt;   /* PEBS output to Intel PT */
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 6bdc282..89d3e4c 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -257,6 +257,40 @@ void reprogram_counter(struct kvm_pmu *pmu, int pmc_idx)
 }
 EXPORT_SYMBOL_GPL(reprogram_counter);
 
+void kvm_pmu_pebs_shadow(struct kvm_vcpu *vcpu)
+{
+   struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
+   struct perf_event *event;
+   int i;
+
+   if (!pmu->pebs_pt)
+   return;
+
+   pmu->pebs_enable_shadow = MSR_IA32_PEBS_OUTPUT_PT;
+
+   for (i = 0; i < pmu->nr_arch_gp_counters; i++) {
+   if (!test_bit(i, (unsigned long *)>pebs_enable))
+   continue;
+
+   event = pmu->gp_counters[i].perf_event;
+   if (event && (event->hw.idx != -1))
+   set_bit(event->hw.idx,
+   (unsigned long *)>pebs_enable_shadow);
+   }
+
+   for (i = 0; i < pmu->nr_arch_fixed_counters; i++) {
+   if (!test_bit(i + INTEL_PMC_IDX_FIXED,
+   (unsigned long *)>pebs_enable))
+   continue;
+
+   event = pmu->fixed_counters[i].perf_event;
+   if (event && (event->hw.idx != -1))
+   set_bit(event->hw.idx,
+   (unsigned long *)>pebs_enable_shadow);
+   }
+}
+EXPORT_SYMBOL_GPL(kvm_pmu_pebs_shadow);
+
 void kvm_pmu_handle_event(struct kvm_vcpu *vcpu)
 {
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h
index 0c59a15..81c35c9 100644
--- a/arch/x86/kvm/pmu.h
+++ b/arch/x86/kvm/pmu.h
@@ -119,6 +119,7 @@ void reprogram_fixed_counter(struct kvm_pmc *pmc, u8 ctrl, 
int fixed_idx,
 void kvm_pmu_init(struct kvm_vcpu *vcpu);
 void kvm_pmu_destroy(struct kvm_vcpu *vcpu);
 int kvm_vm_ioctl_set_pmu_event_filter(struct kvm *kvm, void __user *argp);
+void kvm_pmu_pebs_shadow(struct kvm_vcpu *vcpu);
 
 bool is_vmware_backdoor_pmc(u32 pmc_idx);
 
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index c030c96..4090c08 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -1019,6 +1019,7 @@ static void pt_guest_enter(struct vcpu_vmx *vmx)
wrmsrl(MSR_IA32_RTIT_CTL, 0);
pt_save_msr(>pt_desc.host, vmx->pt_desc.addr_range);
pt_load_msr(>pt_desc.guest, vmx->pt_desc.addr_range);
+   kvm_pmu_pebs_shadow(>vcpu);
}
 }
 
@@ -6365,12 +6366,17 @@ static void atomic_switch_perf_msrs(struct vcpu_vmx 
*vmx)
if (!msrs)
return;
 
-   for (i = 0; i < nr_msrs; i++)
+   for (i = 0; i < nr_msrs; i++) {
+   if (msrs[i].msr == MSR_IA32_PEBS_ENABLE)
+   msrs[i].guest =
+   vcpu_to_pmu(>vcpu)->pebs_enable_shadow;
+
if (msrs[i].host == msrs[i].guest)
clear_atomic_switch_msr(vmx, msrs[i].msr);
else
add_atomic_switch_msr(vmx, msrs[i].msr, msrs[i].guest,
msrs[i].host, false);
+   }
 }
 
 static void vmx_update_hv_timer(struct kvm_vcpu *vcpu)
-- 
1.8.3.1



[RFC v1 2/9] KVM: x86: PEBS via Intel PT HW feature detection

2019-08-28 Thread Luwei Kang
PEBS can be enabled in KVM guest by direct PEBS record into the Intel
Processor Trace output buffer. This patch adds a new flag to detect
if PEBS can be supported in KVM guest. It not only need HW support PEBS
output Intel PT (IA32_PERF_CAPABILITIES.PEBS_OUTPUT_PT_AVAIL[16]=1)
but also depends on:
1. PEBS feature is supported by HW (IA32_MISC_ENABLE[Bit12]=0);
2. Intel PT must be working in HOST_GUEST mode.

Signed-off-by: Luwei Kang 
---
 arch/x86/include/asm/kvm_host.h  |  1 +
 arch/x86/include/asm/msr-index.h |  3 +++
 arch/x86/kvm/vmx/capabilities.h  | 11 +++
 arch/x86/kvm/vmx/pmu_intel.c |  7 ++-
 4 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 74e88e5..3463326 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -472,6 +472,7 @@ struct kvm_pmu {
u64 global_ovf_ctrl_mask;
u64 reserved_bits;
u8 version;
+   bool pebs_pt;   /* PEBS output to Intel PT */
struct kvm_pmc gp_counters[INTEL_PMC_MAX_GENERIC];
struct kvm_pmc fixed_counters[INTEL_PMC_MAX_FIXED];
struct irq_work irq_work;
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 271d837..3dd166a 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -134,6 +134,7 @@
 #define MSR_IA32_PEBS_ENABLE   0x03f1
 #define MSR_PEBS_DATA_CFG  0x03f2
 #define MSR_IA32_DS_AREA   0x0600
+#define MSR_IA32_PERF_CAP_PEBS_OUTPUT_PT   (1UL << 16)
 #define MSR_IA32_PERF_CAPABILITIES 0x0345
 #define MSR_PEBS_LD_LAT_THRESHOLD  0x03f6
 
@@ -660,6 +661,8 @@
 #define MSR_IA32_MISC_ENABLE_FERR  (1ULL << 
MSR_IA32_MISC_ENABLE_FERR_BIT)
 #define MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX_BIT10
 #define MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX(1ULL << 
MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX_BIT)
+#define MSR_IA32_MISC_ENABLE_PEBS_BIT  12
+#define MSR_IA32_MISC_ENABLE_PEBS  (1ULL << 
MSR_IA32_MISC_ENABLE_PEBS_BIT)
 #define MSR_IA32_MISC_ENABLE_TM2_BIT   13
 #define MSR_IA32_MISC_ENABLE_TM2   (1ULL << 
MSR_IA32_MISC_ENABLE_TM2_BIT)
 #define MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE_BIT  19
diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilities.h
index d6664ee..4bcb6b4 100644
--- a/arch/x86/kvm/vmx/capabilities.h
+++ b/arch/x86/kvm/vmx/capabilities.h
@@ -342,4 +342,15 @@ static inline bool cpu_has_vmx_intel_pt(void)
(vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_RTIT_CTL);
 }
 
+static inline bool cpu_has_vmx_pebs_output_pt(void)
+{
+   u64 misc, perf_cap;
+
+   rdmsrl(MSR_IA32_MISC_ENABLE, misc);
+   rdmsrl(MSR_IA32_PERF_CAPABILITIES, perf_cap);
+
+   return (!(misc & MSR_IA32_MISC_ENABLE_PEBS) &&
+   (perf_cap & MSR_IA32_PERF_CAP_PEBS_OUTPUT_PT));
+}
+
 #endif /* __KVM_X86_VMX_CAPS_H */
diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index 01441be..e1c987f 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include "capabilities.h"
 #include "x86.h"
 #include "cpuid.h"
 #include "lapic.h"
@@ -309,10 +310,14 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
pmu->global_ovf_ctrl_mask = pmu->global_ctrl_mask
& ~(MSR_CORE_PERF_GLOBAL_OVF_CTRL_OVF_BUF |
MSR_CORE_PERF_GLOBAL_OVF_CTRL_COND_CHGD);
-   if (kvm_x86_ops->pt_supported())
+   if (kvm_x86_ops->pt_supported()) {
pmu->global_ovf_ctrl_mask &=
~MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI;
 
+   if (cpu_has_vmx_pebs_output_pt())
+   pmu->pebs_pt = true;
+   }
+
entry = kvm_find_cpuid_entry(vcpu, 7, 0);
if (entry &&
(boot_cpu_has(X86_FEATURE_HLE) || boot_cpu_has(X86_FEATURE_RTM)) &&
-- 
1.8.3.1



[RFC v1 7/9] KVM: X86: Expose PDCM cpuid to guest

2019-08-28 Thread Luwei Kang
PDCM (Perfmon and Debug Capability) indicates the processor
supports the performance and debug feature indication
MSR IA32_PERF_CAPABILITIES.

PEBS enabling in KVM guest depend on PEBS via PT, and
PEBS via PT is detected by IA32_PERF_CAPABILITIES[Bit16].

Signed-off-by: Luwei Kang 
---
 arch/x86/include/asm/kvm_host.h |  1 +
 arch/x86/kvm/cpuid.c|  3 ++-
 arch/x86/kvm/svm.c  |  6 ++
 arch/x86/kvm/vmx/capabilities.h | 10 ++
 arch/x86/kvm/vmx/vmx.c  |  1 +
 5 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 07d3b21..2d9b0f9 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1129,6 +1129,7 @@ struct kvm_x86_ops {
bool (*xsaves_supported)(void);
bool (*umip_emulated)(void);
bool (*pt_supported)(void);
+   bool (*pdcm_supported)(void);
 
int (*check_nested_events)(struct kvm_vcpu *vcpu, bool external_intr);
void (*request_immediate_exit)(struct kvm_vcpu *vcpu);
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 22c2720..d12e7af 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -430,6 +430,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_entry2 
*entry, u32 function,
unsigned f_rdtscp = kvm_x86_ops->rdtscp_supported() ? F(RDTSCP) : 0;
unsigned f_xsaves = kvm_x86_ops->xsaves_supported() ? F(XSAVES) : 0;
unsigned f_intel_pt = kvm_x86_ops->pt_supported() ? F(INTEL_PT) : 0;
+   unsigned f_pdcm = kvm_x86_ops->pdcm_supported() ? F(PDCM) : 0;
 
/* cpuid 1.edx */
const u32 kvm_cpuid_1_edx_x86_features =
@@ -458,7 +459,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_entry2 
*entry, u32 function,
F(XMM3) | F(PCLMULQDQ) | 0 /* DTES64, MONITOR */ |
0 /* DS-CPL, VMX, SMX, EST */ |
0 /* TM2 */ | F(SSSE3) | 0 /* CNXT-ID */ | 0 /* Reserved */ |
-   F(FMA) | F(CX16) | 0 /* xTPR Update, PDCM */ |
+   F(FMA) | F(CX16) | 0 /* xTPR Update */ | f_pdcm |
F(PCID) | 0 /* Reserved, DCA */ | F(XMM4_1) |
F(XMM4_2) | F(X2APIC) | F(MOVBE) | F(POPCNT) |
0 /* Reserved*/ | F(AES) | F(XSAVE) | 0 /* OSXSAVE */ | F(AVX) |
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index e036807..8ae6716 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -6005,6 +6005,11 @@ static bool svm_pt_supported(void)
return false;
 }
 
+static bool svm_pdcm_supported(void)
+{
+   return false;
+}
+
 static bool svm_has_wbinvd_exit(void)
 {
return true;
@@ -7293,6 +7298,7 @@ static bool svm_need_emulation_on_page_fault(struct 
kvm_vcpu *vcpu)
.xsaves_supported = svm_xsaves_supported,
.umip_emulated = svm_umip_emulated,
.pt_supported = svm_pt_supported,
+   .pdcm_supported = svm_pdcm_supported,
 
.set_supported_cpuid = svm_set_supported_cpuid,
 
diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilities.h
index 4bcb6b4..82ca51d 100644
--- a/arch/x86/kvm/vmx/capabilities.h
+++ b/arch/x86/kvm/vmx/capabilities.h
@@ -353,4 +353,14 @@ static inline bool cpu_has_vmx_pebs_output_pt(void)
(perf_cap & MSR_IA32_PERF_CAP_PEBS_OUTPUT_PT));
 }
 
+static inline bool vmx_pebs_supported(void)
+{
+   return (cpu_has_vmx_pebs_output_pt() && pt_mode == PT_MODE_HOST_GUEST);
+}
+
+static inline bool vmx_pdcm_supported(void)
+{
+   return boot_cpu_has(X86_FEATURE_PDCM) && vmx_pebs_supported();
+}
+
 #endif /* __KVM_X86_VMX_CAPS_H */
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 4090c08..dbff8f0 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -7768,6 +7768,7 @@ static __exit void hardware_unsetup(void)
.xsaves_supported = vmx_xsaves_supported,
.umip_emulated = vmx_umip_emulated,
.pt_supported = vmx_pt_supported,
+   .pdcm_supported = vmx_pdcm_supported,
 
.request_immediate_exit = vmx_request_immediate_exit,
 
-- 
1.8.3.1



Re: [PATCH] x86/microcode: Add an option to reload microcode even if revision is unchanged

2019-08-28 Thread Raj, Ashok
Hi Boris,

sorry i added the wrong message id in the commit log. 

https://lore.kernel.org/r/20190824085300.gb16...@zn.tnic/

On Wed, Aug 28, 2019 at 10:33:22PM -0700, Ashok Raj wrote:
> During microcode development, its often required to test different versions
> of microcode. Intel microcode loader enforces loading only if the revision is
> greater than what is currently loaded on the cpu. Overriding this behavior
> allows us to reuse the same revision during development cycles.
> This facilty also allows us to share debug microcode with development
> partners for getting feedback before microcode release.
> 
> Microcode developers should have other ways to check which
> of their internal version is actually loaded. For e.g. checking a
> temporary MSR for instance. In order to reload the same microcode do as
> shown below.
> 
>  # echo 2 > /sys/devices/system/cpu/microcode/reload
> 
>  as root.
> 
> 
> I tested this on top of the parallel ucode load patch
> 
> https://lore.kernel.org/r/1566506627-16536-2-git-send-email-mihai.cara...@oracle.com/

Please update with the following: 

https://lore.kernel.org/r/20190824085300.gb16...@zn.tnic/

Cheers,
Ashok


[RFC v1 1/9] KVM: x86: Add base address parameter for get_fixed_pmc function

2019-08-28 Thread Luwei Kang
PEBS output Inte PT introduces some new MSRs (MSR_RELOAD_FIXED_CTRx)
for fixed function counters that use for autoload the preset value
after writing out a PEBS event.

Introduce base MSRs address parameter to make this function can get
performance monitor counter structure by MSR_RELOAD_FIXED_CTRx registers.

Signed-off-by: Luwei Kang 
---
 arch/x86/kvm/pmu.h   |  5 ++---
 arch/x86/kvm/vmx/pmu_intel.c | 14 +-
 2 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h
index 58265f7..c62a1ff 100644
--- a/arch/x86/kvm/pmu.h
+++ b/arch/x86/kvm/pmu.h
@@ -93,10 +93,9 @@ static inline struct kvm_pmc *get_gp_pmc(struct kvm_pmu 
*pmu, u32 msr,
 }
 
 /* returns fixed PMC with the specified MSR */
-static inline struct kvm_pmc *get_fixed_pmc(struct kvm_pmu *pmu, u32 msr)
+static inline struct kvm_pmc *get_fixed_pmc(struct kvm_pmu *pmu, u32 msr,
+   int base)
 {
-   int base = MSR_CORE_PERF_FIXED_CTR0;
-
if (msr >= base && msr < base + pmu->nr_arch_fixed_counters)
return >fixed_counters[msr - base];
 
diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index 4dea0e0..01441be 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -41,7 +41,8 @@ static void reprogram_fixed_counters(struct kvm_pmu *pmu, u64 
data)
u8 old_ctrl = fixed_ctrl_field(pmu->fixed_ctr_ctrl, i);
struct kvm_pmc *pmc;
 
-   pmc = get_fixed_pmc(pmu, MSR_CORE_PERF_FIXED_CTR0 + i);
+   pmc = get_fixed_pmc(pmu, MSR_CORE_PERF_FIXED_CTR0 + i,
+   MSR_CORE_PERF_FIXED_CTR0);
 
if (old_ctrl == new_ctrl)
continue;
@@ -106,7 +107,8 @@ static struct kvm_pmc *intel_pmc_idx_to_pmc(struct kvm_pmu 
*pmu, int pmc_idx)
else {
u32 idx = pmc_idx - INTEL_PMC_IDX_FIXED;
 
-   return get_fixed_pmc(pmu, idx + MSR_CORE_PERF_FIXED_CTR0);
+   return get_fixed_pmc(pmu, idx + MSR_CORE_PERF_FIXED_CTR0,
+   MSR_CORE_PERF_FIXED_CTR0);
}
 }
 
@@ -155,7 +157,7 @@ static bool intel_is_valid_msr(struct kvm_vcpu *vcpu, u32 
msr)
default:
ret = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0) ||
get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0) ||
-   get_fixed_pmc(pmu, msr);
+   get_fixed_pmc(pmu, msr, MSR_CORE_PERF_FIXED_CTR0);
break;
}
 
@@ -185,7 +187,8 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, u32 
msr, u64 *data)
u64 val = pmc_read_counter(pmc);
*data = val & pmu->counter_bitmask[KVM_PMC_GP];
return 0;
-   } else if ((pmc = get_fixed_pmc(pmu, msr))) {
+   } else if ((pmc = get_fixed_pmc(pmu, msr,
+   MSR_CORE_PERF_FIXED_CTR0))) {
u64 val = pmc_read_counter(pmc);
*data = val & pmu->counter_bitmask[KVM_PMC_FIXED];
return 0;
@@ -243,7 +246,8 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct 
msr_data *msr_info)
else
pmc->counter = (s32)data;
return 0;
-   } else if ((pmc = get_fixed_pmc(pmu, msr))) {
+   } else if ((pmc = get_fixed_pmc(pmu, msr,
+   MSR_CORE_PERF_FIXED_CTR0))) {
pmc->counter = data;
return 0;
} else if ((pmc = get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0))) {
-- 
1.8.3.1



[RFC v1 0/9] PEBS enabling in KVM guest

2019-08-28 Thread Luwei Kang
Intel new hardware introduces some Precise Event-Based Sampling (PEBS)
extensions that output the PEBS record to Intel PT stream instead of
DS area. The PEBS record will be packaged in a specific format when
outputing to Intel PT.

This patch set will enable PEBS functionality in KVM Guest by PEBS
output to Intel PT. The native driver as [1] (still under review).

[1] https://www.spinics.net/lists/kernel/msg3215354.html

Luwei Kang (9):
  KVM: x86: Add base address parameter for get_fixed_pmc function
  KVM: x86: PEBS via Intel PT HW feature detection
  KVM: x86: Implement MSR_IA32_PEBS_ENABLE read/write emulation
  KVM: x86: Implement counter reload MSRs read/write emulation
  KVM: x86: Allocate performance counter for PEBS event
  KVM: x86: Add shadow value of PEBS status
  KVM: X86: Expose PDCM cpuid to guest
  KVM: X86: MSR_IA32_PERF_CAPABILITIES MSR emulation
  KVM: x86: Expose PEBS feature to guest

 arch/x86/include/asm/kvm_host.h  |  8 
 arch/x86/include/asm/msr-index.h | 12 ++
 arch/x86/kvm/cpuid.c |  3 +-
 arch/x86/kvm/pmu.c   | 57 ++
 arch/x86/kvm/pmu.h   | 11 ++---
 arch/x86/kvm/pmu_amd.c   |  2 +-
 arch/x86/kvm/svm.c   | 12 ++
 arch/x86/kvm/vmx/capabilities.h  | 21 ++
 arch/x86/kvm/vmx/pmu_intel.c | 88 +++-
 arch/x86/kvm/vmx/vmx.c   | 24 ++-
 arch/x86/kvm/x86.c   | 22 +++---
 11 files changed, 229 insertions(+), 31 deletions(-)

-- 
1.8.3.1



[PATCH] adfs: obj.file_id is uninitialized if __adfs_dir_get() returns error code

2019-08-28 Thread Yizhuo
Inside function adfs_dir_find_entry(), obj.file_id could be uninitialized
if __adfs_dir_get() returns error code. However, the return check cannot
promise the initialization of obj.file_id, which is used in the if
statement. This is potentially unsafe.

Signed-off-by: Yizhuo 
---
 fs/adfs/dir_f.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/adfs/dir_f.c b/fs/adfs/dir_f.c
index 0fbfd0b04ae0..d7fc47598e78 100644
--- a/fs/adfs/dir_f.c
+++ b/fs/adfs/dir_f.c
@@ -335,7 +335,7 @@ adfs_dir_find_entry(struct adfs_dir *dir, unsigned long 
object_id)
ret = -ENOENT;
 
for (pos = 5; pos < ADFS_NUM_DIR_ENTRIES * 26 + 5; pos += 26) {
-   struct object_info obj;
+   struct object_info obj = {};
 
if (!__adfs_dir_get(dir, pos, ))
break;
-- 
2.17.1



Re: [PATCH v5 09/10] rtc: mt6397: fix alarm register overwrite

2019-08-28 Thread Hsin-hsiung Wang
Hi Matthias,

On Fri, 2019-08-23 at 17:35 +0200, Matthias Brugger wrote:
> 
> On 23/08/2019 05:45, Hsin-Hsiung Wang wrote:
> > From: Ran Bi 
> > 
> > Alarm registers high byte was reserved for other functions.
> > This add mask in alarm registers operation functions.
> > This also fix error condition in interrupt handler.
> > 
> > Fixes: fc2979118f3f ("rtc: mediatek: Add MT6397 RTC driver")
> > 
> > Acked-by: Alexandre Belloni 
> > Signed-off-by: Ran Bi 
> 
> Misses your Signed-off-by.
> 

I will add it in the next patch, thanks.

> Regards,
> Matthias
> 
> > ---
> >  drivers/rtc/rtc-mt6397.c | 47 
> > +--
> >  1 file changed, 33 insertions(+), 14 deletions(-)
> > 
> > diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c
> > index b46ed4d..828def7 100644
> > --- a/drivers/rtc/rtc-mt6397.c
> > +++ b/drivers/rtc/rtc-mt6397.c
> > @@ -47,6 +47,14 @@
> >  
> >  #define RTC_AL_SEC 0x0018
> >  
> > +#define RTC_AL_SEC_MASK0x003f
> > +#define RTC_AL_MIN_MASK0x003f
> > +#define RTC_AL_HOU_MASK0x001f
> > +#define RTC_AL_DOM_MASK0x001f
> > +#define RTC_AL_DOW_MASK0x0007
> > +#define RTC_AL_MTH_MASK0x000f
> > +#define RTC_AL_YEA_MASK0x007f
> > +
> >  #define RTC_PDN2   0x002e
> >  #define RTC_PDN2_PWRON_ALARM   BIT(4)
> >  
> > @@ -103,7 +111,7 @@ static irqreturn_t mtk_rtc_irq_handler_thread(int irq, 
> > void *data)
> > irqen = irqsta & ~RTC_IRQ_EN_AL;
> > mutex_lock(>lock);
> > if (regmap_write(rtc->regmap, rtc->addr_base + RTC_IRQ_EN,
> > -irqen) < 0)
> > +irqen) == 0)
> > mtk_rtc_write_trigger(rtc);
> > mutex_unlock(>lock);
> >  
> > @@ -225,12 +233,12 @@ static int mtk_rtc_read_alarm(struct device *dev, 
> > struct rtc_wkalrm *alm)
> > alm->pending = !!(pdn2 & RTC_PDN2_PWRON_ALARM);
> > mutex_unlock(>lock);
> >  
> > -   tm->tm_sec = data[RTC_OFFSET_SEC];
> > -   tm->tm_min = data[RTC_OFFSET_MIN];
> > -   tm->tm_hour = data[RTC_OFFSET_HOUR];
> > -   tm->tm_mday = data[RTC_OFFSET_DOM];
> > -   tm->tm_mon = data[RTC_OFFSET_MTH];
> > -   tm->tm_year = data[RTC_OFFSET_YEAR];
> > +   tm->tm_sec = data[RTC_OFFSET_SEC] & RTC_AL_SEC_MASK;
> > +   tm->tm_min = data[RTC_OFFSET_MIN] & RTC_AL_MIN_MASK;
> > +   tm->tm_hour = data[RTC_OFFSET_HOUR] & RTC_AL_HOU_MASK;
> > +   tm->tm_mday = data[RTC_OFFSET_DOM] & RTC_AL_DOM_MASK;
> > +   tm->tm_mon = data[RTC_OFFSET_MTH] & RTC_AL_MTH_MASK;
> > +   tm->tm_year = data[RTC_OFFSET_YEAR] & RTC_AL_YEA_MASK;
> >  
> > tm->tm_year += RTC_MIN_YEAR_OFFSET;
> > tm->tm_mon--;
> > @@ -251,14 +259,25 @@ static int mtk_rtc_set_alarm(struct device *dev, 
> > struct rtc_wkalrm *alm)
> > tm->tm_year -= RTC_MIN_YEAR_OFFSET;
> > tm->tm_mon++;
> >  
> > -   data[RTC_OFFSET_SEC] = tm->tm_sec;
> > -   data[RTC_OFFSET_MIN] = tm->tm_min;
> > -   data[RTC_OFFSET_HOUR] = tm->tm_hour;
> > -   data[RTC_OFFSET_DOM] = tm->tm_mday;
> > -   data[RTC_OFFSET_MTH] = tm->tm_mon;
> > -   data[RTC_OFFSET_YEAR] = tm->tm_year;
> > -
> > mutex_lock(>lock);
> > +   ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_AL_SEC,
> > +  data, RTC_OFFSET_COUNT);
> > +   if (ret < 0)
> > +   goto exit;
> > +
> > +   data[RTC_OFFSET_SEC] = ((data[RTC_OFFSET_SEC] & ~(RTC_AL_SEC_MASK)) |
> > +   (tm->tm_sec & RTC_AL_SEC_MASK));
> > +   data[RTC_OFFSET_MIN] = ((data[RTC_OFFSET_MIN] & ~(RTC_AL_MIN_MASK)) |
> > +   (tm->tm_min & RTC_AL_MIN_MASK));
> > +   data[RTC_OFFSET_HOUR] = ((data[RTC_OFFSET_HOUR] & ~(RTC_AL_HOU_MASK)) |
> > +   (tm->tm_hour & RTC_AL_HOU_MASK));
> > +   data[RTC_OFFSET_DOM] = ((data[RTC_OFFSET_DOM] & ~(RTC_AL_DOM_MASK)) |
> > +   (tm->tm_mday & RTC_AL_DOM_MASK));
> > +   data[RTC_OFFSET_MTH] = ((data[RTC_OFFSET_MTH] & ~(RTC_AL_MTH_MASK)) |
> > +   (tm->tm_mon & RTC_AL_MTH_MASK));
> > +   data[RTC_OFFSET_YEAR] = ((data[RTC_OFFSET_YEAR] & ~(RTC_AL_YEA_MASK)) |
> > +   (tm->tm_year & RTC_AL_YEA_MASK));
> > +
> > if (alm->enabled) {
> > ret = regmap_bulk_write(rtc->regmap,
> > rtc->addr_base + RTC_AL_SEC,
> > 
> 
> ___
> Linux-mediatek mailing list
> linux-media...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek




[PATCH] x86/microcode: Add an option to reload microcode even if revision is unchanged

2019-08-28 Thread Ashok Raj
During microcode development, its often required to test different versions
of microcode. Intel microcode loader enforces loading only if the revision is
greater than what is currently loaded on the cpu. Overriding this behavior
allows us to reuse the same revision during development cycles.
This facilty also allows us to share debug microcode with development
partners for getting feedback before microcode release.

Microcode developers should have other ways to check which
of their internal version is actually loaded. For e.g. checking a
temporary MSR for instance. In order to reload the same microcode do as
shown below.

 # echo 2 > /sys/devices/system/cpu/microcode/reload

 as root.


I tested this on top of the parallel ucode load patch

https://lore.kernel.org/r/1566506627-16536-2-git-send-email-mihai.cara...@oracle.com/

v2: [Mihai] Address comments from Boris
- Support for AMD
- add taint flag
- removed global force_ucode_load and parameterized it.

Signed-off-by: Ashok Raj 
Signed-off-by: Mihai Carabas 
cc: Boris Ostrovsky 
Cc: Mihai Carabas 
Cc: "H. Peter Anvin" 
Cc: Ingo Molnar 
Cc: Jon Grimm 
Cc: kanth.ghatr...@oracle.com
Cc: konrad.w...@oracle.com
Cc: patrick.c...@oracle.com
Cc: Thomas Gleixner 
Cc: Tom Lendacky 
Cc: x86-ml 
Cc: linux-kernel@vger.kernel.org
---
 Documentation/x86/microcode.rst   |  7 
 arch/x86/include/asm/microcode.h  |  4 +--
 arch/x86/kernel/cpu/microcode/amd.c   | 19 ++-
 arch/x86/kernel/cpu/microcode/core.c  | 31 --
 arch/x86/kernel/cpu/microcode/intel.c | 61 ++-
 5 files changed, 88 insertions(+), 34 deletions(-)

diff --git a/Documentation/x86/microcode.rst b/Documentation/x86/microcode.rst
index a320d37..ad804eb 100644
--- a/Documentation/x86/microcode.rst
+++ b/Documentation/x86/microcode.rst
@@ -110,6 +110,13 @@ The loading mechanism looks for microcode blobs in
 /lib/firmware/{intel-ucode,amd-ucode}. The default distro installation
 packages already put them there.
 
+The microcode will not be updated if the existing revision is newer or the
+same. In order to force a reload you can run the following command::
+
+  # echo 2 > /sys/devices/system/cpu/microcode/reload
+
+as root.
+
 Builtin microcode
 =
 
diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
index 2b7cc53..f5bc849 100644
--- a/arch/x86/include/asm/microcode.h
+++ b/arch/x86/include/asm/microcode.h
@@ -36,7 +36,7 @@ struct microcode_ops {
const void __user *buf, size_t size);
 
enum ucode_state (*request_microcode_fw) (int cpu, struct device *,
- bool refresh_fw);
+ bool refresh_fw, bool 
force_ucode_load);
 
void (*microcode_fini_cpu) (int cpu);
 
@@ -46,7 +46,7 @@ struct microcode_ops {
 * are being called.
 * See also the "Synchronization" section in microcode_core.c.
 */
-   enum ucode_state (*apply_microcode) (int cpu);
+   enum ucode_state (*apply_microcode) (int cpu, bool force_ucode_load);
int (*collect_cpu_info) (int cpu, struct cpu_signature *csig);
 };
 
diff --git a/arch/x86/kernel/cpu/microcode/amd.c 
b/arch/x86/kernel/cpu/microcode/amd.c
index 4ddadf6..1d6e4e2 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -539,7 +539,8 @@ void load_ucode_amd_ap(unsigned int cpuid_1_eax)
 }
 
 static enum ucode_state
-load_microcode_amd(bool save, u8 family, const u8 *data, size_t size);
+load_microcode_amd(bool save, u8 family, const u8 *data, size_t size,
+  bool force_ucode_load);
 
 int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax)
 {
@@ -557,7 +558,7 @@ int __init save_microcode_in_initrd_amd(unsigned int 
cpuid_1_eax)
if (!desc.mc)
return -EINVAL;
 
-   ret = load_microcode_amd(true, x86_family(cpuid_1_eax), desc.data, 
desc.size);
+   ret = load_microcode_amd(true, x86_family(cpuid_1_eax), desc.data, 
desc.size, false);
if (ret > UCODE_UPDATED)
return -EINVAL;
 
@@ -666,7 +667,7 @@ static int collect_cpu_info_amd(int cpu, struct 
cpu_signature *csig)
return 0;
 }
 
-static enum ucode_state apply_microcode_amd(int cpu)
+static enum ucode_state apply_microcode_amd(int cpu, bool force_ucode_load)
 {
struct cpuinfo_x86 *c = _data(cpu);
struct microcode_amd *mc_amd;
@@ -689,7 +690,7 @@ static enum ucode_state apply_microcode_amd(int cpu)
rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
 
/* need to apply patch? */
-   if (rev >= mc_amd->hdr.patch_id) {
+   if (rev >= mc_amd->hdr.patch_id && !force_ucode_load) {
ret = UCODE_OK;
goto out;
}
@@ -835,7 +836,8 @@ static enum ucode_state __load_microcode_amd(u8 family, 
const u8 *data,
 }
 
 static enum ucode_state

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

2019-08-28 Thread Stephen Rothwell
Hi all,

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


Caused by commit

  ef9cc255c953 ("usb: Add USB subsystem notifications")

# CONFIG_USB_NOTIFICATIONS is not set

I have used the keys tree from next-20190828 for today.

-- 
Cheers,
Stephen Rothwell


pgpKFod8MZp2_.pgp
Description: OpenPGP digital signature


[PATCH v2 1/2 RESEND] usb: core: phy: add support for PHY calibration

2019-08-28 Thread Marek Szyprowski
Some PHYs (for example Exynos5 USB3.0 DRD PHY) require calibration to be
done after every USB HCD reset. Generic PHY framework has been already
extended with phy_calibrate() function in commit 36914111e682 ("drivers:
phy: add calibrate method"). This patch adds support for it to generic
PHY handling code in USB HCD core.

Signed-off-by: Marek Szyprowski 
Tested-by: Anand Moon 
Tested-by: Jochen Sprickerhof 
---
 drivers/usb/core/hcd.c |  7 +++
 drivers/usb/core/phy.c | 21 +
 drivers/usb/core/phy.h |  1 +
 3 files changed, 29 insertions(+)

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 88533938ce19..b89936c1df23 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2291,6 +2291,9 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t 
msg)
hcd->state = HC_STATE_RESUMING;
status = hcd->driver->bus_resume(hcd);
clear_bit(HCD_FLAG_WAKEUP_PENDING, >flags);
+   if (status == 0)
+   status = usb_phy_roothub_calibrate(hcd->phy_roothub);
+
if (status == 0) {
struct usb_device *udev;
int port1;
@@ -2864,6 +2867,10 @@ int usb_add_hcd(struct usb_hcd *hcd,
}
hcd->rh_pollable = 1;
 
+   retval = usb_phy_roothub_calibrate(hcd->phy_roothub);
+   if (retval)
+   goto err_hcd_driver_setup;
+
/* NOTE: root hub and controller capabilities may not be the same */
if (device_can_wakeup(hcd->self.controller)
&& device_can_wakeup(>self.root_hub->dev))
diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c
index 7580493b867a..fb1588e7c282 100644
--- a/drivers/usb/core/phy.c
+++ b/drivers/usb/core/phy.c
@@ -151,6 +151,27 @@ int usb_phy_roothub_set_mode(struct usb_phy_roothub 
*phy_roothub,
 }
 EXPORT_SYMBOL_GPL(usb_phy_roothub_set_mode);
 
+int usb_phy_roothub_calibrate(struct usb_phy_roothub *phy_roothub)
+{
+   struct usb_phy_roothub *roothub_entry;
+   struct list_head *head;
+   int err;
+
+   if (!phy_roothub)
+   return 0;
+
+   head = _roothub->list;
+
+   list_for_each_entry(roothub_entry, head, list) {
+   err = phy_calibrate(roothub_entry->phy);
+   if (err)
+   return err;
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(usb_phy_roothub_calibrate);
+
 int usb_phy_roothub_power_on(struct usb_phy_roothub *phy_roothub)
 {
struct usb_phy_roothub *roothub_entry;
diff --git a/drivers/usb/core/phy.h b/drivers/usb/core/phy.h
index dad564e2d2d4..20a267cd986b 100644
--- a/drivers/usb/core/phy.h
+++ b/drivers/usb/core/phy.h
@@ -18,6 +18,7 @@ int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub);
 
 int usb_phy_roothub_set_mode(struct usb_phy_roothub *phy_roothub,
 enum phy_mode mode);
+int usb_phy_roothub_calibrate(struct usb_phy_roothub *phy_roothub);
 int usb_phy_roothub_power_on(struct usb_phy_roothub *phy_roothub);
 void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_roothub);
 
-- 
2.17.1



[PATCH v2 0/2 2nd RESEND] Fix USB3.0 DRD PHY calibration issues (DWC3/XHCI) on Exynos542x SoCs

2019-08-28 Thread Marek Szyprowski
Dear All,

Commit d8c80bb3b55b ("phy: exynos5-usbdrd: Calibrate LOS levels for
exynos5420/5800") added support for Exynos5 USB3.0 DRD PHY calibration,
what enabled proper Super-Speed enumeration of USB3.0 devices connected
to various Exynos5 SoCs. After some time it turned out that the mentioned
patch worked a bit by pure luck and covered only one use case: fresh
boot with all drivers compiled into the kernel.

If drivers were compiled as modules, due to timing issues, it worked only
if XHCI-plat driver was loaded before the DWC3 driver:
https://patchwork.kernel.org/patch/10773947/

Also during the system suspend/resume cycle the calibration was not
performed at the proper time, what resulted in switching USB 3.0 devices to
USB 2.0 high-speed compatibility mode.

This patch addresses all those issues. Exynos5 USB3.0 DRD PHY calibration
is moved to the generic USB HCD PHY handling code, which takes care of
proper PHY calibration after HCD (XHCI) core reset. This fixes all known
use cases (XHCI driver compiled as module and loaded on demand as well as
during system suspend/resume cycle).

The main change comparing to v1 is huge simplification of the code:
generic PHYs are already handled by HCD core code, so the calibration is
added there. No Exynos-specific XHCI driver variant is needed anymore.
There is also no need to change the way the DWC3 driver is instantiated,
what wasn't done right in v1 too (the code oopsed on module remove).

Here are the logs taken on Exynos5422-based Odroid HC1 board (with USB3.0
RTL8153 LAN and USB3.0 JMicron SATA-USB bridge):

Vanilla Linux next-20190716:
->8-
root@target:~# lsusb -t
/:  Bus 06.Port 1: Dev 1, Class=root_hub, Driver=xhci-hcd/1p, 5000M
|__ Port 1: Dev 2, If 0, Class=Vendor Specific Class, Driver=r8152, 5000M
/:  Bus 05.Port 1: Dev 1, Class=root_hub, Driver=xhci-hcd/1p, 480M
/:  Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci-hcd/1p, 5000M
|__ Port 1: Dev 2, If 0, Class=Mass Storage, Driver=uas, 5000M
/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci-hcd/1p, 480M
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=exynos-ohci/3p, 12M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=exynos-ehci/3p, 480M
root@target:~# time rtcwake -s 10 -m mem
rtcwake: wakeup from "mem" using /dev/rtc0 at Fri Jul 19 07:08:29 2019
[   43.641914] PM: suspend entry (deep)
[   43.647758] Filesystems sync: 0.003 seconds
[   43.663038] Freezing user space processes ... (elapsed 0.006 seconds) done.
[   43.674858] OOM killer disabled.
[   43.677824] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) 
done.
[   43.685644] printk: Suspending console(s) (use no_console_suspend to debug)
[   43.754198] sd 0:0:0:0: [sda] Synchronizing SCSI cache
[   43.831613] wake enabled for irq 145
[   43.994550] samsung-pinctrl 1340.pinctrl: Setting external wakeup 
interrupt mask: 0xffef
[   44.004378] Disabling non-boot CPUs ...
[   44.014851] IRQ 51: no longer affine to CPU1
[   44.023293] IRQ 52: no longer affine to CPU2
[   44.028975] IRQ 53: no longer affine to CPU3
[   44.031818] IRQ 54: no longer affine to CPU4
[   44.034229] IRQ 55: no longer affine to CPU5
[   44.036648] IRQ 56: no longer affine to CPU6
[   44.040546] IRQ 57: no longer affine to CPU7
[   44.048237] Enabling non-boot CPUs ...
[   44.053004] CPU1 is up
[   44.056036] CPU2 is up
[   44.058860] CPU3 is up
[   44.059552] CPU4: detected I-Cache line size mismatch, workaround enabled
[   44.063502] CPU4 is up
[   44.064097] CPU5: detected I-Cache line size mismatch, workaround enabled
[   44.065997] CPU5 is up
[   44.066611] CPU6: detected I-Cache line size mismatch, workaround enabled
[   44.068640] CPU6 is up
[   44.069259] CPU7: detected I-Cache line size mismatch, workaround enabled
[   44.071689] CPU7 is up
[   44.096037] s3c2410-wdt 101d.watchdog: watchdog disabled
[   44.176142] wake disabled for irq 145
[   44.184616] usb usb3: root hub lost power or was reset
[   44.184705] usb usb4: root hub lost power or was reset
[   44.184804] s3c-rtc 101e.rtc: rtc disabled, re-enabling
[   44.184877] usb usb5: root hub lost power or was reset
[   44.184894] usb usb6: root hub lost power or was reset
[   48.467048] OOM killer enabled.
[   48.470075] Restarting tasks ...
[   48.471490] usb 4-1: USB disconnect, device number 2
[   48.473789] usb 6-1: USB disconnect, device number 2
[   48.474380] done.
[   48.487766] PM: suspend exit

real0m15.098s
user0m0.000s
sys 0m0.358s
[   48.519357] mmc_host mmc0: Bus speed (slot 0) = 5000Hz (slot req 
40Hz, actual 396825HZ div = 63)
root@target:~# [   48.540888] sd 0:0:0:0: [sda] Synchronizing SCSI cache
[   48.624651] mmc_host mmc0: Bus speed (slot 0) = 2Hz (slot req 
2Hz, actual 2HZ div = 0)
[   48.874422] usb 5-1: new high-speed USB device number 3 using xhci-hcd
[   49.154586] sd 0:0:0:0: [sda] Synchronize Cache(10) failed: Result: 
hostbyte=0x07 

[PATCH v2 2/2 RESEND] usb: dwc3: remove generic PHY calibrate() calls

2019-08-28 Thread Marek Szyprowski
Calls to USB2 generic PHY calibrate() method has been moved to HCD core,
which now successfully handles generic PHYs and their calibration after
every HCD reset. This fixes all the timing issues related to PHY
calibration done directly from DWC3 driver: incorrect operation after
system suspend/resume or USB3.0 detection failure when XHCI-plat driver
compiled as separate module.

Signed-off-by: Marek Szyprowski 
Tested-by: Anand Moon 
Tested-by: Jochen Sprickerhof 
Acked-by: Felipe Balbi 
---
 drivers/usb/dwc3/core.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index c9bb93a2c81e..7dd6d419254d 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -168,7 +168,6 @@ static void __dwc3_set_mode(struct work_struct *work)
otg_set_vbus(dwc->usb2_phy->otg, true);
phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_HOST);
phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_HOST);
-   phy_calibrate(dwc->usb2_generic_phy);
}
break;
case DWC3_GCTL_PRTCAP_DEVICE:
@@ -1166,7 +1165,6 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
dev_err(dev, "failed to initialize host\n");
return ret;
}
-   phy_calibrate(dwc->usb2_generic_phy);
break;
case USB_DR_MODE_OTG:
INIT_WORK(>drd_work, __dwc3_set_mode);
-- 
2.17.1



Re: [PATCH v2] powerpc/fadump: when fadump is supported register the fadump sysfs files.

2019-08-28 Thread Hari Bathini



On 28/08/19 10:57 PM, Michal Suchanek wrote:
> Currently it is not possible to distinguish the case when fadump is
> supported by firmware and disabled in kernel and completely unsupported
> using the kernel sysfs interface. User can investigate the devicetree
> but it is more reasonable to provide sysfs files in case we get some
> fadumpv2 in the future.
> 
> With this patch sysfs files are available whenever fadump is supported
> by firmware.
> 
> Signed-off-by: Michal Suchanek 
> ---

[...]

> - if (!fw_dump.fadump_supported) {
> + if (!fw_dump.fadump_supported && fw_dump.fadump_enabled) {
>   printk(KERN_ERR "Firmware-assisted dump is not supported on"
>   " this hardware\n");
> - return 0;
>   }

The above hunk is redundant with similar message already logged during
early boot in fadump_reserve_mem() function. I am not strongly against
this though. So...


Acked-by: Hari Bathini 



Re: [PATCH v2 1/2 RESEND] usb: core: phy: add support for PHY calibration

2019-08-28 Thread Marek Szyprowski
Hi Greg,

On 2019-08-28 22:41, Greg Kroah-Hartman wrote:
> On Mon, Aug 26, 2019 at 10:55:33AM +0200, Marek Szyprowski wrote:
>> Hi Greg
>>
>> On 2019-08-08 11:41, Marek Szyprowski wrote:
>>> Some PHYs (for example Exynos5 USB3.0 DRD PHY) require calibration to be
>>> done after every USB HCD reset. Generic PHY framework has been already
>>> extended with phy_calibrate() function in commit 36914111e682 ("drivers:
>>> phy: add calibrate method"). This patch adds support for it to generic
>>> PHY handling code in USB HCD core.
>>>
>>> Signed-off-by: Marek Szyprowski 
>>> Tested-by: Anand Moon 
>>> Tested-by: Jochen Sprickerhof 
>> Greg: any chance to give it this a try in -next? If not, maybe You can
>> point someone whose review will help?
> Ah crap, this is me, not the PHY maintainer :(
>
> Can you resend this and I will be glad to review it.  But it would also
> be good to get Felipe's review as well.

No problem, I will resend it again in a few minutes. Felipe already 
acked it: https://lkml.org/lkml/2019/8/8/460

Best regards
-- 
Marek Szyprowski, PhD
Samsung R Institute Poland



Re: [PATCH rebased] powerpc/fadump: when fadump is supported register the fadump sysfs files.

2019-08-28 Thread Hari Bathini



On 28/08/19 10:37 PM, Michal Suchánek wrote:
> On Tue, 27 Aug 2019 17:57:31 +0530
> Hari Bathini  wrote:
> 

[...]

>> Also, get rid of the error message when fadump is
>> not supported as it is already taken care of in fadump_reserve_mem() 
>> function.
> 
> That should not be called in that case, should it?

fadump_reserve_mem() is called during early boot while this is an initcall that 
happens
later. Not sure if we can make the initcall conditional on fadump support 
though..

> Anyway, I find the message right next to the message about reserving
> memory for kdump. So it really looks helpful in the log.

The message you see right after memory reservation for kdump is coming from
fadump_reserve_mem() function. This is the repeat of the same message logged
much later...
 
- Hari



Re: [PATCH] sky2: Disable MSI on yet another ASUS boards (P6Xxxx)

2019-08-28 Thread Takashi Iwai
On Thu, 29 Aug 2019 01:09:37 +0200,
David Miller wrote:
> 
> From: Takashi Iwai 
> Date: Wed, 28 Aug 2019 08:31:19 +0200
> 
> > A similar workaround for the suspend/resume problem is needed for yet
> > another ASUS machines, P6X models.  Like the previous fix, the BIOS
> > doesn't provide the standard DMI_SYS_* entry, so again DMI_BOARD_*
> > entries are used instead.
> > 
> > Reported-and-tested-by: SteveM 
> > Signed-off-by: Takashi Iwai 
> 
> Applied, but this is getting suspicious.
> 
> It looks like MSI generally is not restored properly on resume on these
> boards, so maybe there simply needs to be a generic PCI quirk for that?

Yes, I wondered that, too.
But, e.g. HD-audio should use MSI on Intel platforms, and if the
problem were generic, it must suffer from the same issue, and I
haven't heard of such, so far.  So it's likely specific to some
limited devices, as it seems.


Thanks!

Takashi


Re: [PATCH v7 13/13] arm64: dts: Add power controller device node of MT8183

2019-08-28 Thread CK Hu
Hi, Weiyi:

On Wed, 2019-08-28 at 17:11 +0800, Weiyi Lu wrote:
> Add power controller node and smi-common node for MT8183
> In scpsys node, it contains clocks and regmapping of
> infracfg and smi-common for bus protection.
> 
> Signed-off-by: Weiyi Lu 
> ---
>  arch/arm64/boot/dts/mediatek/mt8183.dtsi | 62 
> 
>  1 file changed, 62 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi 
> b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> index c2749c4..66aaa07 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> @@ -8,6 +8,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include "mt8183-pinfunc.h"
>  
>  / {
> @@ -238,6 +239,62 @@
>   #interrupt-cells = <2>;
>   };
>  
> + scpsys: syscon@10006000 {
> + compatible = "mediatek,mt8183-scpsys", "syscon";
> + #power-domain-cells = <1>;
> + reg = <0 0x10006000 0 0x1000>;
> + clocks = < CLK_TOP_MUX_AUD_INTBUS>,
> +  < CLK_INFRA_AUDIO>,
> +  < CLK_INFRA_AUDIO_26M_BCLK>,
> +  < CLK_TOP_MUX_MFG>,
> +  < CLK_TOP_MUX_MM>,
> +  < CLK_TOP_MUX_CAM>,
> +  < CLK_TOP_MUX_IMG>,
> +  < CLK_TOP_MUX_IPU_IF>,
> +  < CLK_TOP_MUX_DSP>,
> +  < CLK_TOP_MUX_DSP1>,
> +  < CLK_TOP_MUX_DSP2>,
> +  < CLK_MM_SMI_COMMON>,
> +  < CLK_MM_SMI_LARB0>,
> +  < CLK_MM_SMI_LARB1>,
> +  < CLK_MM_GALS_COMM0>,
> +  < CLK_MM_GALS_COMM1>,
> +  < CLK_MM_GALS_CCU2MM>,
> +  < CLK_MM_GALS_IPU12MM>,
> +  < CLK_MM_GALS_IMG2MM>,
> +  < CLK_MM_GALS_CAM2MM>,
> +  < CLK_MM_GALS_IPU2MM>,

Just mention the discussion in [1], we need to confirm this is hardware
limitation or not.

[1] https://patchwork.kernel.org/patch/11005731/

Regards,
CK

> +  < CLK_IMG_LARB5>,
> +  < CLK_IMG_LARB2>,
> +  < CLK_CAM_LARB6>,
> +  < CLK_CAM_LARB3>,
> +  < CLK_CAM_SENINF>,
> +  < CLK_CAM_CAMSV0>,
> +  < CLK_CAM_CAMSV1>,
> +  < CLK_CAM_CAMSV2>,
> +  < CLK_CAM_CCU>,
> +  <_conn CLK_IPU_CONN_IPU>,
> +  <_conn CLK_IPU_CONN_AHB>,
> +  <_conn CLK_IPU_CONN_AXI>,
> +  <_conn CLK_IPU_CONN_ISP>,
> +  <_conn CLK_IPU_CONN_CAM_ADL>,
> +  <_conn CLK_IPU_CONN_IMG_ADL>;
> + clock-names = "audio", "audio1", "audio2",
> +   "mfg", "mm", "cam",
> +   "isp", "vpu", "vpu1",
> +   "vpu2", "vpu3", "mm-0",
> +   "mm-1", "mm-2", "mm-3",
> +   "mm-4", "mm-5", "mm-6",
> +   "mm-7", "mm-8", "mm-9",
> +   "isp-0", "isp-1", "cam-0",
> +   "cam-1", "cam-2", "cam-3",
> +   "cam-4", "cam-5", "cam-6",
> +   "vpu-0", "vpu-1", "vpu-2",
> +   "vpu-3", "vpu-4", "vpu-5";
> + infracfg = <>;
> + smi_comm = <_common>;
> + };
> +
>   apmixedsys: syscon@1000c000 {
>   compatible = "mediatek,mt8183-apmixedsys", "syscon";
>   reg = <0 0x1000c000 0 0x1000>;
> @@ -396,6 +453,11 @@
>   #clock-cells = <1>;
>   };
>  
> + smi_common: smi@14019000 {
> + compatible = "mediatek,mt8183-smi-common", "syscon";
> + reg = <0 0x14019000 0 0x1000>;
> + };
> +
>   imgsys: syscon@1502 {
>   compatible = "mediatek,mt8183-imgsys", "syscon";
>   reg = <0 0x1502 0 0x1000>;




Re: [PATCH v2 07/10] PCI: layerscape: Modify the MSIX to the doorbell way

2019-08-28 Thread Kishon Vijay Abraham I
Gustavo,

On 27/08/19 6:55 PM, Andrew Murray wrote:
> On Sat, Aug 24, 2019 at 12:08:40AM +, Xiaowei Bao wrote:
>>
>>
>>> -Original Message-
>>> From: Andrew Murray 
>>> Sent: 2019年8月23日 21:58
>>> To: Xiaowei Bao 
>>> Cc: bhelg...@google.com; robh...@kernel.org; mark.rutl...@arm.com;
>>> shawn...@kernel.org; Leo Li ; kis...@ti.com;
>>> lorenzo.pieral...@arm.co; a...@arndb.de; gre...@linuxfoundation.org; M.h.
>>> Lian ; Mingkai Hu ; Roy
>>> Zang ; jingooh...@gmail.com;
>>> gustavo.pimen...@synopsys.com; linux-...@vger.kernel.org;
>>> devicet...@vger.kernel.org; linux-kernel@vger.kernel.org;
>>> linux-arm-ker...@lists.infradead.org; linuxppc-...@lists.ozlabs.org
>>> Subject: Re: [PATCH v2 07/10] PCI: layerscape: Modify the MSIX to the
>>> doorbell way
>>>
>>> On Thu, Aug 22, 2019 at 07:22:39PM +0800, Xiaowei Bao wrote:
 The layerscape platform use the doorbell way to trigger MSIX interrupt
 in EP mode.

>>>
>>> I have no problems with this patch, however...
>>>
>>> Are you able to add to this message a reason for why you are making this
>>> change? Did dw_pcie_ep_raise_msix_irq not work when func_no != 0? Or did
>>> it work yet dw_pcie_ep_raise_msix_irq_doorbell is more efficient?
>>
>> The fact is that, this driver is verified in ls1046a platform of NXP before, 
>> and ls1046a don't
>> support MSIX feature, so I set the msix_capable of pci_epc_features struct 
>> is false,
>> but in other platform, e.g. ls1088a, it support the MSIX feature, I verified 
>> the MSIX
>> feature in ls1088a, it is not OK, so I changed to another way. Thanks.
> 
> Right, so the existing pci-layerscape-ep.c driver never supported MSIX yet it
> erroneously had a switch case statement to call dw_pcie_ep_raise_msix_irq 
> which
> would never get used.
> 
> Now that we're adding a platform with MSIX support the existing
> dw_pcie_ep_raise_msix_irq doesn't work (for this platform) so we are adding a
> different method.

Gustavo, can you confirm dw_pcie_ep_raise_msix_irq() works for designware as it
didn't work for both me and Xiaowei?

Thanks
Kishon


Re: [PATCH v2 3/3] dwc: PCI: intel: Intel PCIe RC controller driver

2019-08-28 Thread Kishon Vijay Abraham I
Hi Martin,

On 28/08/19 2:08 AM, Martin Blumenstingl wrote:
> Hello,
> 
> On Tue, Aug 27, 2019 at 5:09 AM Chuan Hua, Lei
>  wrote:
>>
>> Hi Martin,
>>
>> Thanks for your feedback. Please check the comments below.
>>
>> On 8/27/2019 5:15 AM, Martin Blumenstingl wrote:
>>> Hello,
>>>
>>> On Mon, Aug 26, 2019 at 5:31 AM Chuan Hua, Lei
>>>  wrote:
 Hi Martin,

 Thanks for your valuable comments. I reply some of them as below.
>>> you're welcome
>>>
>>> [...]
>> +config PCIE_INTEL_AXI
>> +bool "Intel AHB/AXI PCIe host controller support"
> I believe that this is mostly the same IP block as it's used in Lantiq
> (xDSL) VRX200 SoCs (with MIPS cores) which was introduced in 2010
> (before Intel acquired Lantiq).
> This is why I would have personally called the driver PCIE_LANTIQ
 VRX200 SoC(internally called VR9) was the first PCIe SoC product which
 was using synopsys

 controller v3.30a. It only supports PCIe Gen1.1/1.0. The phy is internal
 phy from infineon.
>>> thank you for these details
>>> I wasn't aware that the PCIe PHY on these SoCs was developed by
>>> Infineon nor is the DWC version documented anywhere
>>
>> VRX200/ARX300 PHY is internal value. There are a lot of hardcode which was
>> from hardware people. From XRX500, we switch to synopsis PHY. However, later
>> comboPHY is coming to the picture. Even though we have one same controller
>> with different versions, we most likely will have three different phy
>> drivers.
> that is a good argument for using a separate PHY driver and
> integrating that using the PHY subsystem (which is already the case in
> this patch revision)
> 
.
.

>> +static int intel_pcie_ep_rst_init(struct intel_pcie_port *lpp)
>> +{
>> +struct device *dev = lpp->pci->dev;
>> +int ret = 0;
>> +
>> +lpp->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
>> +if (IS_ERR(lpp->reset_gpio)) {
>> +ret = PTR_ERR(lpp->reset_gpio);
>> +if (ret != -EPROBE_DEFER)
>> +dev_err(dev, "failed to request PCIe GPIO: %d\n", 
>> ret);
>> +return ret;
>> +}
>> +/* Make initial reset last for 100ms */
>> +msleep(100);
> why is there lpp->rst_interval when you hardcode 100ms here?
 There are different purpose. rst_interval is purely for asserted reset
 pulse.

 Here 100ms is to make sure the initial state keeps at least 100ms, then we
 can reset.
>>> my interpretation is that it totally depends on the board design or
>>> the bootloader setup.
>>
>> Partially, you are right. However, we should not add some dependency
>> here from
>> bootloader and board. rst_interval is just to make sure the pulse (low
>> active or high active)
>> lasts the specified the time.
> +Cc Kishon
> 
> he recently added support for a GPIO reset line to the
> pcie-cadence-host.c [0] and I believe he's also maintaining
> pci-keystone.c which are both using a 100uS delay (instead of 100ms).
> I don't know the PCIe spec so maybe Kishon can comment on the values
> that should be used according to the spec.
> if there's then a reason why values other than the ones from the spec
> are needed then there should be a comment explaining why different
> values are needed (what problem does it solve).

The PCI EXPRESS CARD ELECTROMECHANICAL SPECIFICATION defines the Power
Sequencing and Reset Signal Timings in Table 2-4. Please also refer Figure
2-10: Power Up of the CEM.

╔═╤══╤═╤═╤═══╗
║ Symbol  │ Parameter│ Min │ Max │ Units ║
╠═╪══╪═╪═╪═══╣
║ T PVPERL│ Power stable to PERST# inactive  │ 100 │ │ ms║
╟─┼──┼─┼─┼───╢
║ T PERST-CLK │ REFCLK stable before PERST# inactive │ 100 │ │ μs║
╟─┼──┼─┼─┼───╢
║ T PERST │ PERST# active time   │ 100 │ │ μs║
╟─┼──┼─┼─┼───╢
║ T FAIL  │ Power level invalid to PERST# active │ │ 500 │ ns║
╟─┼──┼─┼─┼───╢
║ T WKRF  │ WAKE# rise – fall time   │ │ 100 │ ns║
╚═╧══╧═╧═╧═══╝

In my code I used T PERST-CLK (i.e REFCLK stable before PERST# inactive).
REFCLK to the card is enabled as part of PHY enable and then wait for 100μs
before making PERST# inactive.

Power to the device is given during board power up and the assumption here is
it will take more the 100ms for the probe to be invoked after board power up
(i.e after ROM, bootloaders and linux kernel). But if you have a regulator that
is enabled in PCI probe, then T PVPERL (100ms) should also used in 

linux-next: manual merge of the keys tree with the security tree

2019-08-28 Thread Stephen Rothwell
Hi all,

Today's linux-next merge of the keys tree got a conflict in:

  include/linux/security.h

between commit:

  9e47d31d6a57 ("security: Add a "locked down" LSM hook")

from the security tree and commit:

  25d2a1e61245 ("security: Add hooks to rule on setting a watch")

from the keys tree.

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

-- 
Cheers,
Stephen Rothwell

diff --cc include/linux/security.h
index 23e1c3f17d48,003437714eee..
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@@ -441,7 -394,13 +443,14 @@@ void security_inode_invalidate_secctx(s
  int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
  int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
  int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
 +int security_locked_down(enum lockdown_reason what);
+ #ifdef CONFIG_WATCH_QUEUE
+ int security_watch_key(struct watch *watch, struct key *key);
+ int security_watch_devices(struct watch *watch);
+ int security_post_notification(const struct cred *w_cred,
+  const struct cred *cred,
+  struct watch_notification *n);
+ #endif /* CONFIG_WATCH_QUEUE */
  #else /* CONFIG_SECURITY */
  
  static inline int call_blocking_lsm_notifier(enum lsm_event event, void *data)
@@@ -1259,10 -1213,22 +1268,26 @@@ static inline int security_inode_getsec
  {
return -EOPNOTSUPP;
  }
 +static inline int security_locked_down(enum lockdown_reason what)
 +{
 +  return 0;
 +}
+ #ifdef CONFIG_WATCH_QUEUE
+ static inline int security_watch_key(struct watch *watch, struct key *key)
+ {
+   return 0;
+ }
+ static inline int security_watch_devices(struct watch *watch)
+ {
+   return 0;
+ }
+ static inline int security_post_notification(const struct cred *w_cred,
+const struct cred *cred,
+struct watch_notification *n)
+ {
+   return 0;
+ }
+ #endif /* CONFIG_WATCH_QUEUE */
  #endif/* CONFIG_SECURITY */
  
  #ifdef CONFIG_SECURITY_NETWORK


pgpmnEfA61NUJ.pgp
Description: OpenPGP digital signature


Re: [PATCH v4] watchdog: orion_wdt: use timer1 as a pretimeout

2019-08-28 Thread Chris Packham
On Wed, 2019-08-28 at 21:45 -0700, Guenter Roeck wrote:
> On 8/28/19 6:53 PM, Chris Packham wrote:
> > The orion watchdog can either reset the CPU or generate an interrupt.
> > The interrupt would be useful for debugging as it provides panic()
> > output about the watchdog expiry, however if the interrupt is used the
> > watchdog can't reset the CPU in the event of being stuck in a loop with
> > interrupts disabled or if the CPU is prevented from accessing memory
> > (e.g. an unterminated DMA).
> > 
> > The Armada SoCs have spare timers that aren't currently used by the
> > Linux kernel. We can use timer1 to provide a pre-timeout ahead of the
> > watchdog timer and provide the possibility of gathering debug before the
> > reset triggers.
> > 
> > Signed-off-by: Chris Packham 
> > ---
> > 
> > This was submitted previously[1], the other patches two from the series have
> > been picked up but this one seems to have fallen through the gaps.
> > 
> 
> I had marked it as "under review" but I don't recall why. Maybe it was because
> it depended on the other patches, but I don't recall, and I didn't keep track
> of those patches either. Sorry for that.
> 

No problem. I think it was related to discussions around the other
patches. I had meant to follow up earlier.

> > Changes in v3:
> > - rebase against linux/master
> > Changes in v2:
> > - apply changes to armada-38x only
> > 
> > [1] - 
> > https://lore.kernel.org/linux-watchdog/20190305201924.14853-4-chris.pack...@alliedtelesis.co.nz/
> > 
> >   drivers/watchdog/orion_wdt.c | 59 ++--
> >   1 file changed, 50 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
> > index cdb0d174c5e2..f2e90bfd7186 100644
> > --- a/drivers/watchdog/orion_wdt.c
> > +++ b/drivers/watchdog/orion_wdt.c
> > @@ -46,6 +46,11 @@
> >   #define WDT_AXP_FIXED_ENABLE_BIT BIT(10)
> >   #define WDT_A370_EXPIRED  BIT(31)
> >   
> > +#define TIMER1_VAL_OFF 0x001c
> > +#define TIMER1_ENABLE_BIT  BIT(2)
> > +#define TIMER1_FIXED_ENABLE_BITBIT(12)
> > +#define TIMER1_STATUS_BIT  BIT(8)
> > +
> 
> It would be better to group the bits associated with a single register 
> together.
> The bits above are not associated with TIMER1_VAL_OFF, yet the grouping 
> suggests
> that this may be the case.

Will fix.

> 
> >   static bool nowayout = WATCHDOG_NOWAYOUT;
> >   static int heartbeat = -1;/* module parameter (seconds) */
> >   
> > @@ -158,6 +163,7 @@ static int armadaxp_wdt_clock_init(struct 
> > platform_device *pdev,
> >struct orion_watchdog *dev)
> >   {
> > int ret;
> > +   u32 val;
> >   
> > dev->clk = of_clk_get_by_name(pdev->dev.of_node, "fixed");
> > if (IS_ERR(dev->clk))
> > @@ -169,38 +175,48 @@ static int armadaxp_wdt_clock_init(struct 
> > platform_device *pdev,
> > }
> >   
> > /* Enable the fixed watchdog clock input */
> > -   atomic_io_modify(dev->reg + TIMER_CTRL,
> > -WDT_AXP_FIXED_ENABLE_BIT,
> > -WDT_AXP_FIXED_ENABLE_BIT);
> > +   val = WDT_AXP_FIXED_ENABLE_BIT | TIMER1_FIXED_ENABLE_BIT;
> 
> This always sets TIMER1_FIXED_ENABLE_BIT, but later the enable bit is set
> only conditionally. I don't know what is correct, but this asks for a comment.

The fixed part is safe to set. It just means that the rate is constant.
I'll add a comment.

> 
> > +   atomic_io_modify(dev->reg + TIMER_CTRL, val, val);
> >   
> > dev->clk_rate = clk_get_rate(dev->clk);
> > +
> 
> We can only hope we won't see another patch two days from now where someone
> removes this added line.
> 
> I can understand such changes if they fix a checkpatch issue,
> but otherwise please refrain from whitespace changes.

I think it was to appease checkpatch, the one below certainly was. If
it's not needed for checkpatch I'll drop it in the next version.

> 
> > return 0;
> >   }
> >   
> >   static int orion_wdt_ping(struct watchdog_device *wdt_dev)
> >   {
> > struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
> > +
> > /* Reload watchdog duration */
> > writel(dev->clk_rate * wdt_dev->timeout,
> >dev->reg + dev->data->wdt_counter_offset);
> > +   if (dev->wdt.info->options & WDIOF_PRETIMEOUT)
> > +   writel(dev->clk_rate * (wdt_dev->timeout - wdt_dev->pretimeout),
> > +  dev->reg + TIMER1_VAL_OFF);
> > +
> > return 0;
> >   }
> >   
> >   static int armada375_start(struct watchdog_device *wdt_dev)
> >   {
> > struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
> > -   u32 reg;
> > +   u32 reg, val;
> >   
> 
> Is the second variable here and below really necessary ?
> 

No I can use reg.

> > /* Set watchdog duration */
> > writel(dev->clk_rate * wdt_dev->timeout,
> >dev->reg + dev->data->wdt_counter_offset);
> > +   if (dev->wdt.info->options & WDIOF_PRETIMEOUT)
> > +   writel(dev->clk_rate * 

build_path_from_dentry_optional_prefix() may schedule from invalid context

2019-08-28 Thread Sergey Senozhatsky
Hello,

Looking at commit "cifs: create a helper to find a writeable handle
by path name":

->open_file_lock scope is atomic context, while build_path_from_dentry()
can schedule - kmalloc(GFP_KERNEL)

   spin_lock(>open_file_lock);
   list_for_each(tmp, >openFileList) {
   cfile = list_entry(tmp, struct cifsFileInfo,
tlist);
   full_path = build_path_from_dentry(cfile->dentry);
   if (full_path == NULL) {
   spin_unlock(>open_file_lock);
   return -ENOMEM;
   }
   if (strcmp(full_path, name)) {
   kfree(full_path);
   continue;
   }
   kfree(full_path);

   cinode = CIFS_I(d_inode(cfile->dentry));
   spin_unlock(>open_file_lock);
   return cifs_get_writable_file(cinode, 0, ret_file);
   }

   spin_unlock(>open_file_lock);

Additionally, kfree() can (and should) be done outside of
->open_file_lock scope.

-ss


Re: [PATCH v2 7/7] bug: Move WARN_ON() "cut here" into exception handler

2019-08-28 Thread Christophe Leroy



Le 24/08/2019 à 21:08, Kees Cook a écrit :

Euh ... only received this mail yesterday. Same for the other answer.



On Fri, Aug 23, 2019 at 04:26:59PM +0200, Christophe Leroy wrote:



Le 23/08/2019 à 00:56, Andrew Morton a écrit :

On Tue, 20 Aug 2019 09:47:55 -0700 Kees Cook  wrote:


Reply-To: 20190819234111.9019-8-keesc...@chromium.org


Really?


That seems correct, that's the "[PATCH 7/7] bug: Move WARN_ON() "cut here"
into exception handler" from the series at
https://lkml.org/lkml/2019/8/19/1155





Subject: [PATCH v2 7/7] bug: Move WARN_ON() "cut here" into exception handler


It's strange to receive a standalone [7/7] patch.


Iaw the Reply_To, I understand it as an update of the 7th patch of the
series.


Was trying to avoid the churn of resending the identical 1-6 patches
(which are all just refactoring to make 7/7 not a mess).


Yes but Reply-To: means the address we have to use to answer to this email.

I think you wanted to use In-reply-to:



I can resend the whole series, if that's preferred.


I guess not.




Reported-by: Christophe Leroy 
Fixes: Fixes: 6b15f678fb7d ("include/asm-generic/bug.h: fix "cut here" for WARN_ON 
for __WARN_TAINT architectures")


I'm seeing double.


Tracking down all these combinations has been tricky, which is why I did
the patch 1-6 refactoring: it makes the call hierarchy much easier to
examine (IMO).


But still, Andrew is seing double ... And me as well :)

Fixes: Fixes:

Christophe



-Kees



[PATCH 2/2] gpio: iproc-gpio: Handle interrupts for multiple instances

2019-08-28 Thread Srinath Mannam
From: Rayagonda Kokatanur 

When multiple instance of iproc-gpio chips are present, a fix up
message[1] is printed during the probe of second and later instances.

This issue is because driver sharing same irq_chip data structure
among multiple instances of driver.

Fix this by allocating irq_chip data structure per instance of
iproc-gpio.

[1] fix up message addressed by this patch
[  7.862208] gpio gpiochip2: (689d.gpio): detected irqchip that
   is shared with multiple gpiochips: please fix the driver.

Fixes: 616043d58a89 ("pinctrl: Rename gpio driver from cygnus to iproc")
Signed-off-by: Rayagonda Kokatanur 
---
 drivers/pinctrl/bcm/pinctrl-iproc-gpio.c | 21 +++--
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c 
b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
index 20b9864..8729f47 100644
--- a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
+++ b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
@@ -114,6 +114,7 @@ struct iproc_gpio {
 
raw_spinlock_t lock;
 
+   struct irq_chip irqchip;
struct gpio_chip gc;
unsigned num_banks;
 
@@ -302,14 +303,6 @@ static int iproc_gpio_irq_set_type(struct irq_data *d, 
unsigned int type)
return 0;
 }
 
-static struct irq_chip iproc_gpio_irq_chip = {
-   .name = "bcm-iproc-gpio",
-   .irq_ack = iproc_gpio_irq_ack,
-   .irq_mask = iproc_gpio_irq_mask,
-   .irq_unmask = iproc_gpio_irq_unmask,
-   .irq_set_type = iproc_gpio_irq_set_type,
-};
-
 /*
  * Request the Iproc IOMUX pinmux controller to mux individual pins to GPIO
  */
@@ -875,14 +868,22 @@ static int iproc_gpio_probe(struct platform_device *pdev)
/* optional GPIO interrupt support */
irq = platform_get_irq(pdev, 0);
if (irq) {
-   ret = gpiochip_irqchip_add(gc, _gpio_irq_chip, 0,
+   chip->irqchip.name = "bcm-iproc-gpio";
+   chip->irqchip.irq_ack = iproc_gpio_irq_ack;
+   chip->irqchip.irq_mask = iproc_gpio_irq_mask;
+   chip->irqchip.irq_unmask = iproc_gpio_irq_unmask;
+   chip->irqchip.irq_set_type = iproc_gpio_irq_set_type;
+   chip->irqchip.irq_enable = iproc_gpio_irq_unmask;
+   chip->irqchip.irq_disable = iproc_gpio_irq_mask;
+
+   ret = gpiochip_irqchip_add(gc, >irqchip, 0,
   handle_simple_irq, IRQ_TYPE_NONE);
if (ret) {
dev_err(dev, "no GPIO irqchip\n");
goto err_rm_gpiochip;
}
 
-   gpiochip_set_chained_irqchip(gc, _gpio_irq_chip, irq,
+   gpiochip_set_chained_irqchip(gc, >irqchip, irq,
 iproc_gpio_irq_handler);
}
 
-- 
2.7.4



[PATCH 1/2] gpio: iproc-gpio: Fix incorrect pinconf configurations

2019-08-28 Thread Srinath Mannam
From: Li Jin 

Fix drive strength for AON/CRMU controller; fix pull-up/down setting
for CCM/CDRU controller.

Fixes: 616043d58a89 ("pinctrl: Rename gpio driver from cygnus to iproc")
Signed-off-by: Li Jin 
---
 drivers/pinctrl/bcm/pinctrl-iproc-gpio.c | 96 +---
 1 file changed, 77 insertions(+), 19 deletions(-)

diff --git a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c 
b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
index b70058c..20b9864 100644
--- a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
+++ b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
@@ -54,8 +54,12 @@
 /* drive strength control for ASIU GPIO */
 #define IPROC_GPIO_ASIU_DRV0_CTRL_OFFSET 0x58
 
-/* drive strength control for CCM/CRMU (AON) GPIO */
-#define IPROC_GPIO_DRV0_CTRL_OFFSET  0x00
+/* pinconf for CCM GPIO */
+#define IPROC_GPIO_PULL_DN_OFFSET   0x10
+#define IPROC_GPIO_PULL_UP_OFFSET   0x14
+
+/* pinconf for CRMU(aon) GPIO and CCM GPIO*/
+#define IPROC_GPIO_DRV_CTRL_OFFSET  0x00
 
 #define GPIO_BANK_SIZE 0x200
 #define NGPIOS_PER_BANK 32
@@ -76,6 +80,12 @@ enum iproc_pinconf_param {
IPROC_PINCON_MAX,
 };
 
+enum iproc_pinconf_ctrl_type {
+   IOCTRL_TYPE_AON = 1,
+   IOCTRL_TYPE_CDRU,
+   IOCTRL_TYPE_INVALID,
+};
+
 /*
  * Iproc GPIO core
  *
@@ -100,6 +110,7 @@ struct iproc_gpio {
 
void __iomem *base;
void __iomem *io_ctrl;
+   enum iproc_pinconf_ctrl_type io_ctrl_type;
 
raw_spinlock_t lock;
 
@@ -461,20 +472,44 @@ static const struct pinctrl_ops iproc_pctrl_ops = {
 static int iproc_gpio_set_pull(struct iproc_gpio *chip, unsigned gpio,
bool disable, bool pull_up)
 {
+   void __iomem *base;
unsigned long flags;
+   unsigned int shift;
+   u32 val_1, val_2;
 
raw_spin_lock_irqsave(>lock, flags);
-
-   if (disable) {
-   iproc_set_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio, false);
+   if (chip->io_ctrl_type == IOCTRL_TYPE_CDRU) {
+   base = chip->io_ctrl;
+   shift = IPROC_GPIO_SHIFT(gpio);
+
+   val_1 = readl(base + IPROC_GPIO_PULL_UP_OFFSET);
+   val_2 = readl(base + IPROC_GPIO_PULL_DN_OFFSET);
+   if (disable) {
+   /* no pull-up or pull-down */
+   val_1 &= ~BIT(shift);
+   val_2 &= ~BIT(shift);
+   } else if (pull_up) {
+   val_1 |= BIT(shift);
+   val_2 &= ~BIT(shift);
+   } else {
+   val_1 &= ~BIT(shift);
+   val_2 |= BIT(shift);
+   }
+   writel(val_1, base + IPROC_GPIO_PULL_UP_OFFSET);
+   writel(val_2, base + IPROC_GPIO_PULL_DN_OFFSET);
} else {
-   iproc_set_bit(chip, IPROC_GPIO_PAD_RES_OFFSET, gpio,
-  pull_up);
-   iproc_set_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio, true);
+   if (disable) {
+   iproc_set_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio,
+ false);
+   } else {
+   iproc_set_bit(chip, IPROC_GPIO_PAD_RES_OFFSET, gpio,
+ pull_up);
+   iproc_set_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio,
+ true);
+   }
}
 
raw_spin_unlock_irqrestore(>lock, flags);
-
dev_dbg(chip->dev, "gpio:%u set pullup:%d\n", gpio, pull_up);
 
return 0;
@@ -483,14 +518,35 @@ static int iproc_gpio_set_pull(struct iproc_gpio *chip, 
unsigned gpio,
 static void iproc_gpio_get_pull(struct iproc_gpio *chip, unsigned gpio,
 bool *disable, bool *pull_up)
 {
+   void __iomem *base;
unsigned long flags;
+   unsigned int shift;
+   u32 val_1, val_2;
 
raw_spin_lock_irqsave(>lock, flags);
-   *disable = !iproc_get_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio);
-   *pull_up = iproc_get_bit(chip, IPROC_GPIO_PAD_RES_OFFSET, gpio);
+   if (chip->io_ctrl_type == IOCTRL_TYPE_CDRU) {
+   base = chip->io_ctrl;
+   shift = IPROC_GPIO_SHIFT(gpio);
+
+   val_1 = readl(base + IPROC_GPIO_PULL_UP_OFFSET) & BIT(shift);
+   val_2 = readl(base + IPROC_GPIO_PULL_DN_OFFSET) & BIT(shift);
+
+   *pull_up = val_1 ? true : false;
+   *disable = (val_1 | val_2) ? false : true;
+
+   } else {
+   *disable = !iproc_get_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio);
+   *pull_up = iproc_get_bit(chip, IPROC_GPIO_PAD_RES_OFFSET, gpio);
+   }
raw_spin_unlock_irqrestore(>lock, flags);
 }
 
+#define DRV_STRENGTH_OFFSET(gpio, bit, type)  ((type) == IOCTRL_TYPE_AON ? \
+   ((2 - (bit)) * 4 + IPROC_GPIO_DRV_CTRL_OFFSET) : \
+   ((type) == IOCTRL_TYPE_CDRU) ? \
+   ((bit) * 4 + IPROC_GPIO_DRV_CTRL_OFFSET) : \
+   ((bit) * 4 + 

[PATCH 0/2] Add fixes to iProc GPIO driver

2019-08-28 Thread Srinath Mannam
This patch series adds the following fixes to the iProc GPIO driver
 - Fix Warning message given for shared irqchip data structure
 - Fix pinconfig of pull-up/down and drive strength for AON/CRMU GPIOs

This patch set is based on Linux-5.2-rc4.

Changes from v1:
  - Add Fixes tags in both patches

Li Jin (1):
  gpio: iproc-gpio: Fix incorrect pinconf configurations

Rayagonda Kokatanur (1):
  gpio: iproc-gpio: Handle interrupts for multiple instances

 drivers/pinctrl/bcm/pinctrl-iproc-gpio.c | 117 +++
 1 file changed, 88 insertions(+), 29 deletions(-)

-- 
2.7.4



[PATCH] selftests: watchdog: Add optional file argument

2019-08-28 Thread George G. Davis
Some systems have multiple watchdog devices where the first device
registered is assigned to the /dev/watchdog device file. In order
to test other watchdog devices, add an optional file argument for
selecting non-default watchdog devices for testing.

Signed-off-by: George G. Davis 
---
 tools/testing/selftests/watchdog/watchdog-test.c | 17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/watchdog/watchdog-test.c 
b/tools/testing/selftests/watchdog/watchdog-test.c
index c2333c78cf04..ebeb684552b9 100644
--- a/tools/testing/selftests/watchdog/watchdog-test.c
+++ b/tools/testing/selftests/watchdog/watchdog-test.c
@@ -19,7 +19,7 @@
 
 int fd;
 const char v = 'V';
-static const char sopts[] = "bdehp:t:Tn:NL";
+static const char sopts[] = "bdehp:t:Tn:NLf:";
 static const struct option lopts[] = {
{"bootstatus",  no_argument, NULL, 'b'},
{"disable", no_argument, NULL, 'd'},
@@ -31,6 +31,7 @@ static const struct option lopts[] = {
{"pretimeout",required_argument, NULL, 'n'},
{"getpretimeout",   no_argument, NULL, 'N'},
{"gettimeleft", no_argument, NULL, 'L'},
+   {"file",  required_argument, NULL, 'f'},
{NULL,  no_argument, NULL, 0x0}
 };
 
@@ -69,6 +70,7 @@ static void term(int sig)
 static void usage(char *progname)
 {
printf("Usage: %s [options]\n", progname);
+   printf(" -f, --file  Open watchdog device file (default is 
/dev/watchdog)\n");
printf(" -b, --bootstatusGet last boot status (Watchdog/POR)\n");
printf(" -d, --disable   Turn off the watchdog timer\n");
printf(" -e, --enableTurn on the watchdog timer\n");
@@ -92,10 +94,16 @@ int main(int argc, char *argv[])
int ret;
int c;
int oneshot = 0;
+   char *file = "/dev/watchdog";
 
setbuf(stdout, NULL);
 
-   fd = open("/dev/watchdog", O_WRONLY);
+   while ((c = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
+   if (c == 'f')
+   file = optarg;
+   }
+
+   fd = open(file, O_WRONLY);
 
if (fd == -1) {
if (errno == ENOENT)
@@ -108,6 +116,8 @@ int main(int argc, char *argv[])
exit(-1);
}
 
+   optind = 0;
+
while ((c = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
switch (c) {
case 'b':
@@ -190,6 +200,9 @@ int main(int argc, char *argv[])
else
printf("WDIOC_GETTIMELEFT error '%s'\n", 
strerror(errno));
break;
+   case 'f':
+   /* Handled above */
+   break;
 
default:
usage(argv[0]);
-- 
2.7.4



Re: [PATCH v4] watchdog: orion_wdt: use timer1 as a pretimeout

2019-08-28 Thread Guenter Roeck

On 8/28/19 6:53 PM, Chris Packham wrote:

The orion watchdog can either reset the CPU or generate an interrupt.
The interrupt would be useful for debugging as it provides panic()
output about the watchdog expiry, however if the interrupt is used the
watchdog can't reset the CPU in the event of being stuck in a loop with
interrupts disabled or if the CPU is prevented from accessing memory
(e.g. an unterminated DMA).

The Armada SoCs have spare timers that aren't currently used by the
Linux kernel. We can use timer1 to provide a pre-timeout ahead of the
watchdog timer and provide the possibility of gathering debug before the
reset triggers.

Signed-off-by: Chris Packham 
---

This was submitted previously[1], the other patches two from the series have
been picked up but this one seems to have fallen through the gaps.



I had marked it as "under review" but I don't recall why. Maybe it was because
it depended on the other patches, but I don't recall, and I didn't keep track
of those patches either. Sorry for that.


Changes in v3:
- rebase against linux/master
Changes in v2:
- apply changes to armada-38x only

[1] - 
https://lore.kernel.org/linux-watchdog/20190305201924.14853-4-chris.pack...@alliedtelesis.co.nz/

  drivers/watchdog/orion_wdt.c | 59 ++--
  1 file changed, 50 insertions(+), 9 deletions(-)

diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
index cdb0d174c5e2..f2e90bfd7186 100644
--- a/drivers/watchdog/orion_wdt.c
+++ b/drivers/watchdog/orion_wdt.c
@@ -46,6 +46,11 @@
  #define WDT_AXP_FIXED_ENABLE_BIT BIT(10)
  #define WDT_A370_EXPIRED  BIT(31)
  
+#define TIMER1_VAL_OFF		0x001c

+#define TIMER1_ENABLE_BIT  BIT(2)
+#define TIMER1_FIXED_ENABLE_BITBIT(12)
+#define TIMER1_STATUS_BIT  BIT(8)
+


It would be better to group the bits associated with a single register together.
The bits above are not associated with TIMER1_VAL_OFF, yet the grouping suggests
that this may be the case.


  static bool nowayout = WATCHDOG_NOWAYOUT;
  static int heartbeat = -1;/* module parameter (seconds) */
  
@@ -158,6 +163,7 @@ static int armadaxp_wdt_clock_init(struct platform_device *pdev,

   struct orion_watchdog *dev)
  {
int ret;
+   u32 val;
  
  	dev->clk = of_clk_get_by_name(pdev->dev.of_node, "fixed");

if (IS_ERR(dev->clk))
@@ -169,38 +175,48 @@ static int armadaxp_wdt_clock_init(struct platform_device 
*pdev,
}
  
  	/* Enable the fixed watchdog clock input */

-   atomic_io_modify(dev->reg + TIMER_CTRL,
-WDT_AXP_FIXED_ENABLE_BIT,
-WDT_AXP_FIXED_ENABLE_BIT);
+   val = WDT_AXP_FIXED_ENABLE_BIT | TIMER1_FIXED_ENABLE_BIT;


This always sets TIMER1_FIXED_ENABLE_BIT, but later the enable bit is set
only conditionally. I don't know what is correct, but this asks for a comment.


+   atomic_io_modify(dev->reg + TIMER_CTRL, val, val);
  
  	dev->clk_rate = clk_get_rate(dev->clk);

+


We can only hope we won't see another patch two days from now where someone
removes this added line.

I can understand such changes if they fix a checkpatch issue,
but otherwise please refrain from whitespace changes.


return 0;
  }
  
  static int orion_wdt_ping(struct watchdog_device *wdt_dev)

  {
struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
+
/* Reload watchdog duration */
writel(dev->clk_rate * wdt_dev->timeout,
   dev->reg + dev->data->wdt_counter_offset);
+   if (dev->wdt.info->options & WDIOF_PRETIMEOUT)
+   writel(dev->clk_rate * (wdt_dev->timeout - wdt_dev->pretimeout),
+  dev->reg + TIMER1_VAL_OFF);
+
return 0;
  }
  
  static int armada375_start(struct watchdog_device *wdt_dev)

  {
struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
-   u32 reg;
+   u32 reg, val;
  


Is the second variable here and below really necessary ?


/* Set watchdog duration */
writel(dev->clk_rate * wdt_dev->timeout,
   dev->reg + dev->data->wdt_counter_offset);
+   if (dev->wdt.info->options & WDIOF_PRETIMEOUT)
+   writel(dev->clk_rate * (wdt_dev->timeout - wdt_dev->pretimeout),
+  dev->reg + TIMER1_VAL_OFF);
  
  	/* Clear the watchdog expiration bit */

atomic_io_modify(dev->reg + TIMER_A370_STATUS, WDT_A370_EXPIRED, 0);
  
  	/* Enable watchdog timer */

-   atomic_io_modify(dev->reg + TIMER_CTRL, dev->data->wdt_enable_bit,
-   dev->data->wdt_enable_bit);
+   val = dev->data->wdt_enable_bit;
+   if (dev->wdt.info->options & WDIOF_PRETIMEOUT)
+   val |= TIMER1_ENABLE_BIT;
+   atomic_io_modify(dev->reg + TIMER_CTRL, val, val);
  
  	/* Enable reset on watchdog */

reg = readl(dev->rstout);
@@ -277,7 +293,7 @@ static int orion_stop(struct watchdog_device *wdt_dev)
 

[PATCH v4 1/2] drivers: hv: vmbus: Introduce latency testing

2019-08-28 Thread Branden Bonaby
Introduce user specified latency in the packet reception path
By exposing the test parameters as part of the debugfs channel
attributes. We will control the testing state via these attributes.

Signed-off-by: Branden Bonaby 
---
changes in v4:
 - Combined v3 patch 2 into this patch, and changed the
   commit description to reflect this.

 - Moved debugfs code from "vmbus_drv.c" that was in
   previous v3 patch 2, into a new file "debugfs.c" in
   drivers/hv.

 - Updated the Makefile to compile "debugfs.c" if
   CONFIG_HYPERV_TESTING is enabled

 - As per Michael's comments, added empty implementations
   of the new functions, so the compiler will not generate
   code when CONFIG_HYPERV_TESTING is not enabled.

 - Added microseconds into description for files in
   Documentation/ABI/testing/debugfs-hyperv.

Changes in v2:
 - Add #ifdef in Kconfig file so test code will not interfere
   with non-test code.
 - Move test code functions for delay to hyperv_vmbus header
   file.
 - Wrap test code under #ifdef statement.

 Documentation/ABI/testing/debugfs-hyperv |  23 +++
 MAINTAINERS  |   1 +
 drivers/hv/Kconfig   |   7 +
 drivers/hv/Makefile  |   1 +
 drivers/hv/connection.c  |   1 +
 drivers/hv/hv_debugfs.c  | 187 +++
 drivers/hv/hyperv_vmbus.h|  31 
 drivers/hv/ring_buffer.c |   2 +
 drivers/hv/vmbus_drv.c   |   6 +
 include/linux/hyperv.h   |  19 +++
 10 files changed, 278 insertions(+)
 create mode 100644 Documentation/ABI/testing/debugfs-hyperv
 create mode 100644 drivers/hv/hv_debugfs.c

diff --git a/Documentation/ABI/testing/debugfs-hyperv 
b/Documentation/ABI/testing/debugfs-hyperv
new file mode 100644
index ..0903e6427a2d
--- /dev/null
+++ b/Documentation/ABI/testing/debugfs-hyperv
@@ -0,0 +1,23 @@
+What:   /sys/kernel/debug/hyperv//fuzz_test_state
+Date:   August 2019
+KernelVersion:  5.3
+Contact:Branden Bonaby 
+Description:Fuzz testing status of a vmbus device, whether its in an ON
+state or a OFF state
+Users:  Debugging tools
+
+What:   
/sys/kernel/debug/hyperv//delay/fuzz_test_buffer_interrupt_delay
+Date:   August 2019
+KernelVersion:  5.3
+Contact:Branden Bonaby 
+Description:Fuzz testing buffer interrupt delay value between 0 - 1000
+microseconds (inclusive).
+Users:  Debugging tools
+
+What:   /sys/kernel/debug/hyperv//delay/fuzz_test_message_delay
+Date:   August 2019
+KernelVersion:  5.3
+Contact:Branden Bonaby 
+Description:Fuzz testing message delay value between 0 - 1000 microseconds
+(inclusive).
+Users:  Debugging tools
diff --git a/MAINTAINERS b/MAINTAINERS
index b1bc9c87838b..6931a4eeaac0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7460,6 +7460,7 @@ F:include/uapi/linux/hyperv.h
 F: include/asm-generic/mshyperv.h
 F: tools/hv/
 F: Documentation/ABI/stable/sysfs-bus-vmbus
+F: Documentation/ABI/testing/debugfs-hyperv
 
 HYPERBUS SUPPORT
 M: Vignesh Raghavendra 
diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
index 9a59957922d4..d97437ba0626 100644
--- a/drivers/hv/Kconfig
+++ b/drivers/hv/Kconfig
@@ -29,4 +29,11 @@ config HYPERV_BALLOON
help
  Select this option to enable Hyper-V Balloon driver.
 
+config HYPERV_TESTING
+bool "Hyper-V testing"
+default n
+depends on HYPERV && DEBUG_FS
+help
+  Select this option to enable Hyper-V vmbus testing.
+
 endmenu
diff --git a/drivers/hv/Makefile b/drivers/hv/Makefile
index a1eec7177c2d..d754bd86ca47 100644
--- a/drivers/hv/Makefile
+++ b/drivers/hv/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_HYPERV)   += hv_vmbus.o
 obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o
 obj-$(CONFIG_HYPERV_BALLOON)   += hv_balloon.o
+obj-$(CONFIG_HYPERV_TESTING)   += hv_debugfs.o
 
 CFLAGS_hv_trace.o = -I$(src)
 CFLAGS_hv_balloon.o = -I$(src)
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index 09829e15d4a0..4d4d40832846 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -357,6 +357,7 @@ void vmbus_on_event(unsigned long data)
 
trace_vmbus_on_event(channel);
 
+   hv_debug_delay_test(channel, INTERRUPT_DELAY);
do {
void (*callback_fn)(void *);
 
diff --git a/drivers/hv/hv_debugfs.c b/drivers/hv/hv_debugfs.c
new file mode 100644
index ..7a3f1ce71ffa
--- /dev/null
+++ b/drivers/hv/hv_debugfs.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Authors:
+ *   Branden Bonaby 
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "hyperv_vmbus.h"
+
+struct dentry *hv_debug_root;
+
+static int hv_debugfs_delay_get(void *data, u64 *val)
+{
+   *val = *(u32 *)data;
+   return 0;
+}
+
+static int 

[PATCH v4 0/2] hv: vmbus: add fuzz testing to hv device

2019-08-28 Thread Branden Bonaby
This patchset introduces a testing framework for Hyper-V drivers.
This framework allows us to introduce delays in the packet receive
path on a per-device basis. While the current code only supports
introducing arbitrary delays in the host/guest communication path,
we intend to expand this to support error injection in the future.

changes in v4:
  patch 1:
Combined previous v3 patches 1 and 2, into a single patch
which is now patch 1. This was done so that calls to
the new debugfs functions are in the same patch as
the definitions for these functions.

Moved debugfs code from "vmbus_drv.c" that was in
previous v3 patch 2, into a new file "debugfs.c" in
drivers/hv.

Updated the Makefile to compile "debugfs.c" if
CONFIG_HYPERV_TESTING is enabled

As per Michael's comments, added empty implementations
of the new functions, so the compiler will not generate
code when CONFIG_HYPERV_TESTING is not enabled.

  patch 2 (was previously v3 patch 3):
Based on Harrys comments, made the tool more
user friendly and added more error checking.

changes in v3:
  patch 2: change call to IS_ERR_OR_NULL, to IS_ERR.

  patch 3: Align python tool to match Linux coding style.

Changes in v2:
  Patch 1: As per Vitaly's suggestion, wrapped the test code under an
   #ifdef and updated the Kconfig file, so that the test code
   will only be used when the config option is set to true.
   (default is false).

   Updated hyperv_vmbus header to contain new #ifdef with new
   new functions for the test code.

  Patch 2: Moved code from under sysfs to debugfs and wrapped it under
   the new ifdef.

   Updated MAINTAINERS file with new debugfs-hyperv file under
   the section for hyperv.

  Patch 3: Updated testing tool with new debugfs location.

Branden Bonaby (2):
  drivers: hv: vmbus: Introduce latency testing
  tools: hv: add vmbus testing tool

 Documentation/ABI/testing/debugfs-hyperv |  23 ++
 MAINTAINERS  |   1 +
 drivers/hv/Kconfig   |   7 +
 drivers/hv/Makefile  |   1 +
 drivers/hv/connection.c  |   1 +
 drivers/hv/hv_debugfs.c  | 187 +++
 drivers/hv/hyperv_vmbus.h|  31 ++
 drivers/hv/ring_buffer.c |   2 +
 drivers/hv/vmbus_drv.c   |   6 +
 include/linux/hyperv.h   |  19 ++
 tools/hv/vmbus_testing   | 376 +++
 11 files changed, 654 insertions(+)
 create mode 100644 Documentation/ABI/testing/debugfs-hyperv
 create mode 100644 drivers/hv/hv_debugfs.c
 create mode 100644 tools/hv/vmbus_testing

-- 
2.17.1



[PATCH v4 2/2] tools: hv: add vmbus testing tool

2019-08-28 Thread Branden Bonaby
This is a userspace tool to drive the testing. Currently it supports
introducing user specified delay in the host to guest communication
path on a per-channel basis.

Signed-off-by: Branden Bonaby 
---
Changes in v4:
- Based on Harrys comments, made the tool more
  user friendly and added more error checking.

Changes in v3:
- Align python tool to match Linux coding style.

Changes in v2:
 - Move testing location to new location in debugfs.
 
 tools/hv/vmbus_testing | 376 +
 1 file changed, 376 insertions(+)
 create mode 100644 tools/hv/vmbus_testing

diff --git a/tools/hv/vmbus_testing b/tools/hv/vmbus_testing
new file mode 100644
index ..e7212903dd1d
--- /dev/null
+++ b/tools/hv/vmbus_testing
@@ -0,0 +1,376 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+#
+# Program to allow users to fuzz test Hyper-V drivers
+# by interfacing with Hyper-V debugfs attributes.
+# Current test methods available:
+#   1. delay testing
+#
+# Current file/directory structure of hyper-V debugfs:
+#   /sys/kernel/debug/hyperv/UUID
+#   /sys/kernel/debug/hyperv/UUID/
+#   /sys/kernel/debug/hyperv/UUID/
+#
+# author: Branden Bonaby 
+
+import os
+import cmd
+import argparse
+import glob
+from argparse import RawDescriptionHelpFormatter
+from argparse import RawTextHelpFormatter
+from enum import Enum
+
+# Do not change unless, you change the debugfs attributes
+# in /drivers/hv/debugfs.c. All fuzz testing
+# attributes will start with "fuzz_test".
+
+# debugfs path for hyperv must exist before proceeding
+debugfs_hyperv_path = "/sys/kernel/debug/hyperv"
+if not os.path.isdir(debugfs_hyperv_path):
+print("{} doesn't exist/check permissions".format(debugfs_hyperv_path))
+exit(-1)
+
+class dev_state(Enum):
+off = 0
+on = 1
+
+# File names, that correspond to the files created in
+# /drivers/hv/debugfs.c
+class f_names(Enum):
+state_f = "fuzz_test_state"
+buff_f =  "fuzz_test_buffer_interrupt_delay"
+mess_f =  "fuzz_test_message_delay"
+
+# Both single_actions and all_actions are used
+# for error checking and to allow for some subparser
+# names to be abbreviated. Do not abbreviate the
+# test method names, as it will become less intuitive
+# as to what the user can do. If you do decide to
+# abbreviate the test method name, make sure the main
+# function reflects this change.
+
+all_actions = [
+"disable_all",
+"D",
+"enable_all",
+"view_all",
+"V"
+]
+
+single_actions = [
+"disable_single",
+"d",
+"enable_single",
+"view_single",
+"v"
+]
+
+def main():
+
+file_map = recursive_file_lookup(debugfs_hyperv_path, dict())
+args = parse_args()
+if (not args.action):
+print ("Error, no options selected...exiting")
+exit(-1)
+arg_set = { k for (k,v) in vars(args).items() if v and k != "action" }
+arg_set.add(args.action)
+path = args.path if "path" in arg_set else None
+if (path and path[-1] == "/"):
+path = path[:-1]
+validate_args_path(path, arg_set, file_map)
+if (path and "enable_single" in arg_set):
+state_path = locate_state(path, file_map)
+set_test_state(state_path, dev_state.on.value, args.quiet)
+
+# Use subparsers as the key for different actions
+if ("delay" in arg_set):
+validate_delay_values(args.delay_time)
+if (args.enable_all):
+set_delay_all_devices(file_map, args.delay_time,
+  args.quiet)
+else:
+set_delay_values(path, file_map, args.delay_time,
+ args.quiet)
+elif ("disable_all" in arg_set or "D" in arg_set):
+disable_all_testing(file_map)
+elif ("disable_single" in arg_set or "d" in arg_set):
+disable_testing_single_device(path, file_map)
+elif ("view_all" in arg_set or "V" in arg_set):
+get_all_devices_test_status(file_map)
+elif ("view_single" in arg_set or  "v" in arg_set):
+get_device_test_values(path, file_map)
+
+# Get the state location
+def locate_state(device, file_map):
+return file_map[device][f_names.state_f.value]
+
+# Validate delay values to make sure they are acceptable to
+# enable delays on a device
+def validate_delay_values(delay):
+
+if (delay[0]  == -1 and delay[1] == -1):
+print("\nError, At least 1 value must be greater than 0")
+exit(-1)
+for i in delay:
+if (i < -1 or i == 0 or i > 1000):
+print("\nError, Values must be  equal to -1 "
+  "or be > 0 and <= 1000")
+exit(-1)
+
+# Validate argument path

[ANN] Squashfs tools 4.4 released

2019-08-28 Thread Phillip Lougher
Hi,

I'm pleased to announce the release of Squashfs tools 4.4.
This is the first release in over 5 years, and there are
substantial improvements: reproducible builds, new compressors,
CVE fixes, security hardening and new options for
Mksquashfs/Unsquashfs.

The new release can be downloaded here:
http://sourceforge.net/projects/squashfs/files/latest/download?source=files

Summary of changes in Squashfs tools 4.4


1. Mksquashfs now generates reproducible images by default.  Mkfs time and
   file timestamps can also be specified.

2. Support for the Zstandard (ZSTD) compression algorithm has been added.

3. Pseudo files now support symbolic links.

4. CVE-2015-4645 and CVE-2015-4646 have been fixed.

5. Unsquashfs has been further hardened against corrupted filestems.

6. Unsquashfs is now more strict about error handling.

7. Miscellaneous new options and major bug fixes for Mksquashfs.

8. Miscellaneous new options and major bug fixes for Unsquashfs.

9. Squashfs-tools 4.4 is compatible with all earlier 4.x filesystems
   and releases.


1. Introducing reproducible builds
--

Ever since Mksquashfs was parallelised back in 2006, there
has been a certain randomness in how fragments and multi-block
files are ordered in the output filesystem even if the input
remains the same.

This is because the multiple parallel threads can be scheduled
differently between Mksquashfs runs.  For example, the thread
given fragment 10 to compress may finish before the thread
given fragment 9 to compress on one run (writing fragment 10
to the output filesystem before fragment 9), but, on the next
run it could be vice-versa.  There are many different scheduling
scenarios here, all of which can have a knock on effect causing
different scheduling and ordering later in the filesystem too.

Mkquashfs doesn't care about the ordering of fragments and
multi-block files within the filesystem, as this does not
affect the correctness of the filesystem.

In fact not caring about the ordering, as it doesn't matter, allows
Mksquashfs to run as fast as possible, maximising CPU and I/O
performance.

But, in the last couple of years, Squashfs has become used in
scenarios (cloud etc) where this randomness is causing problems.
Specifically this appears to be where downloaders, installers etc.
try to work out the differences between Squashfs filesystem
updates to minimise the amount of data that needs to transferred
to update an image.

Additionally, in the last couple of years has arisen the notion
of reproducible builds, that is the same source and build
environment etc should be able to (re-)generate identical
output.  This is usually for verification and security, allowing
binaries/distributions to be checked for malicious activity.
See https://reproducible-builds.org/ for more information.

Mksquashfs now generates reproducible images by default.
Images generated by Mksquashfs will be ordered identically to
previous runs if the same input has been supplied, and the
same options used.

1.1.1 Dealing with timestamps

Timestamps embedded in the filesystem will stiil cause differences.
Each new run of Mksquashfs will produce a different mkfs (make filesystem)
timestamp in the super-block.  Moreover if any file timestamps have changed
(even if the content hasn't), this will produce a difference.

To prevent timestamps from producing differences, the following
new Mksquashfs options have been added.

1.1.2 -mkfs-time 

This option takes a positive time value (which is the number
of seconds since the epoch of 1970-01-01 00:00:00 UTC), and sets
the file system timestamp to that.

Squashfs uses an unsigned 32-bit integer to store time, and the
time given should be in that range.

Obviously you can use the date command to convert dates into
this value, i.e.

% mksquashfs source source.sqsh -mkfs-time $(date +%s -d "Jan 1 2019 19:00")

1.1.3 -all-time 

This option takes a positive time value (which is the number
of seconds since the epoch of 1970-01-01 00:00:00 UTC), and sets
the timestamp on all files to that (but not the mkfs time).

1.1.4 environment variable SOURCE_DATE_EPOCH

As an alternative to the above command line options, you can
set the environment variable SOURCE_DATE_EPOCH to a time value.

This value will be used to set the mkfs time.  Also any
file timestamps which are after SOURCE_DATE_EPOCH will be
clamped to SOURCE_DATE_EPOCH.

See https://reproducible-builds.org/docs/source-date-epoch/
for more information.

Note: both SOURCE_DATE_EPOCH and the command line options cannot
be used at the same time.  They are different ways to do the same thing,
and both have FORCE sematics which mean they can't be over-ridden
elsewhere (otherwise it would defeat the purpose).

1.1.5 -not-reproducible

This option tells Mksquashfs that the files do not have to be
strictly ordered.  This will make Mksquashfs behave like version 4.3.


2. Zstandard (ZSTD) compression added

[PATCH V2 1/1] spi: bcm-qspi: Make BSPI default mode

2019-08-28 Thread Rayagonda Kokatanur
The spi-nor controller defaults to BSPI mode, hence switch back
to its default mode after MSPI operations (write or erase)
are completed.

Changes from V1:
 - Address code review comment from Mark Brown.

Signed-off-by: Rayagonda Kokatanur 
Reviewed-by: Mark Brown 
Reviewed-by: Kamal Dasu 
---
 drivers/spi/spi-bcm-qspi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c
index 902bdbf..46a811a 100644
--- a/drivers/spi/spi-bcm-qspi.c
+++ b/drivers/spi/spi-bcm-qspi.c
@@ -897,6 +897,7 @@ static int bcm_qspi_transfer_one(struct spi_master *master,
 
read_from_hw(qspi, slots);
}
+   bcm_qspi_enable_bspi(qspi);
 
return 0;
 }
-- 
1.9.1



[GIT PULL] vfs: Add support for timestamp limits

2019-08-28 Thread Deepa Dinamani
Hi Al, Arnd,

This is a pull request for filling in min and max timestamps for filesystems.
I've added all the acks, and dropped the adfs patch. That will be merged through
Russell's tree.

Thanks,
Deepa

The following changes since commit 5d18cb62218608a1388858880ad3ec76d6cb0d3b:

  Add linux-next specific files for 20190828 (2019-08-28 19:59:14 +1000)

are available in the Git repository at:

  https://github.com/deepa-hub/vfs limits

for you to fetch changes up to f0f216afa4c7e4dee9121fde52ccf57f76119188:

  isofs: Initialize filesystem timestamp ranges (2019-08-28 19:19:36 -0700)


Deepa Dinamani (19):
  vfs: Add file timestamp range support
  vfs: Add timestamp_truncate() api
  timestamp_truncate: Replace users of timespec64_trunc
  mount: Add mount warning for impending timestamp expiry
  utimes: Clamp the timestamps before update
  fs: Fill in max and min timestamps in superblock
  9p: Fill min and max timestamps in sb
  ext4: Initialize timestamps limits
  fs: nfs: Initialize filesystem timestamp ranges
  fs: cifs: Initialize filesystem timestamp ranges
  fs: fat: Initialize filesystem timestamp ranges
  fs: affs: Initialize filesystem timestamp ranges
  fs: sysv: Initialize filesystem timestamp ranges
  fs: ceph: Initialize filesystem timestamp ranges
  fs: orangefs: Initialize filesystem timestamp ranges
  fs: hpfs: Initialize filesystem timestamp ranges
  fs: omfs: Initialize filesystem timestamp ranges
  pstore: fs superblock limits
  isofs: Initialize filesystem timestamp ranges

 fs/9p/vfs_super.c|  6 +-
 fs/affs/amigaffs.c   |  2 +-
 fs/affs/amigaffs.h   |  3 +++
 fs/affs/inode.c  |  4 ++--
 fs/affs/super.c  |  4 
 fs/attr.c| 21 -
 fs/befs/linuxvfs.c   |  2 ++
 fs/bfs/inode.c   |  2 ++
 fs/ceph/super.c  |  2 ++
 fs/cifs/cifsfs.c | 22 ++
 fs/cifs/netmisc.c| 14 +++---
 fs/coda/inode.c  |  3 +++
 fs/configfs/inode.c  | 12 ++--
 fs/cramfs/inode.c|  2 ++
 fs/efs/super.c   |  2 ++
 fs/ext2/super.c  |  2 ++
 fs/ext4/ext4.h   | 10 +-
 fs/ext4/super.c  | 17 +++--
 fs/f2fs/file.c   | 21 -
 fs/fat/inode.c   | 12 
 fs/freevxfs/vxfs_super.c |  2 ++
 fs/hpfs/hpfs_fn.h|  6 ++
 fs/hpfs/super.c  |  2 ++
 fs/inode.c   | 33 -
 fs/isofs/inode.c |  7 +++
 fs/jffs2/fs.c|  3 +++
 fs/jfs/super.c   |  2 ++
 fs/kernfs/inode.c|  7 +++
 fs/minix/inode.c |  2 ++
 fs/namespace.c   | 33 -
 fs/nfs/super.c   | 20 +++-
 fs/ntfs/inode.c  | 21 -
 fs/omfs/inode.c  |  4 
 fs/orangefs/super.c  |  2 ++
 fs/pstore/ram.c  |  2 ++
 fs/qnx4/inode.c  |  2 ++
 fs/qnx6/inode.c  |  2 ++
 fs/reiserfs/super.c  |  3 +++
 fs/romfs/super.c |  2 ++
 fs/squashfs/super.c  |  2 ++
 fs/super.c   |  2 ++
 fs/sysv/super.c  |  5 -
 fs/ubifs/file.c  | 21 -
 fs/ufs/super.c   |  7 +++
 fs/utimes.c  |  6 ++
 fs/xfs/xfs_super.c   |  2 ++
 include/linux/fs.h   |  5 +
 include/linux/time64.h   |  2 ++
 48 files changed, 298 insertions(+), 72 deletions(-)


Re: [PATCH][cifs-next] cifs: ensure variable rc is initialized at the after_open label

2019-08-28 Thread ronnie sahlberg
On Thu, Aug 29, 2019 at 2:00 PM Steve French  wrote:
>
> Merged into cifs-2.6.git for-next
>
> Ronnie,
> You ok with merging this as a distinct patch?

Sure thing.
Thanks for the fix Colin.


>
> On Wed, Aug 28, 2019 at 7:02 PM Colin King  wrote:
> >
> > From: Colin Ian King 
> >
> > A previous fix added a jump to after_open which now leaves variable
> > rc in a uninitialized state. A couple of the cases in the following
> > switch statement do not set variable rc, hence the error check on rc
> > at the end of the switch statement is reading a garbage value in rc
> > for those specific cases. Fix this by initializing rc to zero before
> > the switch statement.
> >
> > Fixes: 955a9c5b39379 ("cifs: create a helper to find a writeable handle by 
> > path name")
> > Addresses-Coverity: ("Uninitialized scalar variable")
> > Signed-off-by: Colin Ian King 
> > ---
> >  fs/cifs/smb2inode.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
> > index 70342bcd89b4..939fc7b2234c 100644
> > --- a/fs/cifs/smb2inode.c
> > +++ b/fs/cifs/smb2inode.c
> > @@ -116,6 +116,7 @@ smb2_compound_op(const unsigned int xid, struct 
> > cifs_tcon *tcon,
> > smb2_set_next_command(tcon, [num_rqst]);
> >   after_open:
> > num_rqst++;
> > +   rc = 0;
> >
> > /* Operation */
> > switch (command) {
> > --
> > 2.20.1
> >
>
>
> --
> Thanks,
>
> Steve


Re: linux-next: build warning after merge of the block tree

2019-08-28 Thread Stephen Rothwell
Hi all,

On Thu, 29 Aug 2019 13:51:50 +1000 Stephen Rothwell  
wrote:
>
> After merging the block tree, today's linux-next build (x86_64
> allmodconfig) produced this warning:
> 
> In file included from include/trace/events/iocost.h:8,
>  from :
> include/trace/events/iocost.h:12:57: warning: 'struct ioc_now' declared 
> inside parameter list will not be visible outside of this definition or 
> declaration
>   TP_PROTO(struct ioc_gq *iocg, const char *path, struct ioc_now *now,
>  ^~~
> include/linux/tracepoint.h:233:34: note: in definition of macro 
> '__DECLARE_TRACE'
>   static inline void trace_##name(proto)\
>   ^
> include/linux/tracepoint.h:396:24: note: in expansion of macro 'PARAMS'
>   __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args),  \
> ^~
> include/linux/tracepoint.h:532:2: note: in expansion of macro 'DECLARE_TRACE'
>   DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
>   ^
> include/linux/tracepoint.h:532:22: note: in expansion of macro 'PARAMS'
>   DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
>   ^~
> include/trace/events/iocost.h:10:1: note: in expansion of macro 'TRACE_EVENT'
>  TRACE_EVENT(iocost_iocg_activate,
>  ^~~
> include/trace/events/iocost.h:12:2: note: in expansion of macro 'TP_PROTO'
>   TP_PROTO(struct ioc_gq *iocg, const char *path, struct ioc_now *now,
>   ^~~~
> include/trace/events/iocost.h:12:18: warning: 'struct ioc_gq' declared inside 
> parameter list will not be visible outside of this definition or declaration
>   TP_PROTO(struct ioc_gq *iocg, const char *path, struct ioc_now *now,
>   ^~
> include/linux/tracepoint.h:233:34: note: in definition of macro 
> '__DECLARE_TRACE'
>   static inline void trace_##name(proto)\
>   ^
> include/linux/tracepoint.h:396:24: note: in expansion of macro 'PARAMS'
>   __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args),  \
> ^~
> include/linux/tracepoint.h:532:2: note: in expansion of macro 'DECLARE_TRACE'
>   DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
>   ^
> include/linux/tracepoint.h:532:22: note: in expansion of macro 'PARAMS'
>   DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
>   ^~
> include/trace/events/iocost.h:10:1: note: in expansion of macro 'TRACE_EVENT'
>  TRACE_EVENT(iocost_iocg_activate,
>  ^~~
> include/trace/events/iocost.h:12:2: note: in expansion of macro 'TP_PROTO'
>   TP_PROTO(struct ioc_gq *iocg, const char *path, struct ioc_now *now,
>   ^~~~
> 
> (and many more)
> 
> Introduced by commit
> 
>   7caa47151ab2 ("blkcg: implement blk-iocost")
> 
> To get these warnings you need to build with CONFIG_HEADER_TEST and
> CONFIG_KERNEL_HEADER_TEST (and maybe CONFIG_UAPI_HEADER_TEST).
> allmodconfig does that.

I have applied this patch to linux-next for today:

From: Stephen Rothwell 
Date: Thu, 29 Aug 2019 14:03:43 +1000
Subject: [PATCH] blkcg: blk-iocost: predeclare used structs

Signed-off-by: Stephen Rothwell 
---
 include/trace/events/iocost.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/include/trace/events/iocost.h b/include/trace/events/iocost.h
index ec2217dd57ac..7ecaa65b7106 100644
--- a/include/trace/events/iocost.h
+++ b/include/trace/events/iocost.h
@@ -2,6 +2,10 @@
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM iocost
 
+struct ioc;
+struct ioc_now;
+struct ioc_gq;
+
 #if !defined(_TRACE_BLK_IOCOST_H) || defined(TRACE_HEADER_MULTI_READ)
 #define _TRACE_BLK_IOCOST_H
 
-- 
2.20.1

-- 
Cheers,
Stephen Rothwell


pgpuYwLi6AgZB.pgp
Description: OpenPGP digital signature


Re: [PATCH][cifs-next] cifs: ensure variable rc is initialized at the after_open label

2019-08-28 Thread Steve French
Merged into cifs-2.6.git for-next

Ronnie,
You ok with merging this as a distinct patch?

On Wed, Aug 28, 2019 at 7:02 PM Colin King  wrote:
>
> From: Colin Ian King 
>
> A previous fix added a jump to after_open which now leaves variable
> rc in a uninitialized state. A couple of the cases in the following
> switch statement do not set variable rc, hence the error check on rc
> at the end of the switch statement is reading a garbage value in rc
> for those specific cases. Fix this by initializing rc to zero before
> the switch statement.
>
> Fixes: 955a9c5b39379 ("cifs: create a helper to find a writeable handle by 
> path name")
> Addresses-Coverity: ("Uninitialized scalar variable")
> Signed-off-by: Colin Ian King 
> ---
>  fs/cifs/smb2inode.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
> index 70342bcd89b4..939fc7b2234c 100644
> --- a/fs/cifs/smb2inode.c
> +++ b/fs/cifs/smb2inode.c
> @@ -116,6 +116,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon 
> *tcon,
> smb2_set_next_command(tcon, [num_rqst]);
>   after_open:
> num_rqst++;
> +   rc = 0;
>
> /* Operation */
> switch (command) {
> --
> 2.20.1
>


-- 
Thanks,

Steve


BUG: corrupted list in p9_fd_cancelled (2)

2019-08-28 Thread syzbot

Hello,

syzbot found the following crash on:

HEAD commit:36146921 Merge tag 'hyperv-fixes-signed' of git://git.kern..
git tree:   upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=169f691e60
kernel config:  https://syzkaller.appspot.com/x/.config?x=6919752cc1b760b4
dashboard link: https://syzkaller.appspot.com/bug?extid=1d26c4ed77bc6c5ed5e6
compiler:   gcc (GCC) 9.0.0 20181231 (experimental)
syz repro:  https://syzkaller.appspot.com/x/repro.syz?x=14d03ba660

IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+1d26c4ed77bc6c5ed...@syzkaller.appspotmail.com

list_del corruption, 88808ecdbfb0->next is LIST_POISON1  
(dead0100)

[ cut here ]
kernel BUG at lib/list_debug.c:45!
invalid opcode:  [#1] PREEMPT SMP KASAN
CPU: 0 PID: 20174 Comm: syz-executor.1 Not tainted 5.3.0-rc5+ #125
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS  
Google 01/01/2011

RIP: 0010:__list_del_entry_valid.cold+0x23/0x4f lib/list_debug.c:45
Code: e8 d5 06 1e fe 0f 0b 4c 89 f6 48 c7 c7 e0 26 c6 87 e8 c4 06 1e fe 0f  
0b 4c 89 ea 4c 89 f6 48 c7 c7 20 26 c6 87 e8 b0 06 1e fe <0f> 0b 4c 89 e2  
4c 89 f6 48 c7 c7 80 26 c6 87 e8 9c 06 1e fe 0f 0b

RSP: 0018:8880994076d8 EFLAGS: 00010286
RAX: 004e RBX: 111013280ee9 RCX: 
RDX:  RSI: 815c2526 RDI: ed1013280ecd
RBP: 8880994076f0 R08: 004e R09: ed1015d060d1
R10: ed1015d060d0 R11: 8880ae830687 R12: dead0122
R13: dead0100 R14: 88808ecdbfb0 R15: 88808ecdbfb8
FS:  7fb2aca54700() GS:8880ae80() knlGS:
CS:  0010 DS:  ES:  CR0: 80050033
CR2: 7ffee6574f58 CR3: a8e6d000 CR4: 001406f0
DR0:  DR1:  DR2: 
DR3:  DR6: fffe0ff0 DR7: 0400
Call Trace:
 __list_del_entry include/linux/list.h:131 [inline]
 list_del include/linux/list.h:139 [inline]
 p9_fd_cancelled+0x3c/0x1c0 net/9p/trans_fd.c:710
 p9_client_flush+0x1b7/0x1f0 net/9p/client.c:674
 p9_client_rpc+0x112f/0x12a0 net/9p/client.c:781
 p9_client_version net/9p/client.c:952 [inline]
 p9_client_create+0xb7f/0x1430 net/9p/client.c:1052
 v9fs_session_init+0x1e7/0x18c0 fs/9p/v9fs.c:406
 v9fs_mount+0x7d/0x920 fs/9p/vfs_super.c:120
 legacy_get_tree+0x108/0x220 fs/fs_context.c:661
 vfs_get_tree+0x8e/0x390 fs/super.c:1413
 do_new_mount fs/namespace.c:2791 [inline]
 do_mount+0x13b3/0x1c30 fs/namespace.c:3111
 ksys_mount+0xdb/0x150 fs/namespace.c:3320
 __do_sys_mount fs/namespace.c:3334 [inline]
 __se_sys_mount fs/namespace.c:3331 [inline]
 __x64_sys_mount+0xbe/0x150 fs/namespace.c:3331
 do_syscall_64+0xfd/0x6a0 arch/x86/entry/common.c:296
 entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x459879
Code: fd b7 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7  
48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff  
ff 0f 83 cb b7 fb ff c3 66 2e 0f 1f 84 00 00 00 00

RSP: 002b:7fb2aca53c78 EFLAGS: 0246 ORIG_RAX: 00a5
RAX: ffda RBX: 0005 RCX: 00459879
RDX: 22c0 RSI: 2040 RDI: 
RBP: 0075bfc8 R08: 2400 R09: 
R10:  R11: 0246 R12: 7fb2aca546d4
R13: 004c5e2f R14: 004da930 R15: 
Modules linked in:
---[ end trace c76f5f29f0af3347 ]---
RIP: 0010:__list_del_entry_valid.cold+0x23/0x4f lib/list_debug.c:45
Code: e8 d5 06 1e fe 0f 0b 4c 89 f6 48 c7 c7 e0 26 c6 87 e8 c4 06 1e fe 0f  
0b 4c 89 ea 4c 89 f6 48 c7 c7 20 26 c6 87 e8 b0 06 1e fe <0f> 0b 4c 89 e2  
4c 89 f6 48 c7 c7 80 26 c6 87 e8 9c 06 1e fe 0f 0b

RSP: 0018:8880994076d8 EFLAGS: 00010286
RAX: 004e RBX: 111013280ee9 RCX: 
RDX:  RSI: 815c2526 RDI: ed1013280ecd
RBP: 8880994076f0 R08: 004e R09: ed1015d060d1
R10: ed1015d060d0 R11: 8880ae830687 R12: dead0122
R13: dead0100 R14: 88808ecdbfb0 R15: 88808ecdbfb8
FS:  7fb2aca54700() GS:8880ae80() knlGS:
CS:  0010 DS:  ES:  CR0: 80050033
CR2: 7ffee6574f58 CR3: a8e6d000 CR4: 001406f0
DR0:  DR1:  DR2: 
DR3:  DR6: fffe0ff0 DR7: 0400


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

syzbot will keep track of this bug report. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
syzbot can test patches for this bug, for details see:
https://goo.gl/tpsmEJ#testing-patches


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

2019-08-28 Thread Stephen Rothwell
Hi all,

After merging the regulator tree, today's linux-next build (x86_64
allmodconfig) failed like this:

drivers/regulator/mt6358-regulator.c:5:10: fatal error: 
linux/mfd/mt6358/registers.h: No such file or directory
 #include 
  ^~

Caused by commit

  f67ff1bd58f0 ("regulator: mt6358: Add support for MT6358 regulator")

I have reverted that commit for today.

-- 
Cheers,
Stephen Rothwell


pgp9FNuSWoypW.pgp
Description: OpenPGP digital signature


Re: [PATCH v2 15/15] drivers: thermal: tsens: Add interrupt support

2019-08-28 Thread Thara Gopinath
Hi Amit,

On 08/27/2019 08:14 AM, Amit Kucheria wrote:
> Depending on the IP version, TSENS supports upper, lower, max, min and
> critical threshold interrupts. We only add support for upper and lower
> threshold interrupts for now.
> 
> TSENSv2 has an irq [status|clear|mask] bit tuple for each sensor while
> earlier versions only have a single bit per sensor to denote status and
> clear. At each interrupt, we reprogram the new upper and lower threshold
> in the .set_trip callback.
> 
> Signed-off-by: Amit Kucheria 
> ---
>  drivers/thermal/qcom/tsens-common.c | 377 ++--
>  drivers/thermal/qcom/tsens-v0_1.c   |  11 +
>  drivers/thermal/qcom/tsens-v1.c |  29 +++
>  drivers/thermal/qcom/tsens-v2.c |  13 +
>  drivers/thermal/qcom/tsens.c|  32 ++-
>  drivers/thermal/qcom/tsens.h| 270 
>  6 files changed, 669 insertions(+), 63 deletions(-)
> 
> diff --git a/drivers/thermal/qcom/tsens-common.c 
> b/drivers/thermal/qcom/tsens-common.c
> index 06b44cfd5eab9..c549f8e1488ba 100644
> --- a/drivers/thermal/qcom/tsens-common.c
> +++ b/drivers/thermal/qcom/tsens-common.c
> @@ -13,6 +13,30 @@
>  #include 
>  #include "tsens.h"
>  
> +/** struct tsens_irq_data - IRQ status and temperature violations
> + * @up_viol:upper threshold violated
> + * @up_thresh:  upper threshold temperature value
> + * @up_irq_mask:mask register for upper threshold irqs
> + * @up_irq_clear:   clear register for uppper threshold irqs
> + * @low_viol:   lower threshold violated
> + * @low_thresh: lower threshold temperature value
> + * @low_irq_mask:   mask register for lower threshold irqs
> + * @low_irq_clear:  clear register for lower threshold irqs
> + *
> + * Structure containing data about temperature threshold settings and
> + * irq status if they were violated.
> + */
> +struct tsens_irq_data {
> + u32 up_viol;
> + int up_thresh;
> + u32 up_irq_mask;
> + u32 up_irq_clear;
> + u32 low_viol;
> + int low_thresh;
> + u32 low_irq_mask;
> + u32 low_irq_clear;
> +};
> +
>  char *qfprom_read(struct device *dev, const char *cname)
>  {
>   struct nvmem_cell *cell;
> @@ -65,6 +89,14 @@ void compute_intercept_slope(struct tsens_priv *priv, u32 
> *p1,
>   }
>  }
>  
> +static inline u32 degc_to_code(int degc, const struct tsens_sensor *sensor)
> +{
> + u64 code = (degc * sensor->slope + sensor->offset) / SLOPE_FACTOR;
> +
> + pr_debug("%s: raw_code: 0x%llx, degc:%d\n", __func__, code, degc);
> + return clamp_val(code, THRESHOLD_MIN_ADC_CODE, THRESHOLD_MAX_ADC_CODE);
> +}
> +
>  static inline int code_to_degc(u32 adc_code, const struct tsens_sensor *s)
>  {
>   int degc, num, den;
> @@ -114,6 +146,314 @@ static int tsens_hw_to_mC(struct tsens_sensor *s, int 
> field)
>   return sign_extend32(temp, priv->tempres) * 100;
>  }
>  
> +/**
> + * tsens_mC_to_hw - Return correct value to be written to threshold
> + * registers, whether in ADC code or deciCelsius depending on IP version
> + */
> +static int tsens_mC_to_hw(struct tsens_sensor *s, int temp)
> +{
> + struct tsens_priv *priv = s->priv;
> +
> + if (priv->feat->adc) {
> + /* milliC to C to adc code */
> + return degc_to_code(temp / 1000, s);
> + }
> +
> + /* milliC to deciC */
> + return temp / 100;
> +}
> +
> +static inline unsigned int tsens_ver(struct tsens_priv *priv)
> +{
> + return priv->feat->ver_major;
> +}
> +
> +/**
> + * tsens_set_interrupt_v1 - Disable an interrupt (enable = false)
> + *  Re-enable an interrupt (enable = true)
> + */
> +static void tsens_set_interrupt_v1(struct tsens_priv *priv, u32 hw_id,
> +enum tsens_irq_type irq_type, bool enable)
> +{
> + u32 index;
> +
> + if (enable) {
> + switch (irq_type) {
> + case UPPER:
> + index = UP_INT_CLEAR_0 + hw_id;
> + break;
> + case LOWER:
> + index = LOW_INT_CLEAR_0 + hw_id;
> + break;
> + }
> + regmap_field_write(priv->rf[index], 0);
> + } else {
> + switch (irq_type) {
> + case UPPER:
> + index = UP_INT_CLEAR_0 + hw_id;
> + break;
> + case LOWER:
> + index = LOW_INT_CLEAR_0 + hw_id;
> + break;
> + }
> + regmap_field_write(priv->rf[index], 1);
> + }
> +}
> +
> +/**
> + * tsens_set_interrupt_v2 - Disable an interrupt (enable = false)
> + *  Re-enable an interrupt (enable = true)
> + */
> +static void tsens_set_interrupt_v2(struct tsens_priv *priv, u32 hw_id,
> +enum tsens_irq_type irq_type, bool enable)
> +{
> + u32 index_mask, index_clear;
> +
> + if (enable) {
> + switch (irq_type) {
> + case UPPER:

[PATCH] mm: Remove NULL check in clear_hwpoisoned_pages()

2019-08-28 Thread Alastair D'Silva
There is no possibility for memmap to be NULL in the current
codebase.

This check was added in commit 95a4774d055c ("memory-hotplug:
update mce_bad_pages when removing the memory")
where memmap was originally inited to NULL, and only conditionally
given a value.

The code that could have passed a NULL has been removed, so there
is no longer a possibility that memmap can be NULL.

Signed-off-by: Alastair D'Silva 
---
 mm/sparse.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/mm/sparse.c b/mm/sparse.c
index 78979c142b7d..9f7e3682cdcb 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -754,9 +754,6 @@ static void clear_hwpoisoned_pages(struct page *memmap, int 
nr_pages)
 {
int i;
 
-   if (!memmap)
-   return;
-
/*
 * A further optimization is to have per section refcounted
 * num_poisoned_pages.  But that would need more space per memmap, so
-- 
2.21.0



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

2019-08-28 Thread Stephen Rothwell
Hi all,

After merging the block tree, today's linux-next build (x86_64
allmodconfig) produced this warning:

In file included from include/trace/events/iocost.h:8,
 from :
include/trace/events/iocost.h:12:57: warning: 'struct ioc_now' declared inside 
parameter list will not be visible outside of this definition or declaration
  TP_PROTO(struct ioc_gq *iocg, const char *path, struct ioc_now *now,
 ^~~
include/linux/tracepoint.h:233:34: note: in definition of macro 
'__DECLARE_TRACE'
  static inline void trace_##name(proto)\
  ^
include/linux/tracepoint.h:396:24: note: in expansion of macro 'PARAMS'
  __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args),  \
^~
include/linux/tracepoint.h:532:2: note: in expansion of macro 'DECLARE_TRACE'
  DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
  ^
include/linux/tracepoint.h:532:22: note: in expansion of macro 'PARAMS'
  DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
  ^~
include/trace/events/iocost.h:10:1: note: in expansion of macro 'TRACE_EVENT'
 TRACE_EVENT(iocost_iocg_activate,
 ^~~
include/trace/events/iocost.h:12:2: note: in expansion of macro 'TP_PROTO'
  TP_PROTO(struct ioc_gq *iocg, const char *path, struct ioc_now *now,
  ^~~~
include/trace/events/iocost.h:12:18: warning: 'struct ioc_gq' declared inside 
parameter list will not be visible outside of this definition or declaration
  TP_PROTO(struct ioc_gq *iocg, const char *path, struct ioc_now *now,
  ^~
include/linux/tracepoint.h:233:34: note: in definition of macro 
'__DECLARE_TRACE'
  static inline void trace_##name(proto)\
  ^
include/linux/tracepoint.h:396:24: note: in expansion of macro 'PARAMS'
  __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args),  \
^~
include/linux/tracepoint.h:532:2: note: in expansion of macro 'DECLARE_TRACE'
  DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
  ^
include/linux/tracepoint.h:532:22: note: in expansion of macro 'PARAMS'
  DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
  ^~
include/trace/events/iocost.h:10:1: note: in expansion of macro 'TRACE_EVENT'
 TRACE_EVENT(iocost_iocg_activate,
 ^~~
include/trace/events/iocost.h:12:2: note: in expansion of macro 'TP_PROTO'
  TP_PROTO(struct ioc_gq *iocg, const char *path, struct ioc_now *now,
  ^~~~

(and many more)

Introduced by commit

  7caa47151ab2 ("blkcg: implement blk-iocost")

To get these warnings you need to build with CONFIG_HEADER_TEST and
CONFIG_KERNEL_HEADER_TEST (and maybe CONFIG_UAPI_HEADER_TEST).
allmodconfig does that.

-- 
Cheers,
Stephen Rothwell


pgp76eVUKGASg.pgp
Description: OpenPGP digital signature


Re: [PATCH] ima: use struct_size() in kzalloc()

2019-08-28 Thread Mimi Zohar
Hi Gustavo,

On Wed, 2019-08-28 at 13:29 -0500, Gustavo A. R. Silva wrote:
> On 5/29/19 11:53 AM, Gustavo A. R. Silva wrote:
> > One of the more common cases of allocation size calculations is finding
> > the size of a structure that has a zero-sized array at the end, along
> > with memory for some number of elements for that array. For example:
> > 
> > struct foo {
> >int stuff;
> >struct boo entry[];
> > };
> > 
> > instance = kzalloc(sizeof(struct foo) + count * sizeof(struct boo), 
> > GFP_KERNEL);
> > 
> > Instead of leaving these open-coded and prone to type mistakes, we can
> > now use the new struct_size() helper:
> > 
> > instance = kzalloc(struct_size(instance, entry, count), GFP_KERNEL);
> > 
> > This code was detected with the help of Coccinelle.
> > 
> > Signed-off-by: Gustavo A. R. Silva 
> > ---
> >  security/integrity/ima/ima_template.c | 5 ++---
> >  1 file changed, 2 insertions(+), 3 deletions(-)
> > 
> > diff --git a/security/integrity/ima/ima_template.c 
> > b/security/integrity/ima/ima_template.c
> > index b631b8bc7624..b945dff2ed14 100644
> > --- a/security/integrity/ima/ima_template.c
> > +++ b/security/integrity/ima/ima_template.c
> > @@ -281,9 +281,8 @@ static int ima_restore_template_data(struct 
> > ima_template_desc *template_desc,
> > int ret = 0;
> > int i;
> >  
> > -   *entry = kzalloc(sizeof(**entry) +
> > -   template_desc->num_fields * sizeof(struct ima_field_data),
> > -   GFP_NOFS);
> > +   *entry = kzalloc(struct_size(*entry, template_data,
> > +template_desc->num_fields), GFP_NOFS);
> > if (!*entry)
> > return -ENOMEM;
> >  
> > 

The same usage exists in ima_api.c: ima_alloc_init_template().  Did
you want to make the change there as well?

thanks,

Mimi



Re: [PATCH] usb: chipidea: msm: Use device-managed registration API

2019-08-28 Thread Peter Chen
On 19-08-28 19:42:32, Chuhong Yuan wrote:
> On Wed, Aug 28, 2019 at 11:24 AM Peter Chen  wrote:
> >
> > On 19-07-23 11:02:07, Chuhong Yuan wrote:
> > > Use devm_reset_controller_register to get rid
> > > of manual unregistration.
> > >
> > > Signed-off-by: Chuhong Yuan 
> > > ---
> > >  drivers/usb/chipidea/ci_hdrc_msm.c | 4 +---
> > >  1 file changed, 1 insertion(+), 3 deletions(-)
> > >
> > > diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c 
> > > b/drivers/usb/chipidea/ci_hdrc_msm.c
> > > index bb4645a8ca46..067542e84aea 100644
> > > --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> > > +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> > > @@ -216,7 +216,7 @@ static int ci_hdrc_msm_probe(struct platform_device 
> > > *pdev)
> > >   ci->rcdev.ops = _hdrc_msm_reset_ops;
> > >   ci->rcdev.of_node = pdev->dev.of_node;
> > >   ci->rcdev.nr_resets = 2;
> > > - ret = reset_controller_register(>rcdev);
> > > + ret = devm_reset_controller_register(>dev, >rcdev);
> > >   if (ret)
> > >   return ret;
> > >
> > > @@ -272,7 +272,6 @@ static int ci_hdrc_msm_probe(struct platform_device 
> > > *pdev)
> > >  err_iface:
> > >   clk_disable_unprepare(ci->core_clk);
> > >  err_fs:
> > > - reset_controller_unregister(>rcdev);
> >
> > It is devm API, why the unregister needs to be called at
> > fail path?
> >
> 
> I am not very clear about your problem...
> After using devm_reset_controller_register(), I have removed
> reset_controller_unregister() calls
> in this patch.
> 

Sorry, my fault.

Your patch is ok, but try to clean up the label "err_fs" since
it is not needed.

Peter

> > Peter
> >
> > >   return ret;
> > >  }
> > >
> > > @@ -284,7 +283,6 @@ static int ci_hdrc_msm_remove(struct platform_device 
> > > *pdev)
> > >   ci_hdrc_remove_device(ci->ci);
> > >   clk_disable_unprepare(ci->iface_clk);
> > >   clk_disable_unprepare(ci->core_clk);
> > > - reset_controller_unregister(>rcdev);
> > >
> > >   return 0;
> > >  }
> > > --
> > > 2.20.1
> > >

Re: [PATCH 00/10] OOM Debug print selection and additional information

2019-08-28 Thread Edward Chron
On Wed, Aug 28, 2019 at 1:04 PM Edward Chron  wrote:
>
> On Wed, Aug 28, 2019 at 3:12 AM Tetsuo Handa
>  wrote:
> >
> > On 2019/08/28 16:08, Michal Hocko wrote:
> > > On Tue 27-08-19 19:47:22, Edward Chron wrote:
> > >> For production systems installing and updating EBPF scripts may someday
> > >> be very common, but I wonder how data center managers feel about it now?
> > >> Developers are very excited about it and it is a very powerful tool but 
> > >> can I
> > >> get permission to add or replace an existing EBPF on production systems?
> > >
> > > I am not sure I understand. There must be somebody trusted to take care
> > > of systems, right?
> > >
> >
> > Speak of my cases, those who take care of their systems are not developers.
> > And they afraid changing code that runs in kernel mode. They unlikely give
> > permission to install SystemTap/eBPF scripts. As a result, in many cases,
> > the root cause cannot be identified.
>
> +1. Exactly. The only thing we could think of Tetsuo is if Linux OOM Reporting
> uses a an eBPF script then systems have to load them to get any kind of
> meaningful report. Frankly, if using eBPF is the route to go than essentially
> the whole OOM reporting should go there. We can adjust as we need and
> have precedent for wanting to load the script. That's the best we could come
> up with.
>
> >
> > Moreover, we are talking about OOM situations, where we can't expect 
> > userspace
> > processes to work properly. We need to dump information we want, without
> > counting on userspace processes, before sending SIGKILL.
>
> +1. We've tried and as you point out and for best results the kernel
> has to provide
>  the state.
>
> Again a full system dump would be wonderful, but taking a full dump for
> every OOM event on production systems? I am not nearly a good enough salesman
> to sell that one. So we need an alternate mechanism.
>
> If we can't agree on some sort of extensible, configurable approach then put
> the standard OOM Report in eBPF and make it mandatory to load it so we can
> justify having to do that. Linux should load it automatically.
> We'll just make a few changes and additions as needed.
>
> Sounds like a plan that we could live with.
> Would be interested if this works for others as well.

One further comment. In talking with my colleagues here who know eBPF
much better
than I do, it may not be possible to implement something this
complicated with eBPF.

If that is in the fact the case, then we'd have to try and hook the
OOM Reporting code
with tracepoints similar to kprobes only we want to do more than add counters
we want to change the flow to skip small output entries that aren't
worth printing.
If this isn't feasible with eBPF, then some derivative or our approach
or enhancing
the OOM output code directly seem like the best options. Will have to
investigate
this further.


Re: [RFC PATCH v2 00/19] RDMA/FS DAX truncate proposal V1,000,002 ;-)

2019-08-28 Thread John Hubbard

On 8/28/19 7:02 PM, Ira Weiny wrote:

On Mon, Aug 26, 2019 at 03:55:10PM +1000, Dave Chinner wrote:

On Fri, Aug 23, 2019 at 10:08:36PM -0700, Ira Weiny wrote:

On Sat, Aug 24, 2019 at 10:11:24AM +1000, Dave Chinner wrote:

On Fri, Aug 23, 2019 at 09:04:29AM -0300, Jason Gunthorpe wrote:

...


Sure, that part works because the struct file is passed. It doesn't
end up with the same fd number in the other process, though.

The issue is that layout leases need to notify userspace when they
are broken by the kernel, so a lease stores the owner pid/tid in the
file->f_owner field via __f_setown(). It also keeps a struct fasync
attached to the file_lock that records the fd that the lease was
created on.  When a signal needs to be sent to userspace for that
lease, we call kill_fasync() and that walks the list of fasync
structures on the lease and calls:

send_sigio(fown, fa->fa_fd, band);

And it does for every fasync struct attached to a lease. Yes, a
lease can track multiple fds, but it can only track them in a single
process context. The moment the struct file is shared with another
process, the lease is no longer capable of sending notifications to
all the lease holders.

Yes, you can change the owning process via F_SETOWNER, but that's
still only a single process context, and you can't change the fd in
the fasync list. You can add new fd to an existing lease by calling
F_SETLEASE on the new fd, but you still only have a single process
owner context for signal delivery.

As such, leases that require callbacks to userspace are currently
only valid within the process context the lease was taken in.


But for long term pins we are not requiring callbacks.



Hi Ira,

If "require callbacks to userspace" means sending SIGIO, then actually
FOLL_LONGTERM *does* require those callbacks. Because we've been, so
far, equating FOLL_LONGTERM with the vaddr_pin struct and with a lease.

What am I missing here?

thanks,
--
John Hubbard
NVIDIA


Re: [PATCH] usb: storage: Add ums-cros-aoa driver

2019-08-28 Thread Julius Werner
(Thanks for the reviews... I'll get back to the kernel code details
after double-checking if this can be done from userspace.)

> > Besides, what's wrong with binding to devices that weren't switched
> > into AOA mode?  Would that just provoke a bunch of unnecessary error
> > messages?

It's not about devices that aren't switched into AOA mode... it's
about devices that are switched into AOA mode for other reasons
(connecting to other Android apps). I don't think a kernel driver like
that exists today, but it could be added, or people could use libusb
to talk to an AOA device. AOA is just a general mechanism to talk to
an Android app for whatever you want, and the descriptors sent during
mode switch clarify what app it's talking to (and thereby what
protocol it is using... it could be mass storage or it could be
something entirely different). But a device switched into AOA mode for
whatever app will always use that same well-known VID/PID (18d1:2d00).
So if I just add that VID/PID to the IDs bound by the usb-storage
driver, it would also grab a device that was mode-switched by
userspace to talk to a completely different app. I need some way to
make sure it only grabs the intended device, and there's no good
identifier for that other than comparing the dev path to what you
originally mode switched.

> > > + /*
> > > +  * Only interface 0 connects to the AOA app. Android devices that 
> > > have
> > > +  * ADB enabled also export an interface 1. We don't want it.
> > > +  */
> > > + if (us->pusb_intf->cur_altsetting->desc.bInterfaceNumber != 0)
> > > + return -ENODEV;
> >
> > Do you really need this test?  What would go wrong if you don't do it?

Yes, otherwise two separate usb-storage instances bind to the two
interfaces. The second interface is meant for a special ADB debugging
protocol and will not respond at all to USB mass storage packets, so
eventually the first request to it times out and
usb_stor_invoke_transport() will do a port reset to recover. That also
kills the first interface asynchronously even though it was working
fine.

> > IMO the userspace approach would be better, unless you can provide a
> > really compelling argument for why it won't suffice.

Well... okay, let me think through that again. I just found the new_id
sysfs API that I wasn't aware of before, maybe I could leverage that
to bind this from userspace after doing the mode switch. But it looks
like that only operates on whole devices... is there any way to force
it to only bind one particular interface?


Re: [PATCH v2] fs/proc/page: Skip uninitialized page when iterating page structures

2019-08-28 Thread Toshiki Fukasawa
On 2019/08/28 23:18, Waiman Long wrote:
> On 8/28/19 10:09 AM, Michal Hocko wrote:
>> On Wed 28-08-19 09:46:21, Waiman Long wrote:
>>> On 8/28/19 4:00 AM, Michal Hocko wrote:
 On Tue 27-08-19 16:22:38, Michal Hocko wrote:
> Dan, isn't this something we have discussed recently?
 This was 
 http://lkml.kernel.org/r/20190725023100.31141-3-t-fukas...@vx.jp.nec.com
 and talked about /proc/kpageflags but this is essentially the same thing
 AFAIU. I hope we get a consistent solution for both issues.

>>> Yes, it is the same problem. The uninitialized page structure problem
>>> affects all the 3 /proc/kpage{cgroup,count,flags) files.
>>>
>>> Toshiki's patch seems to fix it just for /proc/kpageflags, though.
>> Yup. I was arguing that whacking a mole kinda fix is far from good. Dan
>> had some arguments on why initializing those struct pages is a problem.
>> The discussion had a half open end though. I hoped that Dan would try
>> out the initialization side but I migh have misunderstood.
> 
> If the page structures of the reserved PFNs are always initialized, that
> will fix the problem too. I am not familiar with the zone device code.
> So I didn't attempt to do that.
> 
> Cheers,
> Longman
> 
> 
I also think that the struct pages should be initialized.
I'm preparing to post the patch.

Toshiki Fukasawa


[PATCH netdev] net: stmmac: dwmac-rk: Don't fail if phy regulator is absent

2019-08-28 Thread Chen-Yu Tsai
From: Chen-Yu Tsai 

The devicetree binding lists the phy phy as optional. As such, the
driver should not bail out if it can't find a regulator. Instead it
should just skip the remaining regulator related code and continue
on normally.

Skip the remainder of phy_power_on() if a regulator supply isn't
available. This also gets rid of the bogus return code.

Fixes: 2e12f536635f ("net: stmmac: dwmac-rk: Use standard devicetree property 
for phy regulator")
Signed-off-by: Chen-Yu Tsai 
---

On a separate note, maybe we should add this file to the Rockchip
entry in MAINTAINERS?

---
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 4644b2aeeba1..e2e469c37a4d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -1194,10 +1194,8 @@ static int phy_power_on(struct rk_priv_data *bsp_priv, 
bool enable)
int ret;
struct device *dev = _priv->pdev->dev;
 
-   if (!ldo) {
-   dev_err(dev, "no regulator found\n");
-   return -1;
-   }
+   if (!ldo)
+   return 0;
 
if (enable) {
ret = regulator_enable(ldo);
-- 
2.20.1



[PATCH 1/1] sched/rt: avoid contend with CFS task

2019-08-28 Thread Jing-Ting Wu
At original linux design, RT & CFS scheduler are independent.
Current RT task placement policy will select the first cpu in
lowest_mask, even if the first CPU is running a CFS task.
This may put RT task to a running cpu and let CFS task runnable.

So we select idle cpu in lowest_mask first to avoid preempting
CFS task.

Signed-off-by: Jing-Ting Wu 
---
 kernel/sched/rt.c |   42 +-
 1 file changed, 17 insertions(+), 25 deletions(-)

diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index a532558..626ca27 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -1388,7 +1388,6 @@ static void yield_task_rt(struct rq *rq)
 static int
 select_task_rq_rt(struct task_struct *p, int cpu, int sd_flag, int flags)
 {
-   struct task_struct *curr;
struct rq *rq;
 
/* For anything but wake ups, just return the task_cpu */
@@ -1398,33 +1397,15 @@ static void yield_task_rt(struct rq *rq)
rq = cpu_rq(cpu);
 
rcu_read_lock();
-   curr = READ_ONCE(rq->curr); /* unlocked access */
 
/*
-* If the current task on @p's runqueue is an RT task, then
-* try to see if we can wake this RT task up on another
-* runqueue. Otherwise simply start this RT task
-* on its current runqueue.
-*
-* We want to avoid overloading runqueues. If the woken
-* task is a higher priority, then it will stay on this CPU
-* and the lower prio task should be moved to another CPU.
-* Even though this will probably make the lower prio task
-* lose its cache, we do not want to bounce a higher task
-* around just because it gave up its CPU, perhaps for a
-* lock?
-*
-* For equal prio tasks, we just let the scheduler sort it out.
-*
-* Otherwise, just let it ride on the affined RQ and the
-* post-schedule router will push the preempted task away
-*
-* This test is optimistic, if we get it wrong the load-balancer
-* will have to sort it out.
+* If the task p is allowed to put more than one CPU or
+* it is not allowed to put on this CPU.
+* Let p use find_lowest_rq to choose other idle CPU first,
+* instead of choose this cpu and preempt curr cfs task.
 */
-   if (curr && unlikely(rt_task(curr)) &&
-   (curr->nr_cpus_allowed < 2 ||
-curr->prio <= p->prio)) {
+   if ((p->nr_cpus_allowed > 1) ||
+   (!cpumask_test_cpu(cpu, p->cpus_ptr))) {
int target = find_lowest_rq(p);
 
/*
@@ -1648,6 +1629,7 @@ static int find_lowest_rq(struct task_struct *task)
struct cpumask *lowest_mask = this_cpu_cpumask_var_ptr(local_cpu_mask);
int this_cpu = smp_processor_id();
int cpu  = task_cpu(task);
+   int i;
 
/* Make sure the mask is initialized first */
if (unlikely(!lowest_mask))
@@ -1659,6 +1641,16 @@ static int find_lowest_rq(struct task_struct *task)
if (!cpupri_find(_rq(task)->rd->cpupri, task, lowest_mask))
return -1; /* No targets found */
 
+   /* Choose previous cpu if it is idle and it fits lowest_mask */
+   if (cpumask_test_cpu(cpu, lowest_mask) && idle_cpu(cpu))
+   return cpu;
+
+   /* Choose idle_cpu among lowest_mask */
+   for_each_cpu(i, lowest_mask) {
+   if (idle_cpu(i))
+   return i;
+   }
+
/*
 * At this point we have built a mask of CPUs representing the
 * lowest priority tasks in the system.  Now we want to elect
-- 
1.7.9.5



Re: [RESEND PATCH V3 3/8] perf/x86/intel: Support hardware TopDown metrics

2019-08-28 Thread Andi Kleen
On Wed, Aug 28, 2019 at 06:28:57PM +0200, Peter Zijlstra wrote:
> On Wed, Aug 28, 2019 at 09:17:54AM -0700, Andi Kleen wrote:
> > > This really doesn't make sense to me; if you set FIXED_CTR3 := 0, you'll
> > > never trigger the overflow there; this then seems to suggest the actual
> > 
> > The 48bit counter might overflow in a few hours.
> 
> Sure; the point is? Kan said it should not be too big; a full 48bit wrap
> around must be too big or nothing is.

We expect users to avoid making it too big, but we cannot rule it out.

Actually for the common perf stat for a long time case you can make it fairly
big because the percentages still work out over the complete run time.

The problem with letting it accumulate too much is mainly if you
want to use a continuously running metrics counter to time smaller
regions by taking deltas, for example using RDPMC. 

In this case the small regions would be too inaccurate after some time.

But to make the first case work absolutely need to handle the overflow
case. Otherwise the metrics would just randomly stop at some
point.


-Andi





Re: [PATCH V3 1/5] thermal: qoriq: Add clock operations

2019-08-28 Thread Zhang Rui
On Thu, 2019-08-29 at 02:49 +, Anson Huang wrote:
> Hi, Rui
> 
> > > On Wed, 2019-08-28 at 08:51 +, Anson Huang wrote:
> > > > Hi, Rui
> > > > 
> > > > > On Tue, 2019-08-27 at 12:41 +, Leonard Crestez wrote:
> > > > > > On 27.08.2019 04:51, Anson Huang wrote:
> > > > > > > > In an earlier series the CLK_IS_CRITICAL flags was
> > > > > > > > removed
> > > > > > > > from the TMU clock so if the thermal driver doesn't
> > > > > > > > explicitly enable it the system will hang on probe.
> > > > > > > > This is
> > > > > > > > what happens in linux-next right now!
> > > > > > > 
> > > > > > > The thermal driver should be built with module, so
> > > > > > > default
> > > > > > > kernel should can boot up, do you modify the thermal
> > > > > > > driver as
> > > > > > > built- in?
> > > > > > > 
> > > > > > > > Unless this patches is merged soon we'll end up with a
> > > > > > > > 5.4-
> > > > > > > > rc1
> > > > > > > > that doesn't boot on imx8mq. An easy fix would be to
> > > > > > > > drop/revert commit
> > > > > > > > 951c1aef9691 ("clk: imx8mq: Remove CLK_IS_CRITICAL flag
> > > > > > > > for
> > > > > > > > IMX8MQ_CLK_TMU_ROOT") until the thermal patches are
> > 
> > accepted.
> > > > > > > 
> > > > > > > If the thermal driver is built as module, I think no need
> > > > > > > to
> > > > > > > revert the commit, but if by default thermal driver is
> > > > > > > built-in or mod probed, then yes, it should NOT break
> > > > > > > kernel boot
> > 
> > up.
> > > > > > 
> > > > > > The qoriq_thermal driver is built as a module in defconfig
> > > > > > and
> > > > > > when modules are properly installed in rootfs they will be
> > > > > > automatically be probed on boot and cause a hang.
> > > > > > 
> > > > > > I usually run nfsroot with modules:
> > > > > > 
> > > > > >  make modules_install INSTALL_MOD_PATH=/srv/nfs/imx8-
> > > > > > root
> > > > > 
> > > > > so we need this patch shipped in the beginning of the merge
> > > > > window, right?
> > > > > if there is hard dependency between patches, it's better to
> > > > > send
> > > > > them in one series, and get shipped via either tree.
> > > > 
> > > > There is no hard dependency in this patch series. Previous for
> > > > the
> > > > TMU clock disabled patch, since thermal driver is built as
> > > > module so
> > > > I did NOT found the issue. The patch series is the correct fix.
> > > > 
> > > 
> > > Got it.
> > > the clock patch is also queued for 5.4-rc1, right?
> > > I will apply this series and try to push it as early as possible
> > > during the merge window.
> > 
> > The clock patch is as below in Linux-next tree, while I did NOT see
> > it in v5.3-
> > rc6, so it should be queued for 5.4-rc1, right?
> > Thanks for taking the patch series!
> 
> Sorry for pushing, so you will apply this patch series to avoid the
> i.MX8MQ kernel boot up hang
> caused by insmod qoriq thermal driver, right? Then we no need to
> revert that TMU clock patch
> 951c1aef9691 ("clk: imx8mq: Remove CLK_IS_CRITICAL flag for
> IMX8MQ_CLK_TMU_ROOT").
> 
right. I will queue it for 5.4-rc1.

thanks,
rui

> Thanks,
> Anson
> 
> > 
> > 
> > commit 951c1aef9691491ddf4dd5aab76f2665d56bd5d3
> > Author: Anson Huang 
> > Date:   Fri Jul 5 12:56:11 2019 +0800
> > 
> > clk: imx8mq: Remove CLK_IS_CRITICAL flag for
> > IMX8MQ_CLK_TMU_ROOT
> > 
> > IMX8MQ_CLK_TMU_ROOT is ONLY used for thermal module, the driver
> > should manage this clock, so no need to have CLK_IS_CRITICAL
> > flag
> > set.
> > 
> > Signed-off-by: Anson Huang 
> > Reviewed-by: Abel Vesa 
> > Acked-by: Stephen Boyd 
> > Signed-off-by: Shawn Guo 
> > 
> > drivers/clk/imx/clk-imx8mq.c
> > 
> > 
> > Thanks,
> > Anson



Re: [PATCH v2 3/3] dwc: PCI: intel: Intel PCIe RC controller driver

2019-08-28 Thread Chuan Hua, Lei



On 8/29/2019 3:36 AM, Martin Blumenstingl wrote:

On Wed, Aug 28, 2019 at 5:35 AM Chuan Hua, Lei
 wrote:
[...]

+static int intel_pcie_ep_rst_init(struct intel_pcie_port *lpp)
+{
+struct device *dev = lpp->pci->dev;
+int ret = 0;
+
+lpp->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+if (IS_ERR(lpp->reset_gpio)) {
+ret = PTR_ERR(lpp->reset_gpio);
+if (ret != -EPROBE_DEFER)
+dev_err(dev, "failed to request PCIe GPIO: %d\n", ret);
+return ret;
+}
+/* Make initial reset last for 100ms */
+msleep(100);

why is there lpp->rst_interval when you hardcode 100ms here?

There are different purpose. rst_interval is purely for asserted reset
pulse.

Here 100ms is to make sure the initial state keeps at least 100ms, then we
can reset.

my interpretation is that it totally depends on the board design or
the bootloader setup.

Partially, you are right. However, we should not add some dependency
here from
bootloader and board. rst_interval is just to make sure the pulse (low
active or high active)
lasts the specified the time.

+Cc Kishon

he recently added support for a GPIO reset line to the
pcie-cadence-host.c [0] and I believe he's also maintaining
pci-keystone.c which are both using a 100uS delay (instead of 100ms).
I don't know the PCIe spec so maybe Kishon can comment on the values
that should be used according to the spec.
if there's then a reason why values other than the ones from the spec
are needed then there should be a comment explaining why different
values are needed (what problem does it solve).

spec doesn't guide this part. It is a board or SoC specific setting.
100us also should work. spec only requirs reset duration should last
100ms. The idea is that before reset assert and deassert, make sure the
default deassert status keeps some time. We take this value from
hardware suggestion long time back. We can reduce this value to 100us,
but we need to test on the board.

OK. I don't know how other PCI controller drivers manage this. if the
PCI maintainers are happy with this then I am as well
maybe it's worth changing the comment to indicate that this delay was
suggested by the hardware team (so it's clear that this is not coming
from the PCI spec)
Dilip will change to 100us delay and run the test. I also need to run 
some tests for old boards(XRX350/550/PRX300) to confirm this has no 
impact on function.

[...]

+static void __intel_pcie_remove(struct intel_pcie_port *lpp)
+{
+pcie_rc_cfg_wr_mask(lpp, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER,
+0, PCI_COMMAND);

I expect logic like this to be part of the PCI subsystem in Linux.
why is this needed?

[...]

bind/unbind case we use this. For extreme cases, we use unbind and bind
to reset
PCI instead of rebooting.

OK, but this does not seem Intel/Lantiq specific at all
why isn't this managed by either pcie-designware-host.c or the generic
PCI/PCIe subsystem in Linux?

I doubt if other RC driver will support bind/unbind. We do have this
requirement due to power management from WiFi devices.

pcie-designware-host.c will gain .remove() support in Linux 5.4
I don't understand how .remove() and then .probe() again is different
from .unbind() followed by a .bind()

Good. If this is the case, bind/unbind eventually goes to probe/remove,
so we can remove this.

OK. as far as I understand you need to call dw_pcie_host_deinit from
the .remove() callback (which is missing in this version)
(I'm using drivers/pci/controller/dwc/pcie-tegra194.c as an example,
this driver is in linux-next and thus will appear in Linux 5.4)

Thanks for your information. We should adapt this in next version.



Martin


Re: [PATCH v2 2/2] reset: Reset controller driver for Intel LGM SoC

2019-08-28 Thread Chuan Hua, Lei



On 8/29/2019 4:01 AM, Martin Blumenstingl wrote:

Hi,

On Wed, Aug 28, 2019 at 3:53 AM Chuan Hua, Lei
 wrote:
[...]

1. reset-lantiq.c use index instead of register offset + bit position.
index reset is good for a small system (< 64). However, it will become very
difficult to use if you have  > 100 reset. So we use register offset +
bit position

reset-lantiq uses bit bit positions for specifying the reset line.
for example this is from OpenWrt's vr9.dtsi:
 reset0: reset-controller@10 {
   ...
   reg = <0x10 4>, <0x14 4>;
   #reset-cells = <2>;
 };

 gphy0: gphy@20 {
   ...
   resets = < 31 30>, < 7 7>;
   reset-names = "gphy", "gphy2";
 };

in my own words this means:
- all reset0 reset bits are at offset 0x10 (parent is RCU)
- all reset0 status bits are at offset 0x14 (parent is RCU)
- the first reset line uses reset bit 31 and status bit 30
- the second reset line uses reset bit 7 and status bit 7
- there can be multiple reset-controller instances, each taking the
reset and status offsets (OpenWrt's vr9.dtsi specifies the second RCU
reset controller "reset1" with reset offset 0x48 and status offset
0x24)

in reset-lantiq.c, we split each reset request /status pair into one
reset controller.

Each reset controller handles up to 32 resets. It will create up to 9
even more
reset controllers in the new SoCs. In reality, there is only one RCU
controller for all
SoCs. These designs worked but did not follow what hardware implemented.

After checking the existing code and referring to other implementation,
we decided to
use register offset + bit position method. It can support all SoCs with
this methods
without code change(device tree change only).

maybe I have a different interpretation of what "RCU" does.
let me explain it in my own words based on my knowledge about VRX200:
- in my own words it is a multi function device with the following
functionality:
- it contains two reset controllers (reset at 0x10, status 0x14 and
reset at 0x48, status at 0x24)
- it contains two USB2 PHYs (PHY registers at 0x18, ANA cfg at 0x38
and PHY registers at 0x34, ANA cfg at 0x3c)
- it contains the configuration for the two GPHY IP blocks (at 0x20 and 0x68)
- it contains endianness configuration registers (for PCI, PCIe, ...)
- it contains the watchdog boot status (whether the SoC was previously
reset by the WDT)
- maybe more, but I don't know anything else about it

In fact, there is only one reset controller for all SoCs even it doesn't
prevent software from virtualizing multiple reset controllers. Reset
control does include some misc stuff which has been moved to chiptop in
new SoCs so that RCU has a clean job.

just to confirm that I understand this correctly:
even the VRX200 SoC only has one physical reset controller?
instead of a contiguous register area (let's say: 0x10 to 0x1c) it
uses four separate registers:
- 0x10 for asserting/deasserting/pulsing the first 32 reset lines
- 0x14 for the status of the first 32 reset lines
- 0x48 for asserting/deasserting/pulsing the second 32 reset lines
- 0x28 for the status of the second 32 reset lines


Yes, but for VRX200, reset controller registers include some other misc 
registers. At that time,


hardware doesn't use chiptop concept, they put some misc registers into 
CGU/RCU which makes it quite messy.


We also prefer to have 0x10~0x1c. However, when developing VRX200, 0x18, 
0x20 and other address had been used by other registers. system becomes 
more complex, need more reset bits for new modules, then hardware just 
added them to any available place. From another angle, hardware people 
also tried to keep backward compatible with old products like Danube.




I'm not surprised that we got some of the IP block layout for the
VRX200 RCU "wrong" - all "documentation" we have is the old Lantiq UGW
(BSP).
with proper documentation (as in a "public datasheet for the SoC") it
would be easy to spot these mistakes (at least I assume that the
quality of the Infineon / Lantiq datasheets is excellent).

back to reset-intel-syscon:
assigning only one job to the RCU hardware is a good idea (in my opinion).
that brings up a question: why do we need the "syscon" compatible for
the RCU node?
this is typically used when registers are accessed by another IP block
and the other driver has to access these registers as well. does this
mean that there's more hidden in the RCU registers?
As I mentioned, some other misc registers are put into RCU even they 
don't belong to reset functions. In MIPS, global software reset handled 
in arch/mips/, only recently, this situation changed. This means we have 
at least two places to access this module.



2. reset-lantiq.c does not support device restart which is part of the
reset in
old lantiq SoC. It moved this part into arch/mips/lantiq directory.

it was moved to the .dts instead of the arch code. again from
OpenWrt's vr9.dtsi [0]:
 reboot {
   compatible = "syscon-reboot";
   regmap = <>;
   

RE: [PATCH V3 1/5] thermal: qoriq: Add clock operations

2019-08-28 Thread Anson Huang
Hi, Rui

> > On Wed, 2019-08-28 at 08:51 +, Anson Huang wrote:
> > > Hi, Rui
> > >
> > > > On Tue, 2019-08-27 at 12:41 +, Leonard Crestez wrote:
> > > > > On 27.08.2019 04:51, Anson Huang wrote:
> > > > > > > In an earlier series the CLK_IS_CRITICAL flags was removed
> > > > > > > from the TMU clock so if the thermal driver doesn't
> > > > > > > explicitly enable it the system will hang on probe. This is
> > > > > > > what happens in linux-next right now!
> > > > > >
> > > > > > The thermal driver should be built with module, so default
> > > > > > kernel should can boot up, do you modify the thermal driver as
> > > > > > built- in?
> > > > > >
> > > > > > > Unless this patches is merged soon we'll end up with a 5.4-
> > > > > > > rc1
> > > > > > > that doesn't boot on imx8mq. An easy fix would be to
> > > > > > > drop/revert commit
> > > > > > > 951c1aef9691 ("clk: imx8mq: Remove CLK_IS_CRITICAL flag for
> > > > > > > IMX8MQ_CLK_TMU_ROOT") until the thermal patches are
> accepted.
> > > > > >
> > > > > > If the thermal driver is built as module, I think no need to
> > > > > > revert the commit, but if by default thermal driver is
> > > > > > built-in or mod probed, then yes, it should NOT break kernel boot
> up.
> > > > >
> > > > > The qoriq_thermal driver is built as a module in defconfig and
> > > > > when modules are properly installed in rootfs they will be
> > > > > automatically be probed on boot and cause a hang.
> > > > >
> > > > > I usually run nfsroot with modules:
> > > > >
> > > > >  make modules_install INSTALL_MOD_PATH=/srv/nfs/imx8-root
> > > >
> > > > so we need this patch shipped in the beginning of the merge
> > > > window, right?
> > > > if there is hard dependency between patches, it's better to send
> > > > them in one series, and get shipped via either tree.
> > >
> > > There is no hard dependency in this patch series. Previous for the
> > > TMU clock disabled patch, since thermal driver is built as module so
> > > I did NOT found the issue. The patch series is the correct fix.
> > >
> > Got it.
> > the clock patch is also queued for 5.4-rc1, right?
> > I will apply this series and try to push it as early as possible
> > during the merge window.
> 
> The clock patch is as below in Linux-next tree, while I did NOT see it in 
> v5.3-
> rc6, so it should be queued for 5.4-rc1, right?
> Thanks for taking the patch series!

Sorry for pushing, so you will apply this patch series to avoid the i.MX8MQ 
kernel boot up hang
caused by insmod qoriq thermal driver, right? Then we no need to revert that 
TMU clock patch
951c1aef9691 ("clk: imx8mq: Remove CLK_IS_CRITICAL flag for 
IMX8MQ_CLK_TMU_ROOT").

Thanks,
Anson

> 
> 
> commit 951c1aef9691491ddf4dd5aab76f2665d56bd5d3
> Author: Anson Huang 
> Date:   Fri Jul 5 12:56:11 2019 +0800
> 
> clk: imx8mq: Remove CLK_IS_CRITICAL flag for IMX8MQ_CLK_TMU_ROOT
> 
> IMX8MQ_CLK_TMU_ROOT is ONLY used for thermal module, the driver
> should manage this clock, so no need to have CLK_IS_CRITICAL flag
> set.
> 
> Signed-off-by: Anson Huang 
> Reviewed-by: Abel Vesa 
> Acked-by: Stephen Boyd 
> Signed-off-by: Shawn Guo 
> 
> drivers/clk/imx/clk-imx8mq.c
> 
> 
> Thanks,
> Anson


[PATCH] amd-xgbe: Fix error path in xgbe_mod_init()

2019-08-28 Thread YueHaibing
In xgbe_mod_init(), we should do cleanup if some error occurs

Reported-by: Hulk Robot 
Fixes: efbaa828330a ("amd-xgbe: Add support to handle device renaming")
Fixes: 47f164deab22 ("amd-xgbe: Add PCI device support")
Signed-off-by: YueHaibing 
---
 drivers/net/ethernet/amd/xgbe/xgbe-main.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c 
b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
index b41f236..7ce9c69 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
@@ -469,13 +469,19 @@ static int __init xgbe_mod_init(void)
 
ret = xgbe_platform_init();
if (ret)
-   return ret;
+   goto err_platform_init;
 
ret = xgbe_pci_init();
if (ret)
-   return ret;
+   goto err_pci_init;
 
return 0;
+
+err_pci_init:
+   xgbe_platform_exit();
+err_platform_init:
+   unregister_netdevice_notifier(_netdev_notifier);
+   return ret;
 }
 
 static void __exit xgbe_mod_exit(void)
-- 
1.8.3.1




RE: [PATCH] arm: xen: mm: use __GPF_DMA32 for arm64

2019-08-28 Thread Peng Fan
Hi Stefano,

> Subject: RE: [PATCH] arm: xen: mm: use __GPF_DMA32 for arm64
> 
> On Wed, 28 Aug 2019, Peng Fan wrote:
> > Hi Robin,
> >
> > > Subject: Re: [PATCH] arm: xen: mm: use __GPF_DMA32 for arm64
> > >
> > > On 09/07/2019 09:22, Peng Fan wrote:
> > > > arm64 shares some code under arch/arm/xen, including mm.c.
> > > > However ZONE_DMA is removed by commit
> > > > ad67f5a6545("arm64: replace ZONE_DMA with ZONE_DMA32").
> > > > So to ARM64, need use __GFP_DMA32.
> 
> Hi Peng,
> 
> Sorry for being so late in replying, this email got lost in the noise.
> 
> 
> > > > Signed-off-by: Peng Fan 
> > > > ---
> > > >   arch/arm/xen/mm.c | 2 +-
> > > >   1 file changed, 1 insertion(+), 1 deletion(-)
> > > >
> > > > diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c index
> > > > e1d44b903dfc..a95e76d18bf9 100644
> > > > --- a/arch/arm/xen/mm.c
> > > > +++ b/arch/arm/xen/mm.c
> > > > @@ -27,7 +27,7 @@ unsigned long
> > > > xen_get_swiotlb_free_pages(unsigned
> > > > int order)
> > > >
> > > > for_each_memblock(memory, reg) {
> > > > if (reg->base < (phys_addr_t)0x) {
> > > > -   flags |= __GFP_DMA;
> > > > +   flags |= __GFP_DMA | __GFP_DMA32;
> > >
> > > Given the definition of GFP_ZONE_BAD, I'm not sure this combination
> > > of flags is strictly valid, but rather is implicitly reliant on only
> > > one of those zones ever actually existing. As such, it seems liable
> > > to blow up if the plans to add ZONE_DMA to arm64[1] go ahead.
> >
> > How about this, or do you have any suggestions?
> > diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c index
> > d33b77e9add3..f61c29a4430f 100644
> > --- a/arch/arm/xen/mm.c
> > +++ b/arch/arm/xen/mm.c
> > @@ -28,7 +28,11 @@ unsigned long xen_get_swiotlb_free_pages(unsigned
> > int order)
> >
> > for_each_memblock(memory, reg) {
> > if (reg->base < (phys_addr_t)0x) {
> > +#ifdef CONFIG_ARM64
> > +   flags |= __GFP_DMA32; #else
> > flags |= __GFP_DMA;
> > +#endif
> > break;
> > }
> > }
> 
> Yes I think this is the way to go, but we are trying not to add any #ifdef
> CONFIG_ARM64 under arch/arm. Maybe you could introduce a static inline
> function to set GFP_DMA:
> 
>   static inline void xen_set_gfp_dma(gfp_t *flags)
> 
> it could be implemented under arch/arm/include/asm/xen/page.h for arm
> and under arch/arm64/include/asm/xen/page.h for arm64 using __GFP_DMA
> for the former and __GFP_DMA32 for the latter.

Thanks for your suggestion. I'll use this in V2.

Thanks,
Peng.



Re: [PATCH v6 00/12] implement KASLR for powerpc/fsl_booke/32

2019-08-28 Thread Jason Yan




On 2019/8/28 12:59, Scott Wood wrote:

On Tue, 2019-08-27 at 23:05 -0500, Scott Wood wrote:

On Fri, 2019-08-09 at 18:07 +0800, Jason Yan wrote:

  Freescale Book-E
parts expect lowmem to be mapped by fixed TLB entries(TLB1). The TLB1
entries are not suitable to map the kernel directly in a randomized
region, so we chose to copy the kernel to a proper place and restart to
relocate.

Entropy is derived from the banner and timer base, which will change every
build and boot. This not so much safe so additionally the bootloader may
pass entropy via the /chosen/kaslr-seed node in device tree.


How complicated would it be to directly access the HW RNG (if present) that
early in the boot?  It'd be nice if a U-Boot update weren't required (and
particularly concerning that KASLR would appear to work without a U-Boot
update, but without decent entropy).


OK, I see that kaslr-seed is used on some other platforms, though arm64 aborts
KASLR if it doesn't get a seed.  I'm not sure if that's better than a loud
warning message (or if it was a conscious choice rather than just not having
an alternative implemented), but silently using poor entropy for something
like this seems bad.



It can still make the attacker's cost higher with not so good entropy.
The same strategy exists in X86 when X86 KASLR uses RDTSC if without
X86_FEATURE_RDRAND supported. I agree that having a warning message
looks better for reminding people in this situation.


-Scott



.





Re: mmotm 2019-08-27-20-39 uploaded (sound/hda/intel-nhlt.c)

2019-08-28 Thread Randy Dunlap
On 8/28/19 3:59 PM, Randy Dunlap wrote:
> On 8/28/19 3:45 PM, Pierre-Louis Bossart wrote:
>>
>>>>> I just checked with Mark Brown's for-next tree 
>>>>> 8aceffa09b4b9867153bfe0ff6f40517240cee12
>>>>> and things are fine in i386 mode, see below.
>>>>>
>>>>> next-20190828 also works fine for me in i386 mode.
>>>>>
>>>>> if you can point me to a tree and configuration that don't work I'll look 
>>>>> into this, I'd need more info to progress.
>>>>
>>>> Please try the attached randconfig file.
>>>>
>>>> Thanks for looking.
>>>
>>> Ack, I see some errors as well with this config. Likely a missing 
>>> dependency somewhere, working on this now.
>>
>> My bad, I added a fallback with static inline functions in the .h file when 
>> ACPI is not defined, but the .c file was still compiled.
>>
>> The diff below makes next-20190828 compile with Randy's config.
>>
>> It looks like the alsa-devel server is down btw?
>>
>> diff --git a/sound/hda/Makefile b/sound/hda/Makefile
>> index 8560f6ef1b19..b3af071ce06b 100644
>> --- a/sound/hda/Makefile
>> +++ b/sound/hda/Makefile
>> @@ -14,5 +14,7 @@ obj-$(CONFIG_SND_HDA_CORE) += snd-hda-core.o
>>  #extended hda
>>  obj-$(CONFIG_SND_HDA_EXT_CORE) += ext/
>>
>> +ifdef CONFIG_ACPI
>>  snd-intel-nhlt-objs := intel-nhlt.o
>>  obj-$(CONFIG_SND_INTEL_NHLT) += snd-intel-nhlt.o
>> +endif
>>
> 
> works for me.  Thanks.
> Acked-by: Randy Dunlap  # build-tested
> 

although this Makefile change should not be needed
and the dependencies should be handled correctly in Kconfig files.

-- 
~Randy


[v5] rtc: pcf85363/pcf85263: fix error that failed to run hwclock -w

2019-08-28 Thread Biwen Li
Issue:
- # hwclock -w
  hwclock: RTC_SET_TIME: Invalid argument

Why:
- Relative commit: 8b9f9d4dc511309918c4f6793bae7387c0c638af, this patch
  will always check for unwritable registers, it will compare reg
  with max_register in regmap_writeable.

- The pcf85363/pcf85263 has the capability of address wrapping
  which means if you access an address outside the allowed range
  (0x00-0x2f) hardware actually wraps the access to a lower address.
  The rtc-pcf85363 driver will use this feature to configure the time
  and execute 2 actions in the same i2c write operation (stopping the
  clock and configure the time). However the driver has also
  configured the `regmap maxregister` protection mechanism that will
  block accessing addresses outside valid range (0x00-0x2f).

How:
- Split of writing regs to two parts, first part writes control
  registers about stop_enable and resets, second part writes
  RTC time and date registers.

Signed-off-by: Biwen Li 
---
Change in v5:
- drop robust explanation

Change in v4:
- use old scheme
- replace link to lkml.org with commit
- add proper explanation

Change in v3:
- replace old scheme with new scheme:
  increase max_register.

Change in v2:
- add Why and How into commit message.

 drivers/rtc/rtc-pcf85363.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c
index a075e77617dc..3450d615974d 100644
--- a/drivers/rtc/rtc-pcf85363.c
+++ b/drivers/rtc/rtc-pcf85363.c
@@ -166,7 +166,12 @@ static int pcf85363_rtc_set_time(struct device *dev, 
struct rtc_time *tm)
buf[DT_YEARS] = bin2bcd(tm->tm_year % 100);
 
ret = regmap_bulk_write(pcf85363->regmap, CTRL_STOP_EN,
-   tmp, sizeof(tmp));
+   tmp, 2);
+   if (ret)
+   return ret;
+
+   ret = regmap_bulk_write(pcf85363->regmap, DT_100THS,
+   buf, sizeof(tmp) - 2);
if (ret)
return ret;
 
-- 
2.17.1



[PATCH v2 0/4] KVM: selftests: Introduce VM_MODE_PXXV48_4K

2019-08-28 Thread Peter Xu
v2:
- pick r-bs
- rebased to master
- fix pa width detect, check cpuid(1):edx.PAE(bit 6)
- fix arm compilation issue [Drew]
- fix indents issues and ways to define macros [Drew]
- provide functions for fetching cpu pa/va bits [Drew]

This series originates from "[PATCH] KVM: selftests: Detect max PA
width from cpuid" [1] and one of Drew's comments - instead of keeping
the hackish line to overwrite guest_pa_bits all the time, this series
introduced the new mode VM_MODE_PXXV48_4K for x86_64 platform.

The major issue is that even all the x86_64 kvm selftests are
currently using the guest mode VM_MODE_P52V48_4K, many x86_64 hosts
are not using 52 bits PA (and in most cases, far less).  If with luck
we could be having 48 bits hosts, but it's more adhoc (I've observed 3
x86_64 systems, they are having different PA width of 36, 39, 48).  I
am not sure whether this is happening to the other archs as well, but
it probably makes sense to bring the x86_64 tests to the real world on
always using the correct PA bits.

A side effect of this series is that it will also fix the crash we've
encountered on Xeon E3-1220 as mentioned [1] due to the
differenciation of PA width.

With [1], we've observed AMD host issues when with NPT=off.  However a
funny fact is that after I reworked into this series, the tests can
instead pass on both NPT=on/off.  It could be that the series changes
vm->pa_bits or other fields so something was affected.  I didn't dig
more on that though, considering we should not lose anything.

[1] https://lkml.org/lkml/2019/8/26/141

Peter Xu (4):
  KVM: selftests: Move vm type into _vm_create() internally
  KVM: selftests: Create VM earlier for dirty log test
  KVM: selftests: Introduce VM_MODE_PXXV48_4K
  KVM: selftests: Remove duplicate guest mode handling

 tools/testing/selftests/kvm/dirty_log_test.c  | 79 +--
 .../testing/selftests/kvm/include/kvm_util.h  | 16 +++-
 .../selftests/kvm/include/x86_64/processor.h  |  3 +
 .../selftests/kvm/lib/aarch64/processor.c |  3 +
 tools/testing/selftests/kvm/lib/kvm_util.c| 67 
 .../selftests/kvm/lib/x86_64/processor.c  | 30 ++-
 6 files changed, 119 insertions(+), 79 deletions(-)

-- 
2.21.0



[PATCH v2 4/4] KVM: selftests: Remove duplicate guest mode handling

2019-08-28 Thread Peter Xu
Remove the duplication code in run_test() of dirty_log_test because
after some reordering of functions now we can directly use the outcome
of vm_create().

Meanwhile, with the new VM_MODE_PXXV48_4K, we can safely revert
b442324b58 too where we stick the x86_64 PA width to 39 bits for
dirty_log_test.

Reviewed-by: Andrew Jones 
Signed-off-by: Peter Xu 
---
 tools/testing/selftests/kvm/dirty_log_test.c  | 52 ++-
 .../testing/selftests/kvm/include/kvm_util.h  |  4 ++
 tools/testing/selftests/kvm/lib/kvm_util.c| 17 ++
 3 files changed, 26 insertions(+), 47 deletions(-)

diff --git a/tools/testing/selftests/kvm/dirty_log_test.c 
b/tools/testing/selftests/kvm/dirty_log_test.c
index c86f83cb33e5..89fac11733a5 100644
--- a/tools/testing/selftests/kvm/dirty_log_test.c
+++ b/tools/testing/selftests/kvm/dirty_log_test.c
@@ -234,10 +234,8 @@ static struct kvm_vm *create_vm(enum vm_guest_mode mode, 
uint32_t vcpuid,
 static void run_test(enum vm_guest_mode mode, unsigned long iterations,
 unsigned long interval, uint64_t phys_offset)
 {
-   unsigned int guest_pa_bits, guest_page_shift;
pthread_t vcpu_thread;
struct kvm_vm *vm;
-   uint64_t max_gfn;
unsigned long *bmap;
 
/*
@@ -252,60 +250,20 @@ static void run_test(enum vm_guest_mode mode, unsigned 
long iterations,
   2ul << (DIRTY_MEM_BITS - PAGE_SHIFT_4K),
   guest_code);
 
-   switch (mode) {
-   case VM_MODE_P52V48_4K:
-   case VM_MODE_PXXV48_4K:
-   guest_pa_bits = 52;
-   guest_page_shift = 12;
-   break;
-   case VM_MODE_P52V48_64K:
-   guest_pa_bits = 52;
-   guest_page_shift = 16;
-   break;
-   case VM_MODE_P48V48_4K:
-   guest_pa_bits = 48;
-   guest_page_shift = 12;
-   break;
-   case VM_MODE_P48V48_64K:
-   guest_pa_bits = 48;
-   guest_page_shift = 16;
-   break;
-   case VM_MODE_P40V48_4K:
-   guest_pa_bits = 40;
-   guest_page_shift = 12;
-   break;
-   case VM_MODE_P40V48_64K:
-   guest_pa_bits = 40;
-   guest_page_shift = 16;
-   break;
-   default:
-   TEST_ASSERT(false, "Unknown guest mode, mode: 0x%x", mode);
-   }
-
-   DEBUG("Testing guest mode: %s\n", vm_guest_mode_string(mode));
-
-#ifdef __x86_64__
-   /*
-* FIXME
-* The x86_64 kvm selftests framework currently only supports a
-* single PML4 which restricts the number of physical address
-* bits we can change to 39.
-*/
-   guest_pa_bits = 39;
-#endif
-   max_gfn = (1ul << (guest_pa_bits - guest_page_shift)) - 1;
-   guest_page_size = (1ul << guest_page_shift);
+   guest_page_size = vm_get_page_size(vm);
/*
 * A little more than 1G of guest page sized pages.  Cover the
 * case where the size is not aligned to 64 pages.
 */
-   guest_num_pages = (1ul << (DIRTY_MEM_BITS - guest_page_shift)) + 16;
+   guest_num_pages = (1ul << (DIRTY_MEM_BITS -
+  vm_get_page_shift(vm))) + 16;
host_page_size = getpagesize();
host_num_pages = (guest_num_pages * guest_page_size) / host_page_size +
 !!((guest_num_pages * guest_page_size) % 
host_page_size);
 
if (!phys_offset) {
-   guest_test_phys_mem = (max_gfn - guest_num_pages) * 
guest_page_size;
+   guest_test_phys_mem = (vm_get_max_gfn(vm) -
+  guest_num_pages) * guest_page_size;
guest_test_phys_mem &= ~(host_page_size - 1);
} else {
guest_test_phys_mem = phys_offset;
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h 
b/tools/testing/selftests/kvm/include/kvm_util.h
index 430edbacb9b2..070e3ba193a6 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -152,6 +152,10 @@ void vm_vcpu_add_default(struct kvm_vm *vm, uint32_t 
vcpuid, void *guest_code);
 
 bool vm_is_unrestricted_guest(struct kvm_vm *vm);
 
+unsigned int vm_get_page_size(struct kvm_vm *vm);
+unsigned int vm_get_page_shift(struct kvm_vm *vm);
+unsigned int vm_get_max_gfn(struct kvm_vm *vm);
+
 struct kvm_userspace_memory_region *
 kvm_userspace_memory_region_find(struct kvm_vm *vm, uint64_t start,
 uint64_t end);
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c 
b/tools/testing/selftests/kvm/lib/kvm_util.c
index bb8f993b25fb..80a338b5403c 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -136,6 +136,8 @@ struct kvm_vm *_vm_create(enum vm_guest_mode mode, uint64_t 
phy_pages, int perm)
 {
struct kvm_vm *vm;
 
+   DEBUG("Testing guest mode: %s\n", 

[PATCH v2 3/4] KVM: selftests: Introduce VM_MODE_PXXV48_4K

2019-08-28 Thread Peter Xu
The naming VM_MODE_P52V48_4K is explicit but unclear when used on
x86_64 machines, because x86_64 machines are having various physical
address width rather than some static values.  Here's some examples:

  - Intel Xeon E3-1220:  36 bits
  - Intel Core i7-8650:  39 bits
  - AMD   EPYC 7251: 48 bits

All of them are using 48 bits linear address width but with totally
different physical address width (and most of the old machines should
be less than 52 bits).

Let's create a new guest mode called VM_MODE_PXXV48_4K for current
x86_64 tests and make it as the default to replace the old naming of
VM_MODE_P52V48_4K because it shows more clearly that the PA width is
not really a constant.  Meanwhile we also stop assuming all the x86
machines are having 52 bits PA width but instead we fetch the real
vm->pa_bits from CPUID 0x8008 during runtime.

We currently make this exclusively used by x86_64 but no other arch.

As a slight touch up, moving DEBUG macro from dirty_log_test.c to
kvm_util.h so lib can use it too.

Signed-off-by: Peter Xu 
---
 tools/testing/selftests/kvm/dirty_log_test.c  |  5 ++--
 .../testing/selftests/kvm/include/kvm_util.h  |  9 +-
 .../selftests/kvm/include/x86_64/processor.h  |  3 ++
 .../selftests/kvm/lib/aarch64/processor.c |  3 ++
 tools/testing/selftests/kvm/lib/kvm_util.c| 29 ++
 .../selftests/kvm/lib/x86_64/processor.c  | 30 ---
 6 files changed, 65 insertions(+), 14 deletions(-)

diff --git a/tools/testing/selftests/kvm/dirty_log_test.c 
b/tools/testing/selftests/kvm/dirty_log_test.c
index efb7746a7e99..c86f83cb33e5 100644
--- a/tools/testing/selftests/kvm/dirty_log_test.c
+++ b/tools/testing/selftests/kvm/dirty_log_test.c
@@ -19,8 +19,6 @@
 #include "kvm_util.h"
 #include "processor.h"
 
-#define DEBUG printf
-
 #define VCPU_ID1
 
 /* The memory slot index to track dirty pages */
@@ -256,6 +254,7 @@ static void run_test(enum vm_guest_mode mode, unsigned long 
iterations,
 
switch (mode) {
case VM_MODE_P52V48_4K:
+   case VM_MODE_PXXV48_4K:
guest_pa_bits = 52;
guest_page_shift = 12;
break;
@@ -446,7 +445,7 @@ int main(int argc, char *argv[])
 #endif
 
 #ifdef __x86_64__
-   vm_guest_mode_params_init(VM_MODE_P52V48_4K, true, true);
+   vm_guest_mode_params_init(VM_MODE_PXXV48_4K, true, true);
 #endif
 #ifdef __aarch64__
vm_guest_mode_params_init(VM_MODE_P40V48_4K, true, true);
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h 
b/tools/testing/selftests/kvm/include/kvm_util.h
index c78faa2ff7f3..430edbacb9b2 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -24,6 +24,10 @@ struct kvm_vm;
 typedef uint64_t vm_paddr_t; /* Virtual Machine (Guest) physical address */
 typedef uint64_t vm_vaddr_t; /* Virtual Machine (Guest) virtual address */
 
+#ifndef DEBUG
+#define DEBUG printf
+#endif
+
 /* Minimum allocated guest virtual and physical addresses */
 #define KVM_UTIL_MIN_VADDR 0x2000
 
@@ -38,11 +42,14 @@ enum vm_guest_mode {
VM_MODE_P48V48_64K,
VM_MODE_P40V48_4K,
VM_MODE_P40V48_64K,
+   VM_MODE_PXXV48_4K,  /* For 48bits VA but ANY bits PA */
NUM_VM_MODES,
 };
 
-#ifdef __aarch64__
+#if defined(__aarch64__)
 #define VM_MODE_DEFAULT VM_MODE_P40V48_4K
+#elif defined(__x86_64__)
+#define VM_MODE_DEFAULT VM_MODE_PXXV48_4K
 #else
 #define VM_MODE_DEFAULT VM_MODE_P52V48_4K
 #endif
diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h 
b/tools/testing/selftests/kvm/include/x86_64/processor.h
index 80d19740d2dc..0c17f2ee685e 100644
--- a/tools/testing/selftests/kvm/include/x86_64/processor.h
+++ b/tools/testing/selftests/kvm/include/x86_64/processor.h
@@ -325,6 +325,9 @@ uint64_t vcpu_get_msr(struct kvm_vm *vm, uint32_t vcpuid, 
uint64_t msr_index);
 void vcpu_set_msr(struct kvm_vm *vm, uint32_t vcpuid, uint64_t msr_index,
  uint64_t msr_value);
 
+uint32_t kvm_get_cpuid_max(void);
+void kvm_get_cpu_address_width(unsigned int *pa_bits, unsigned int *va_bits);
+
 /*
  * Basic CPU control in CR0
  */
diff --git a/tools/testing/selftests/kvm/lib/aarch64/processor.c 
b/tools/testing/selftests/kvm/lib/aarch64/processor.c
index 486400a97374..86036a59a668 100644
--- a/tools/testing/selftests/kvm/lib/aarch64/processor.c
+++ b/tools/testing/selftests/kvm/lib/aarch64/processor.c
@@ -264,6 +264,9 @@ void aarch64_vcpu_setup(struct kvm_vm *vm, int vcpuid, 
struct kvm_vcpu_init *ini
case VM_MODE_P52V48_4K:
TEST_ASSERT(false, "AArch64 does not support 4K sized pages "
   "with 52-bit physical address ranges");
+   case VM_MODE_PXXV48_4K:
+   TEST_ASSERT(false, "AArch64 does not support 4K sized pages "
+  "with ANY-bit physical address ranges");
case VM_MODE_P52V48_64K:
 

[PATCH v2 2/4] KVM: selftests: Create VM earlier for dirty log test

2019-08-28 Thread Peter Xu
Since we've just removed the dependency of vm type in previous patch,
now we can create the vm much earlier.  Note that to move it earlier
we used an approximation of number of extra pages but it should be
fine.

This prepares for the follow up patches to finally remove the
duplication of guest mode parsings.

Reviewed-by: Andrew Jones 
Signed-off-by: Peter Xu 
---
 tools/testing/selftests/kvm/dirty_log_test.c | 19 ---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/kvm/dirty_log_test.c 
b/tools/testing/selftests/kvm/dirty_log_test.c
index 135cba5c6d0d..efb7746a7e99 100644
--- a/tools/testing/selftests/kvm/dirty_log_test.c
+++ b/tools/testing/selftests/kvm/dirty_log_test.c
@@ -230,6 +230,9 @@ static struct kvm_vm *create_vm(enum vm_guest_mode mode, 
uint32_t vcpuid,
return vm;
 }
 
+#define DIRTY_MEM_BITS 30 /* 1G */
+#define PAGE_SHIFT_4K  12
+
 static void run_test(enum vm_guest_mode mode, unsigned long iterations,
 unsigned long interval, uint64_t phys_offset)
 {
@@ -239,6 +242,18 @@ static void run_test(enum vm_guest_mode mode, unsigned 
long iterations,
uint64_t max_gfn;
unsigned long *bmap;
 
+   /*
+* We reserve page table for 2 times of extra dirty mem which
+* will definitely cover the original (1G+) test range.  Here
+* we do the calculation with 4K page size which is the
+* smallest so the page number will be enough for all archs
+* (e.g., 64K page size guest will need even less memory for
+* page tables).
+*/
+   vm = create_vm(mode, VCPU_ID,
+  2ul << (DIRTY_MEM_BITS - PAGE_SHIFT_4K),
+  guest_code);
+
switch (mode) {
case VM_MODE_P52V48_4K:
guest_pa_bits = 52;
@@ -285,7 +300,7 @@ static void run_test(enum vm_guest_mode mode, unsigned long 
iterations,
 * A little more than 1G of guest page sized pages.  Cover the
 * case where the size is not aligned to 64 pages.
 */
-   guest_num_pages = (1ul << (30 - guest_page_shift)) + 16;
+   guest_num_pages = (1ul << (DIRTY_MEM_BITS - guest_page_shift)) + 16;
host_page_size = getpagesize();
host_num_pages = (guest_num_pages * guest_page_size) / host_page_size +
 !!((guest_num_pages * guest_page_size) % 
host_page_size);
@@ -302,8 +317,6 @@ static void run_test(enum vm_guest_mode mode, unsigned long 
iterations,
bmap = bitmap_alloc(host_num_pages);
host_bmap_track = bitmap_alloc(host_num_pages);
 
-   vm = create_vm(mode, VCPU_ID, guest_num_pages, guest_code);
-
 #ifdef USE_CLEAR_DIRTY_LOG
struct kvm_enable_cap cap = {};
 
-- 
2.21.0



[PATCH v2 1/4] KVM: selftests: Move vm type into _vm_create() internally

2019-08-28 Thread Peter Xu
Rather than passing the vm type from the top level to the end of vm
creation, let's simply keep that as an internal of kvm_vm struct and
decide the type in _vm_create().  Several reasons for doing this:

- The vm type is only decided by physical address width and currently
  only used in aarch64, so we've got enough information as long as
  we're passing vm_guest_mode into _vm_create(),

- This removes a loop dependency between the vm->type and creation of
  vms.  That's why now we need to parse vm_guest_mode twice sometimes,
  once in run_test() and then again in _vm_create().  The follow up
  patches will move on to clean up that as well so we can have a
  single place to decide guest machine types and so.

Note that this patch will slightly change the behavior of aarch64
tests in that previously most vm_create() callers will directly pass
in type==0 into _vm_create() but now the type will depend on
vm_guest_mode, however it shouldn't affect any user because all
vm_create() users of aarch64 will be using VM_MODE_DEFAULT guest
mode (which is VM_MODE_P40V48_4K) so at last type will still be zero.

Signed-off-by: Peter Xu 
---
 tools/testing/selftests/kvm/dirty_log_test.c  | 13 +++-
 .../testing/selftests/kvm/include/kvm_util.h  |  3 +--
 tools/testing/selftests/kvm/lib/kvm_util.c| 21 ---
 3 files changed, 17 insertions(+), 20 deletions(-)

diff --git a/tools/testing/selftests/kvm/dirty_log_test.c 
b/tools/testing/selftests/kvm/dirty_log_test.c
index ceb52b952637..135cba5c6d0d 100644
--- a/tools/testing/selftests/kvm/dirty_log_test.c
+++ b/tools/testing/selftests/kvm/dirty_log_test.c
@@ -216,14 +216,12 @@ static void vm_dirty_log_verify(unsigned long *bmap)
 }
 
 static struct kvm_vm *create_vm(enum vm_guest_mode mode, uint32_t vcpuid,
-   uint64_t extra_mem_pages, void *guest_code,
-   unsigned long type)
+   uint64_t extra_mem_pages, void *guest_code)
 {
struct kvm_vm *vm;
uint64_t extra_pg_pages = extra_mem_pages / 512 * 2;
 
-   vm = _vm_create(mode, DEFAULT_GUEST_PHY_PAGES + extra_pg_pages,
-   O_RDWR, type);
+   vm = _vm_create(mode, DEFAULT_GUEST_PHY_PAGES + extra_pg_pages, O_RDWR);
kvm_vm_elf_load(vm, program_invocation_name, 0, 0);
 #ifdef __x86_64__
vm_create_irqchip(vm);
@@ -240,7 +238,6 @@ static void run_test(enum vm_guest_mode mode, unsigned long 
iterations,
struct kvm_vm *vm;
uint64_t max_gfn;
unsigned long *bmap;
-   unsigned long type = 0;
 
switch (mode) {
case VM_MODE_P52V48_4K:
@@ -281,10 +278,6 @@ static void run_test(enum vm_guest_mode mode, unsigned 
long iterations,
 * bits we can change to 39.
 */
guest_pa_bits = 39;
-#endif
-#ifdef __aarch64__
-   if (guest_pa_bits != 40)
-   type = KVM_VM_TYPE_ARM_IPA_SIZE(guest_pa_bits);
 #endif
max_gfn = (1ul << (guest_pa_bits - guest_page_shift)) - 1;
guest_page_size = (1ul << guest_page_shift);
@@ -309,7 +302,7 @@ static void run_test(enum vm_guest_mode mode, unsigned long 
iterations,
bmap = bitmap_alloc(host_num_pages);
host_bmap_track = bitmap_alloc(host_num_pages);
 
-   vm = create_vm(mode, VCPU_ID, guest_num_pages, guest_code, type);
+   vm = create_vm(mode, VCPU_ID, guest_num_pages, guest_code);
 
 #ifdef USE_CLEAR_DIRTY_LOG
struct kvm_enable_cap cap = {};
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h 
b/tools/testing/selftests/kvm/include/kvm_util.h
index e0e66b115ef2..c78faa2ff7f3 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -60,8 +60,7 @@ int kvm_check_cap(long cap);
 int vm_enable_cap(struct kvm_vm *vm, struct kvm_enable_cap *cap);
 
 struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int 
perm);
-struct kvm_vm *_vm_create(enum vm_guest_mode mode, uint64_t phy_pages,
- int perm, unsigned long type);
+struct kvm_vm *_vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int 
perm);
 void kvm_vm_free(struct kvm_vm *vmp);
 void kvm_vm_restart(struct kvm_vm *vmp, int perm);
 void kvm_vm_release(struct kvm_vm *vmp);
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c 
b/tools/testing/selftests/kvm/lib/kvm_util.c
index 6e49bb039376..34a8a6572c7c 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -84,7 +84,7 @@ int vm_enable_cap(struct kvm_vm *vm, struct kvm_enable_cap 
*cap)
return ret;
 }
 
-static void vm_open(struct kvm_vm *vm, int perm, unsigned long type)
+static void vm_open(struct kvm_vm *vm, int perm)
 {
vm->kvm_fd = open(KVM_DEV_PATH, perm);
if (vm->kvm_fd < 0)
@@ -95,7 +95,7 @@ static void vm_open(struct kvm_vm *vm, int perm, unsigned 
long type)
exit(KSFT_SKIP);
}
 
-   vm->fd = 

Re: [PATCH 4/4] KVM: selftests: Remove duplicate guest mode handling

2019-08-28 Thread Peter Xu
On Wed, Aug 28, 2019 at 01:46:13PM +0200, Andrew Jones wrote:

[...]

> > +unsigned int vm_get_page_size(struct kvm_vm *vm)
> > +{
> > +   return vm->page_size;
> > +}
> > +
> > +unsigned int vm_get_page_shift(struct kvm_vm *vm)
> > +{
> > +   return vm->page_shift;
> > +}
> 
> We could get by with just one of the above two, but whatever

Right... and imho if we export kvm_vm struct we don't even any
helpers. :) But I didn't touch that.

> > +
> > +unsigned int vm_get_max_gfn(struct kvm_vm *vm)
> > +{
> > +   return vm->max_gfn;
> > +}
> > -- 
> > 2.21.0
> >
> 
> Reviewed-by: Andrew Jones 

Thanks!

-- 
Peter Xu


Re: [PATCH 3/4] KVM: selftests: Introduce VM_MODE_PXXV48_4K

2019-08-28 Thread Peter Xu
On Wed, Aug 28, 2019 at 01:41:04PM +0200, Andrew Jones wrote:

[...]

> > +#define DEBUG printf
> 
> If this is going to be some general thing, then maybe we should do it
> like this
> 
> #ifndef NDEBUG
> #define dprintf printf
> #endif

Ok.

> 
> 
> > +
> >  /* Minimum allocated guest virtual and physical addresses */
> >  #define KVM_UTIL_MIN_VADDR 0x2000
> >  
> > @@ -38,12 +40,19 @@ enum vm_guest_mode {
> > VM_MODE_P48V48_64K,
> > VM_MODE_P40V48_4K,
> > VM_MODE_P40V48_64K,
> > +   VM_MODE_PXXV48_4K,  /* For 48bits VA but ANY bits PA */
> > NUM_VM_MODES,
> >  };
> >  
> >  #ifdef __aarch64__
> >  #define VM_MODE_DEFAULT VM_MODE_P40V48_4K
> > -#else
> > +#endif
> > +
> > +#ifdef __x86_64__
> > +#define VM_MODE_DEFAULT VM_MODE_PXXV48_4K
> > +#endif
> > +
> > +#ifndef VM_MODE_DEFAULT
> >  #define VM_MODE_DEFAULT VM_MODE_P52V48_4K
> >  #endif
> 
> nit: how about
> 
> #if defined(__aarch64__)
> ...
> #elif defined(__x86_64__)
> ...
> #else
> ...
> #endif

Yes, better!

> 
> >  
> > diff --git a/tools/testing/selftests/kvm/lib/aarch64/processor.c 
> > b/tools/testing/selftests/kvm/lib/aarch64/processor.c
> > index 486400a97374..86036a59a668 100644
> > --- a/tools/testing/selftests/kvm/lib/aarch64/processor.c
> > +++ b/tools/testing/selftests/kvm/lib/aarch64/processor.c
> > @@ -264,6 +264,9 @@ void aarch64_vcpu_setup(struct kvm_vm *vm, int vcpuid, 
> > struct kvm_vcpu_init *ini
> > case VM_MODE_P52V48_4K:
> > TEST_ASSERT(false, "AArch64 does not support 4K sized pages "
> >"with 52-bit physical address ranges");
> > +   case VM_MODE_PXXV48_4K:
> > +   TEST_ASSERT(false, "AArch64 does not support 4K sized pages "
> > +  "with ANY-bit physical address ranges");
> > case VM_MODE_P52V48_64K:
> > tcr_el1 |= 1ul << 14; /* TG0 = 64KB */
> > tcr_el1 |= 6ul << 32; /* IPS = 52 bits */
> > diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c 
> > b/tools/testing/selftests/kvm/lib/kvm_util.c
> > index 0c7c4368bc14..8c6f872a8793 100644
> > --- a/tools/testing/selftests/kvm/lib/kvm_util.c
> > +++ b/tools/testing/selftests/kvm/lib/kvm_util.c
> > @@ -8,6 +8,7 @@
> >  #include "test_util.h"
> >  #include "kvm_util.h"
> >  #include "kvm_util_internal.h"
> > +#include "processor.h"
> >  
> >  #include 
> >  #include 
> > @@ -101,12 +102,13 @@ static void vm_open(struct kvm_vm *vm, int perm)
> >  }
> >  
> >  const char * const vm_guest_mode_string[] = {
> > -   "PA-bits:52, VA-bits:48, 4K pages",
> > -   "PA-bits:52, VA-bits:48, 64K pages",
> > -   "PA-bits:48, VA-bits:48, 4K pages",
> > -   "PA-bits:48, VA-bits:48, 64K pages",
> > -   "PA-bits:40, VA-bits:48, 4K pages",
> > -   "PA-bits:40, VA-bits:48, 64K pages",
> > +   "PA-bits:52,  VA-bits:48, 4K pages",
> > +   "PA-bits:52,  VA-bits:48, 64K pages",
> > +   "PA-bits:48,  VA-bits:48, 4K pages",
> > +   "PA-bits:48,  VA-bits:48, 64K pages",
> > +   "PA-bits:40,  VA-bits:48, 4K pages",
> > +   "PA-bits:40,  VA-bits:48, 64K pages",
> > +   "PA-bits:ANY, VA-bits:48, 4K pages",
> 
> nit: while formatting we could align the 'K's in the 64/4K column

Ok.

> 
> >  };
> >  _Static_assert(sizeof(vm_guest_mode_string)/sizeof(char *) == NUM_VM_MODES,
> >"Missing new mode strings?");
> > @@ -185,6 +187,32 @@ struct kvm_vm *_vm_create(enum vm_guest_mode mode, 
> > uint64_t phy_pages,
> > vm->page_size = 0x1;
> > vm->page_shift = 16;
> > break;
> > +   case VM_MODE_PXXV48_4K:
> > +#ifdef __x86_64__
> > +   {
> > +   struct kvm_cpuid_entry2 *entry;
> > +
> > +   /* SDM 4.1.4 */
> > +   entry = kvm_get_supported_cpuid_entry(0x8008);
> > +   if (entry) {
> > +   vm->pa_bits = entry->eax & 0xff;
> > +   vm->va_bits = (entry->eax >> 8) & 0xff;
> > +   } else {
> > +   vm->pa_bits = vm->va_bits = 32;
> > +   }
> > +   TEST_ASSERT(vm->va_bits == 48, "Linear address width "
> > +   "(%d bits) not supported", vm->va_bits);
> > +   vm->pgtable_levels = 4;
> > +   vm->page_size = 0x1000;
> > +   vm->page_shift = 12;
> > +   DEBUG("Guest physical address width detected: %d\n",
> > + vm->pa_bits);
> > +   }
> 
> How about making this a function that lives in x86_64/processor.c?

Done.  Also I fixed up the overlooked PAE calculation which should be
36 rather than 32 bits PA.

> 
> > +#else
> > +   TEST_ASSERT(false, "VM_MODE_PXXV48_4K not supported on "
> > +   "non-x86 platforms");
> 
> This should make the above aarch64_vcpu_setup() change unnecessary.

I tend to prefer keeping both because if some non-arm arch removed it
then aarch64 has another chance to assert.


RE: [PATCH v2 08/10] PCI: layerscape: Add EP mode support for ls1088a and ls2088a

2019-08-28 Thread Xiaowei Bao


> -Original Message-
> From: Andrew Murray 
> Sent: 2019年8月28日 17:01
> To: Xiaowei Bao 
> Cc: bhelg...@google.com; robh...@kernel.org; mark.rutl...@arm.com;
> shawn...@kernel.org; Leo Li ; kis...@ti.com;
> lorenzo.pieral...@arm.co; a...@arndb.de; gre...@linuxfoundation.org; M.h.
> Lian ; Mingkai Hu ; Roy
> Zang ; jingooh...@gmail.com;
> gustavo.pimen...@synopsys.com; linux-...@vger.kernel.org;
> devicet...@vger.kernel.org; linux-kernel@vger.kernel.org;
> linux-arm-ker...@lists.infradead.org; linuxppc-...@lists.ozlabs.org
> Subject: Re: [PATCH v2 08/10] PCI: layerscape: Add EP mode support for
> ls1088a and ls2088a
> 
> On Wed, Aug 28, 2019 at 04:29:32AM +, Xiaowei Bao wrote:
> >
> >
> > > -Original Message-
> > > From: Andrew Murray 
> > > Sent: 2019年8月27日 21:34
> > > To: Xiaowei Bao 
> > > Cc: bhelg...@google.com; robh...@kernel.org; mark.rutl...@arm.com;
> > > shawn...@kernel.org; Leo Li ; kis...@ti.com;
> > > lorenzo.pieral...@arm.co; a...@arndb.de; gre...@linuxfoundation.org;
> M.h.
> > > Lian ; Mingkai Hu ; Roy
> > > Zang ; jingooh...@gmail.com;
> > > gustavo.pimen...@synopsys.com; linux-...@vger.kernel.org;
> > > devicet...@vger.kernel.org; linux-kernel@vger.kernel.org;
> > > linux-arm-ker...@lists.infradead.org; linuxppc-...@lists.ozlabs.org
> > > Subject: Re: [PATCH v2 08/10] PCI: layerscape: Add EP mode support
> > > for ls1088a and ls2088a
> > >
> > > On Mon, Aug 26, 2019 at 09:49:35AM +, Xiaowei Bao wrote:
> > > >
> > > >
> > > > > -Original Message-
> > > > > From: Andrew Murray 
> > > > > Sent: 2019年8月23日 22:28
> > > > > To: Xiaowei Bao 
> > > > > Cc: bhelg...@google.com; robh...@kernel.org;
> > > > > mark.rutl...@arm.com; shawn...@kernel.org; Leo Li
> > > > > ; kis...@ti.com; lorenzo.pieral...@arm.co;
> > > > > a...@arndb.de; gre...@linuxfoundation.org;
> > > M.h.
> > > > > Lian ; Mingkai Hu ;
> > > > > Roy Zang ; jingooh...@gmail.com;
> > > > > gustavo.pimen...@synopsys.com; linux-...@vger.kernel.org;
> > > > > devicet...@vger.kernel.org; linux-kernel@vger.kernel.org;
> > > > > linux-arm-ker...@lists.infradead.org;
> > > > > linuxppc-...@lists.ozlabs.org
> > > > > Subject: Re: [PATCH v2 08/10] PCI: layerscape: Add EP mode
> > > > > support for ls1088a and ls2088a
> > > > >
> > > > > On Thu, Aug 22, 2019 at 07:22:40PM +0800, Xiaowei Bao wrote:
> > > > > > Add PCIe EP mode support for ls1088a and ls2088a, there are
> > > > > > some difference between LS1 and LS2 platform, so refactor the
> > > > > > code of the EP driver.
> > > > > >
> > > > > > Signed-off-by: Xiaowei Bao 
> > > > > > ---
> > > > > > v2:
> > > > > >  - New mechanism for layerscape EP driver.
> > > > >
> > > > > Was there a v1 of this patch?
> > > > >
> > > > > >
> > > > > >  drivers/pci/controller/dwc/pci-layerscape-ep.c | 76
> > > > > > --
> > > > > >  1 file changed, 58 insertions(+), 18 deletions(-)
> > > > > >
> > > > > > diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > > > > b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > > > > index 7ca5fe8..2a66f07 100644
> > > > > > --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > > > > +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > > > > @@ -20,27 +20,29 @@
> > > > > >
> > > > > >  #define PCIE_DBI2_OFFSET   0x1000  /* DBI2 base address*/
> > > > > >
> > > > > > -struct ls_pcie_ep {
> > > > > > -   struct dw_pcie  *pci;
> > > > > > -   struct pci_epc_features *ls_epc;
> > > > > > +#define to_ls_pcie_ep(x)   dev_get_drvdata((x)->dev)
> > > > > > +
> > > > > > +struct ls_pcie_ep_drvdata {
> > > > > > +   u32 func_offset;
> > > > > > +   const struct dw_pcie_ep_ops *ops;
> > > > > > +   const struct dw_pcie_ops*dw_pcie_ops;
> > > > > >  };
> > > > > >
> > > > > > -#define to_ls_pcie_ep(x)   dev_get_drvdata((x)->dev)
> > > > > > +struct ls_pcie_ep {
> > > > > > +   struct dw_pcie  *pci;
> > > > > > +   struct pci_epc_features *ls_epc;
> > > > > > +   const struct ls_pcie_ep_drvdata *drvdata; };
> > > > > >
> > > > > >  static int ls_pcie_establish_link(struct dw_pcie *pci)  {
> > > > > > return 0;
> > > > > >  }
> > > > > >
> > > > > > -static const struct dw_pcie_ops ls_pcie_ep_ops = {
> > > > > > +static const struct dw_pcie_ops dw_ls_pcie_ep_ops = {
> > > > > > .start_link = ls_pcie_establish_link,  };
> > > > > >
> > > > > > -static const struct of_device_id ls_pcie_ep_of_match[] = {
> > > > > > -   { .compatible = "fsl,ls-pcie-ep",},
> > > > > > -   { },
> > > > > > -};
> > > > > > -
> > > > > >  static const struct pci_epc_features*
> > > > > > ls_pcie_ep_get_features(struct dw_pcie_ep *ep)  { @@ -82,10
> > > > > > +84,44 @@ static int ls_pcie_ep_raise_irq(struct dw_pcie_ep *ep,
> u8 func_no,
> > > > > > }
> > > > > >  }
> > > > > >
> > > > > > -static const struct dw_pcie_ep_ops pcie_ep_ops = {
> > > > > > +static unsigned int ls_pcie_ep_func_conf_select(struct
> > > > > > +dw_pcie_ep
> > 

Re: [RFC PATCH v2 00/19] RDMA/FS DAX truncate proposal V1,000,002 ;-)

2019-08-28 Thread Ira Weiny
On Mon, Aug 26, 2019 at 03:55:10PM +1000, Dave Chinner wrote:
> On Fri, Aug 23, 2019 at 10:08:36PM -0700, Ira Weiny wrote:
> > On Sat, Aug 24, 2019 at 10:11:24AM +1000, Dave Chinner wrote:
> > > On Fri, Aug 23, 2019 at 09:04:29AM -0300, Jason Gunthorpe wrote:
> > >
> > > > IMHO it is wrong to try and create a model where the file lease exists
> > > > independently from the kernel object relying on it. In other words the
> > > > IB MR object itself should hold a reference to the lease it relies
> > > > upon to function properly.
> > > 
> > > That still doesn't work. Leases are not individually trackable or
> > > reference counted objects objects - they are attached to a struct
> > > file bUt, in reality, they are far more restricted than a struct
> > > file.
> > > 
> > > That is, a lease specifically tracks the pid and the _open fd_ it
> > > was obtained for, so it is essentially owned by a specific process
> > > context.  Hence a lease is not able to be passed to a separate
> > > process context and have it still work correctly for lease break
> > > notifications.  i.e. the layout break signal gets delivered to
> > > original process that created the struct file, if it still exists
> > > and has the original fd still open. It does not get sent to the
> > > process that currently holds a reference to the IB context.

But this is an exclusive layout lease which does not send a signal.  There is
no way to break it.

> > >
> > 
> > The fcntl man page says:
> > 
> > "Leases are associated with an open file description (see open(2)).  This 
> > means
> > that duplicate file descriptors (created by, for example, fork(2) or dup(2))
> > refer to the same lease, and this lease may be modified or released using 
> > any
> > of these descriptors.  Furthermore,  the lease is released by either an
> > explicit F_UNLCK operation on any of these duplicate file descriptors, or 
> > when
> > all such file descriptors have been closed."
> 
> Right, the lease is attached to the struct file, so it follows
> where-ever the struct file goes. That doesn't mean it's actually
> useful when the struct file is duplicated and/or passed to another
> process. :/
> 
> AFAICT, the problem is that when we take another reference to the
> struct file, or when the struct file is passed to a different
> process, nothing updates the lease or lease state attached to that
> struct file.

Ok, I probably should have made this more clear in the cover letter but _only_
the process which took the lease can actually pin memory.

That pinned memory _can_ be passed to another process but those sub-process' can
_not_ use the original lease to pin _more_ of the file.  They would need to
take their own lease to do that.

Sorry for not being clear on that.

> 
> > From this I took it that the child process FD would have the lease as well
> > _and_ could release it.  I _assumed_ that applied to SCM_RIGHTS but it does 
> > not
> > seem to work the same way as dup() so I'm not so sure.
> 
> Sure, that part works because the struct file is passed. It doesn't
> end up with the same fd number in the other process, though.
> 
> The issue is that layout leases need to notify userspace when they
> are broken by the kernel, so a lease stores the owner pid/tid in the
> file->f_owner field via __f_setown(). It also keeps a struct fasync
> attached to the file_lock that records the fd that the lease was
> created on.  When a signal needs to be sent to userspace for that
> lease, we call kill_fasync() and that walks the list of fasync
> structures on the lease and calls:
> 
>   send_sigio(fown, fa->fa_fd, band);
> 
> And it does for every fasync struct attached to a lease. Yes, a
> lease can track multiple fds, but it can only track them in a single
> process context. The moment the struct file is shared with another
> process, the lease is no longer capable of sending notifications to
> all the lease holders.
> 
> Yes, you can change the owning process via F_SETOWNER, but that's
> still only a single process context, and you can't change the fd in
> the fasync list. You can add new fd to an existing lease by calling
> F_SETLEASE on the new fd, but you still only have a single process
> owner context for signal delivery.
> 
> As such, leases that require callbacks to userspace are currently
> only valid within the process context the lease was taken in.

But for long term pins we are not requiring callbacks.

> Indeed, even closing the fd the lease was taken on without
> F_UNLCKing it first doesn't mean the lease has been torn down if
> there is some other reference to the struct file. That means the
> original lease owner will still get SIGIO delivered to that fd on a
> lease break regardless of whether it is open or not. ANd if we
> implement "layout lease not released within SIGIO response timeout"
> then that process will get killed, despite the fact it may not even
> have a reference to that file anymore.

I'm not seeing that as a problem.  This is all a result 

Re: [PATCH v6 00/12] implement KASLR for powerpc/fsl_booke/32

2019-08-28 Thread Jason Yan




On 2019/8/28 12:05, Scott Wood wrote:

On Fri, 2019-08-09 at 18:07 +0800, Jason Yan wrote:

This series implements KASLR for powerpc/fsl_booke/32, as a security
feature that deters exploit attempts relying on knowledge of the location
of kernel internals.

Since CONFIG_RELOCATABLE has already supported, what we need to do is
map or copy kernel to a proper place and relocate.


Have you tested this with a kernel that was loaded at a non-zero address?  I
tried loading a kernel at 0x0400 (by changing the address in the uImage,
and setting bootm_low to 0400 in U-Boot), and it works without
CONFIG_RANDOMIZE and fails with.



Not yet. I will test this kind of cases in the next days. Thank you so
much. If there are any other corner cases that have to be tested, please
let me know.


  Freescale Book-E
parts expect lowmem to be mapped by fixed TLB entries(TLB1). The TLB1
entries are not suitable to map the kernel directly in a randomized
region, so we chose to copy the kernel to a proper place and restart to
relocate.

Entropy is derived from the banner and timer base, which will change every
build and boot. This not so much safe so additionally the bootloader may
pass entropy via the /chosen/kaslr-seed node in device tree.


How complicated would it be to directly access the HW RNG (if present) that
early in the boot?  It'd be nice if a U-Boot update weren't required (and
particularly concerning that KASLR would appear to work without a U-Boot
update, but without decent entropy).

-Scott



.





[PATCH v4] watchdog: orion_wdt: use timer1 as a pretimeout

2019-08-28 Thread Chris Packham
The orion watchdog can either reset the CPU or generate an interrupt.
The interrupt would be useful for debugging as it provides panic()
output about the watchdog expiry, however if the interrupt is used the
watchdog can't reset the CPU in the event of being stuck in a loop with
interrupts disabled or if the CPU is prevented from accessing memory
(e.g. an unterminated DMA).

The Armada SoCs have spare timers that aren't currently used by the
Linux kernel. We can use timer1 to provide a pre-timeout ahead of the
watchdog timer and provide the possibility of gathering debug before the
reset triggers.

Signed-off-by: Chris Packham 
---

This was submitted previously[1], the other patches two from the series have
been picked up but this one seems to have fallen through the gaps.

Changes in v3:
- rebase against linux/master
Changes in v2:
- apply changes to armada-38x only

[1] - 
https://lore.kernel.org/linux-watchdog/20190305201924.14853-4-chris.pack...@alliedtelesis.co.nz/

 drivers/watchdog/orion_wdt.c | 59 ++--
 1 file changed, 50 insertions(+), 9 deletions(-)

diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
index cdb0d174c5e2..f2e90bfd7186 100644
--- a/drivers/watchdog/orion_wdt.c
+++ b/drivers/watchdog/orion_wdt.c
@@ -46,6 +46,11 @@
 #define WDT_AXP_FIXED_ENABLE_BIT BIT(10)
 #define WDT_A370_EXPIRED   BIT(31)
 
+#define TIMER1_VAL_OFF 0x001c
+#define TIMER1_ENABLE_BIT  BIT(2)
+#define TIMER1_FIXED_ENABLE_BITBIT(12)
+#define TIMER1_STATUS_BIT  BIT(8)
+
 static bool nowayout = WATCHDOG_NOWAYOUT;
 static int heartbeat = -1; /* module parameter (seconds) */
 
@@ -158,6 +163,7 @@ static int armadaxp_wdt_clock_init(struct platform_device 
*pdev,
   struct orion_watchdog *dev)
 {
int ret;
+   u32 val;
 
dev->clk = of_clk_get_by_name(pdev->dev.of_node, "fixed");
if (IS_ERR(dev->clk))
@@ -169,38 +175,48 @@ static int armadaxp_wdt_clock_init(struct platform_device 
*pdev,
}
 
/* Enable the fixed watchdog clock input */
-   atomic_io_modify(dev->reg + TIMER_CTRL,
-WDT_AXP_FIXED_ENABLE_BIT,
-WDT_AXP_FIXED_ENABLE_BIT);
+   val = WDT_AXP_FIXED_ENABLE_BIT | TIMER1_FIXED_ENABLE_BIT;
+   atomic_io_modify(dev->reg + TIMER_CTRL, val, val);
 
dev->clk_rate = clk_get_rate(dev->clk);
+
return 0;
 }
 
 static int orion_wdt_ping(struct watchdog_device *wdt_dev)
 {
struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
+
/* Reload watchdog duration */
writel(dev->clk_rate * wdt_dev->timeout,
   dev->reg + dev->data->wdt_counter_offset);
+   if (dev->wdt.info->options & WDIOF_PRETIMEOUT)
+   writel(dev->clk_rate * (wdt_dev->timeout - wdt_dev->pretimeout),
+  dev->reg + TIMER1_VAL_OFF);
+
return 0;
 }
 
 static int armada375_start(struct watchdog_device *wdt_dev)
 {
struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
-   u32 reg;
+   u32 reg, val;
 
/* Set watchdog duration */
writel(dev->clk_rate * wdt_dev->timeout,
   dev->reg + dev->data->wdt_counter_offset);
+   if (dev->wdt.info->options & WDIOF_PRETIMEOUT)
+   writel(dev->clk_rate * (wdt_dev->timeout - wdt_dev->pretimeout),
+  dev->reg + TIMER1_VAL_OFF);
 
/* Clear the watchdog expiration bit */
atomic_io_modify(dev->reg + TIMER_A370_STATUS, WDT_A370_EXPIRED, 0);
 
/* Enable watchdog timer */
-   atomic_io_modify(dev->reg + TIMER_CTRL, dev->data->wdt_enable_bit,
-   dev->data->wdt_enable_bit);
+   val = dev->data->wdt_enable_bit;
+   if (dev->wdt.info->options & WDIOF_PRETIMEOUT)
+   val |= TIMER1_ENABLE_BIT;
+   atomic_io_modify(dev->reg + TIMER_CTRL, val, val);
 
/* Enable reset on watchdog */
reg = readl(dev->rstout);
@@ -277,7 +293,7 @@ static int orion_stop(struct watchdog_device *wdt_dev)
 static int armada375_stop(struct watchdog_device *wdt_dev)
 {
struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
-   u32 reg;
+   u32 reg, mask;
 
/* Disable reset on watchdog */
atomic_io_modify(dev->rstout_mask, dev->data->rstout_mask_bit,
@@ -287,7 +303,10 @@ static int armada375_stop(struct watchdog_device *wdt_dev)
writel(reg, dev->rstout);
 
/* Disable watchdog timer */
-   atomic_io_modify(dev->reg + TIMER_CTRL, dev->data->wdt_enable_bit, 0);
+   mask = dev->data->wdt_enable_bit;
+   if (wdt_dev->info->options & WDIOF_PRETIMEOUT)
+   mask += TIMER1_ENABLE_BIT;
+   atomic_io_modify(dev->reg + TIMER_CTRL, mask, 0);
 
return 0;
 }
@@ -349,7 +368,7 @@ static unsigned int orion_wdt_get_timeleft(struct 
watchdog_device *wdt_dev)
return readl(dev->reg + 

Re: linux-next: Tree for Aug 27 (objtool)

2019-08-28 Thread Masami Hiramatsu
Hi Josh,

On Wed, 28 Aug 2019 11:34:33 -0500
Josh Poimboeuf  wrote:

> On Wed, Aug 28, 2019 at 11:13:31AM -0500, Josh Poimboeuf wrote:
> > Turns out this patch does break something:
> > 
> >   arch/x86/xen/enlighten_pv.o: warning: objtool: xen_cpuid()+0x25: can't 
> > find jump dest instruction at .text+0x9c
> > 
> > I'll need to figure out a better way to whitelist that
> > XEN_EMULATE_PREFIX fake instruction thing.  I'll probably just teach
> > the objtool decoder about it.
> 
> Hi Masami,
> 
> Is it possible for the kernel x86 decoder to recognize the
> XEN_EMULATE_PREFIX prefix?
> 
> asm(XEN_EMULATE_PREFIX "cpuid"
> : "=a" (*ax),
>   "=b" (*bx),
>   "=c" (*cx),
>   "=d" (*dx)
> : "0" (*ax), "2" (*cx));
> 
> is disassembled to:
> 
>   33:   0f 0b   ud2
>   35:   78 65   js 9c 
>   37:   6e  outsb  %ds:(%rsi),(%dx)
>   38:   0f a2   cpuid
> 
> which confuses objtool.  Presumably that would confuse other users of
> the decoder as well.

Good catch! It should be problematic, since x86 decoder sanity test is
based on objtool. But I don't want to change the test code itself,
because this problem is highly depending on Xen.

> That's a highly unlikely sequence of instructions, maybe the kernel
> decoder should recognize it as a single instruction.

OK, it is better to be done in decoder (only for CONFIG_XEN_PVHVM)

BTW, could you also share what test case would you using?

And what about attached patch? (just compile checked with/without 
CONFIG_XEN_PVHVM)

Thank you,


-- 
Masami Hiramatsu 
>From 9a46833c54fd320afd3836c0e51ade82e4bc6f96 Mon Sep 17 00:00:00 2001
From: Masami Hiramatsu 
Date: Thu, 29 Aug 2019 10:01:55 +0900
Subject: [PATCH] x86: xen: insn: Decode XEN_EMULATE_PREFIX correctly

Add XEN_EMULATE_PREFIX prefix support to x86 insn decoder.
This treats a special sequence of instructions of XEN_EMULATE_PREFIX
as a prefix bytes in x86 insn decoder only if CONFIG_XEN_PVHVM=y.
Note that this prefix is treated as just a dummy code.

Reported-by: Josh Poimboeuf 
Signed-off-by: Masami Hiramatsu 
---
 arch/x86/include/asm/xen/interface.h |  8 +--
 arch/x86/lib/insn.c  | 35 
 2 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/xen/interface.h b/arch/x86/include/asm/xen/interface.h
index 62ca03ef5c65..fbee520b1f07 100644
--- a/arch/x86/include/asm/xen/interface.h
+++ b/arch/x86/include/asm/xen/interface.h
@@ -27,6 +27,8 @@
 #ifndef _ASM_X86_XEN_INTERFACE_H
 #define _ASM_X86_XEN_INTERFACE_H
 
+#include 
+
 /*
  * XEN_GUEST_HANDLE represents a guest pointer, when passed as a field
  * in a struct in memory.
@@ -379,11 +381,13 @@ struct xen_pmu_arch {
  * Prefix forces emulation of some non-trapping instructions.
  * Currently only CPUID.
  */
+#define __XEN_EMULATE_PREFIX  0x0f,0x0b,0x78,0x65,0x6e
+#define __XEN_EMULATE_PREFIX_STR  __stringify(__XEN_EMULATE_PREFIX)
 #ifdef __ASSEMBLY__
-#define XEN_EMULATE_PREFIX .byte 0x0f,0x0b,0x78,0x65,0x6e ;
+#define XEN_EMULATE_PREFIX .byte __XEN_EMULATE_PREFIX ;
 #define XEN_CPUID  XEN_EMULATE_PREFIX cpuid
 #else
-#define XEN_EMULATE_PREFIX ".byte 0x0f,0x0b,0x78,0x65,0x6e ; "
+#define XEN_EMULATE_PREFIX ".byte " __XEN_EMULATE_PREFIX_STR " ; "
 #define XEN_CPUID  XEN_EMULATE_PREFIX "cpuid"
 #endif
 
diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c
index 0b5862ba6a75..2401a6fc9509 100644
--- a/arch/x86/lib/insn.c
+++ b/arch/x86/lib/insn.c
@@ -7,6 +7,9 @@
 
 #ifdef __KERNEL__
 #include 
+#include 
+/* For special Xen prefix */
+#include 
 #else
 #include 
 #endif
@@ -58,6 +61,34 @@ void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64)
 		insn->addr_bytes = 4;
 }
 
+#ifdef CONFIG_XEN_PVHVM
+static const insn_byte_t xen_prefix[] = { XEN_EMULATE_PREFIX };
+
+static int insn_xen_prefix(struct insn *insn, insn_byte_t b)
+{
+	struct insn_field *prefixes = >prefixes;
+	int i = 0;
+
+	while (i < ARRAY_SIZE(xen_prefix) && b == xen_prefix[i])
+		b = peek_nbyte_next(insn_byte_t, insn, ++i);
+
+	if (unlikely(i == ARRAY_SIZE(xen_prefix))) {
+		memcpy(prefixes->bytes, xen_prefix, 3);
+		prefixes->bytes[3] = xen_prefix[ARRAY_SIZE(xen_prefix) - 1];
+		prefixes->nbytes = ARRAY_SIZE(xen_prefix);
+		insn->next_byte += prefixes->nbytes;
+		prefixes->got = 1;
+
+		return 1;
+	}
+
+err_out:
+	return 0;
+}
+#else
+#define insn_xen_prefix(insn,b)	(0)
+#endif
+
 /**
  * insn_get_prefixes - scan x86 instruction prefix bytes
  * @insn:	 insn containing instruction
@@ -79,6 +110,10 @@ void insn_get_prefixes(struct insn *insn)
 	nb = 0;
 	lb = 0;
 	b = peek_next(insn_byte_t, insn);
+
+	if (insn_xen_prefix(insn, b))
+		return;
+
 	attr = inat_get_opcode_attribute(b);
 	while (inat_is_legacy_prefix(attr)) {
 		/* Skip if same prefix */
-- 
2.20.1



[PATCH] um: Rewrite host RNG driver.

2019-08-28 Thread Alexander Neville
The old driver had a bug that would cause it to outright stop working if
the host's /dev/random were to block. Instead of trying to track down
the cause of said bug, rewriting it from scratch turned out to be a much
better option as it came with a few benefits:

 - The new driver properly registers itself as an hardware RNG.

 - The code is simpler and therefore easier to maintain.

 - It serves as a minimal example of writing a hardware RNG driver.

I also edited the Kconfig symbol to bring it up to more modern
standards.

Signed-off-by: Alexander Neville 
---
 arch/um/drivers/Makefile   |   3 +-
 arch/um/drivers/random.c   | 192 -
 drivers/char/hw_random/Kconfig |  21 ++--
 3 files changed, 59 insertions(+), 157 deletions(-)

diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
index 693319839f69..29b0364f267d 100644
--- a/arch/um/drivers/Makefile
+++ b/arch/um/drivers/Makefile
@@ -17,6 +17,7 @@ hostaudio-objs := hostaudio_kern.o
 ubd-objs := ubd_kern.o ubd_user.o
 port-objs := port_kern.o port_user.o
 harddog-objs := harddog_kern.o harddog_user.o
+uml-rng-objs := random.o
 
 LDFLAGS_pcap.o := -r $(shell $(CC) $(KBUILD_CFLAGS) -print-file-name=libpcap.a)
 
@@ -60,7 +61,7 @@ obj-$(CONFIG_TTY_CHAN) += tty.o
 obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
 obj-$(CONFIG_UML_WATCHDOG) += harddog.o
 obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
-obj-$(CONFIG_UML_RANDOM) += random.o
+obj-$(CONFIG_UML_RANDOM) += uml-rng.o
 
 # pcap_user.o must be added explicitly.
 USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o pcap_user.o 
vde_user.o vector_user.o
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
index 1d5d3057e6f1..7a3099277ebd 100644
--- a/arch/um/drivers/random.c
+++ b/arch/um/drivers/random.c
@@ -1,175 +1,75 @@
-/* Copyright (C) 2005 - 2008 Jeff Dike  */
-
-/* Much of this ripped from drivers/char/hw_random.c, see there for other
- * copyright.
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * UML Host RNG Driver
+ *
+ * (c) Copright 2019 Alexander Neville 
  *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
  */
-#include 
+
+#include 
+#include 
 #include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
+#include 
+#include 
 #include 
 
-/*
- * core module and version information
- */
-#define RNG_VERSION "1.0.0"
-#define RNG_MODULE_NAME "hw_random"
-
-#define RNG_MISCDEV_MINOR  183 /* official */
-
-/* Changed at init time, in the non-modular case, and at module load
- * time, in the module case.  Presumably, the module subsystem
- * protects against a module being loaded twice at the same time.
- */
-static int random_fd = -1;
-static DECLARE_WAIT_QUEUE_HEAD(host_read_wait);
-
-static int rng_dev_open (struct inode *inode, struct file *filp)
+static int uml_rng_read(struct hwrng *rng, void *data, size_t bufsize,
+   bool wait)
 {
-   /* enforce read-only access to this chrdev */
-   if ((filp->f_mode & FMODE_READ) == 0)
-   return -EINVAL;
-   if ((filp->f_mode & FMODE_WRITE) != 0)
-   return -EINVAL;
-
-   return 0;
+   return os_read_file(rng->priv, data, bufsize);
 }
 
-static atomic_t host_sleep_count = ATOMIC_INIT(0);
-
-static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size,
-loff_t *offp)
+static int uml_rng_init(struct hwrng *rng)
 {
-   u32 data;
-   int n, ret = 0, have_data;
-
-   while (size) {
-   n = os_read_file(random_fd, , sizeof(data));
-   if (n > 0) {
-   have_data = n;
-   while (have_data && size) {
-   if (put_user((u8) data, buf++)) {
-   ret = ret ? : -EFAULT;
-   break;
-   }
-   size--;
-   ret++;
-   have_data--;
-   data >>= 8;
-   }
-   }
-   else if (n == -EAGAIN) {
-   DECLARE_WAITQUEUE(wait, current);
-
-   if (filp->f_flags & O_NONBLOCK)
-   return ret ? : -EAGAIN;
-
-   atomic_inc(_sleep_count);
-   add_sigio_fd(random_fd);
-
-   add_wait_queue(_read_wait, );
-   set_current_state(TASK_INTERRUPTIBLE);
-
-   schedule();
-   remove_wait_queue(_read_wait, );
-
-   if (atomic_dec_and_test(_sleep_count)) {
- 

[PATCH v14 08/10] soc: mediatek: cmdq: add polling function

2019-08-28 Thread Bibby Hsieh
add polling function in cmdq helper functions

Signed-off-by: Bibby Hsieh 
Reviewed-by: CK Hu 
Reviewed-by: Houlong Wei 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   | 30 ++
 include/linux/mailbox/mtk-cmdq-mailbox.h |  1 +
 include/linux/soc/mediatek/mtk-cmdq.h| 32 
 3 files changed, 63 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 9472526ab076..bec7bb6c3988 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -211,6 +211,36 @@ int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event)
 }
 EXPORT_SYMBOL(cmdq_pkt_clear_event);
 
+int cmdq_pkt_poll(struct cmdq_pkt *pkt, u8 subsys,
+ u16 offset, u32 value)
+{
+   struct cmdq_instruction inst;
+
+   inst.op = CMDQ_CODE_POLL;
+   inst.value = value;
+   inst.offset = offset;
+   inst.subsys = subsys;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_poll);
+
+int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
+  u16 offset, u32 value, u32 mask)
+{
+   struct cmdq_instruction inst = { {0} };
+   int err = 0;
+
+   inst.op = CMDQ_CODE_MASK;
+   inst.mask = ~mask;
+   err = cmdq_pkt_append_command(pkt, inst);
+   offset = offset | 0x1;
+   err |= cmdq_pkt_poll(pkt, subsys, offset, value);
+
+   return err;
+}
+EXPORT_SYMBOL(cmdq_pkt_poll_mask);
+
 static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 678760548791..a4dc45fbec0a 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -55,6 +55,7 @@
 enum cmdq_code {
CMDQ_CODE_MASK = 0x02,
CMDQ_CODE_WRITE = 0x04,
+   CMDQ_CODE_POLL = 0x08,
CMDQ_CODE_JUMP = 0x10,
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 9618debb9ceb..92bd5b5c6341 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -99,6 +99,38 @@ int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event);
  */
 int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event);
 
+/**
+ * cmdq_pkt_poll() - Append polling command to the CMDQ packet, ask GCE to
+ *  execute an instruction that wait for a specified
+ *  hardware register to check for the value w/o mask.
+ *  All GCE hardware threads will be blocked by this
+ *  instruction.
+ * @pkt:   the CMDQ packet
+ * @subsys:the CMDQ sub system code
+ * @offset:register offset from CMDQ sub system
+ * @value: the specified target register value
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_poll(struct cmdq_pkt *pkt, u8 subsys,
+ u16 offset, u32 value);
+
+/**
+ * cmdq_pkt_poll_mask() - Append polling command to the CMDQ packet, ask GCE to
+ *   execute an instruction that wait for a specified
+ *   hardware register to check for the value w/ mask.
+ *   All GCE hardware threads will be blocked by this
+ *   instruction.
+ * @pkt:   the CMDQ packet
+ * @subsys:the CMDQ sub system code
+ * @offset:register offset from CMDQ sub system
+ * @value: the specified target register value
+ * @mask:  the specified target register mask
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
+  u16 offset, u32 value, u32 mask);
 /**
  * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
  *  packet and call back at the end of done packet
-- 
2.18.0



[PATCH v14 03/10] dt-binding: gce: add binding for gce client reg property

2019-08-28 Thread Bibby Hsieh
cmdq driver provide a function that get the relationship
of sub system number from device node for client.
add specification for #subsys-cells, mediatek,gce-client-reg.

Signed-off-by: Bibby Hsieh 
Reviewed-by: Rob Herring 
---
 .../devicetree/bindings/mailbox/mtk-gce.txt  | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt 
b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
index 1f7f8f2a3f49..7b13787ab13d 100644
--- a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
+++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
@@ -25,8 +25,16 @@ Required properties:
 Required properties for a client device:
 - mboxes: Client use mailbox to communicate with GCE, it should have this
   property and list of phandle, mailbox specifiers.
-- mediatek,gce-subsys: u32, specify the sub-system id which is corresponding
-  to the register address.
+Optional properties for a client device:
+- mediatek,gce-client-reg: Specify the sub-system id which is corresponding
+  to the register address, it should have this property and list of phandle,
+  sub-system specifiers.
+  < subsys_number start_offset size>
+  phandle: Label name of a gce node.
+  subsys_number: specify the sub-system id which is corresponding
+ to the register address.
+  start_offset: the start offset of register address that GCE can access.
+  size: the total size of register address that GCE can access.
 
 Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h'
 or 'dt-binding/gce/mt8183-gce.h'. Such as sub-system ids, thread priority, 
event ids.
@@ -48,9 +56,9 @@ Example for a client device:
compatible = "mediatek,mt8173-mmsys";
mboxes = < 0 CMDQ_THR_PRIO_LOWEST 1>,
 < 1 CMDQ_THR_PRIO_LOWEST 1>;
-   mediatek,gce-subsys = ;
mutex-event-eof = ;
-
+   mediatek,gce-client-reg = < SUBSYS_1400 0x3000 0x1000>,
+ < SUBSYS_1401 0x2000 0x100>;
...
};
-- 
2.18.0



[PATCH v14 02/10] dt-binding: gce: add gce header file for mt8183

2019-08-28 Thread Bibby Hsieh
Add documentation for the mt8183 gce.

Add gce header file defined the gce hardware event,
subsys number and constant for mt8183.

Signed-off-by: Bibby Hsieh 
Reviewed-by: Rob Herring 
---
 .../devicetree/bindings/mailbox/mtk-gce.txt   |   6 +-
 include/dt-bindings/gce/mt8183-gce.h  | 175 ++
 2 files changed, 178 insertions(+), 3 deletions(-)
 create mode 100644 include/dt-bindings/gce/mt8183-gce.h

diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt 
b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
index cfe40b01d164..1f7f8f2a3f49 100644
--- a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
+++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
@@ -9,7 +9,7 @@ CMDQ driver uses mailbox framework for communication. Please 
refer to
 mailbox.txt for generic information about mailbox device-tree bindings.
 
 Required properties:
-- compatible: Must be "mediatek,mt8173-gce"
+- compatible: can be "mediatek,mt8173-gce" or "mediatek,mt8183-gce"
 - reg: Address range of the GCE unit
 - interrupts: The interrupt signal from the GCE block
 - clock: Clocks according to the common clock binding
@@ -28,8 +28,8 @@ Required properties for a client device:
 - mediatek,gce-subsys: u32, specify the sub-system id which is corresponding
   to the register address.
 
-Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h'. Such 
as
-sub-system ids, thread priority, event ids.
+Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h'
+or 'dt-binding/gce/mt8183-gce.h'. Such as sub-system ids, thread priority, 
event ids.
 
 Example:
 
diff --git a/include/dt-bindings/gce/mt8183-gce.h 
b/include/dt-bindings/gce/mt8183-gce.h
new file mode 100644
index ..29c967476f73
--- /dev/null
+++ b/include/dt-bindings/gce/mt8183-gce.h
@@ -0,0 +1,175 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Bibby Hsieh 
+ *
+ */
+
+#ifndef _DT_BINDINGS_GCE_MT8183_H
+#define _DT_BINDINGS_GCE_MT8183_H
+
+#define CMDQ_NO_TIMEOUT0x
+
+/* GCE HW thread priority */
+#define CMDQ_THR_PRIO_LOWEST   0
+#define CMDQ_THR_PRIO_HIGHEST  1
+
+/* GCE SUBSYS */
+#define SUBSYS_13000
+#define SUBSYS_14001
+#define SUBSYS_14012
+#define SUBSYS_14023
+#define SUBSYS_15024
+#define SUBSYS_18805
+#define SUBSYS_18816
+#define SUBSYS_18827
+#define SUBSYS_18838
+#define SUBSYS_18849
+#define SUBSYS_100010
+#define SUBSYS_100111
+#define SUBSYS_100212
+#define SUBSYS_100313
+#define SUBSYS_100414
+#define SUBSYS_100515
+#define SUBSYS_102016
+#define SUBSYS_102817
+#define SUBSYS_170018
+#define SUBSYS_170119
+#define SUBSYS_170220
+#define SUBSYS_170321
+#define SUBSYS_180022
+#define SUBSYS_180123
+#define SUBSYS_180224
+#define SUBSYS_180425
+#define SUBSYS_180526
+#define SUBSYS_180827
+#define SUBSYS_180a28
+#define SUBSYS_180b29
+
+#define CMDQ_EVENT_DISP_RDMA0_SOF  0
+#define CMDQ_EVENT_DISP_RDMA1_SOF  1
+#define CMDQ_EVENT_MDP_RDMA0_SOF   2
+#define CMDQ_EVENT_MDP_RSZ0_SOF
4
+#define CMDQ_EVENT_MDP_RSZ1_SOF
5
+#define CMDQ_EVENT_MDP_TDSHP_SOF   6
+#define CMDQ_EVENT_MDP_WROT0_SOF   7
+#define CMDQ_EVENT_MDP_WDMA0_SOF   8
+#define CMDQ_EVENT_DISP_OVL0_SOF   9
+#define CMDQ_EVENT_DISP_OVL0_2L_SOF10
+#define CMDQ_EVENT_DISP_OVL1_2L_SOF11
+#define CMDQ_EVENT_DISP_WDMA0_SOF  12
+#define CMDQ_EVENT_DISP_COLOR0_SOF 13
+#define CMDQ_EVENT_DISP_CCORR0_SOF 14
+#define CMDQ_EVENT_DISP_AAL0_SOF   15
+#define CMDQ_EVENT_DISP_GAMMA0_SOF 16
+#define CMDQ_EVENT_DISP_DITHER0_SOF17
+#define CMDQ_EVENT_DISP_PWM0_SOF   18
+#define CMDQ_EVENT_DISP_DSI0_SOF   19
+#define CMDQ_EVENT_DISP_DPI0_SOF   20

[PATCH v14 07/10] soc: mediatek: cmdq: define the instruction struct

2019-08-28 Thread Bibby Hsieh
Define an instruction structure for gce driver to append command.
This structure can make the client's code more readability.

Signed-off-by: Bibby Hsieh 
Reviewed-by: CK Hu 
Reviewed-by: Houlong Wei 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   | 77 
 include/linux/mailbox/mtk-cmdq-mailbox.h | 10 +++
 2 files changed, 61 insertions(+), 26 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 7aa0517ff2f3..9472526ab076 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -9,12 +9,24 @@
 #include 
 #include 
 
-#define CMDQ_ARG_A_WRITE_MASK  0x
 #define CMDQ_WRITE_ENABLE_MASK BIT(0)
 #define CMDQ_EOC_IRQ_ENBIT(0)
 #define CMDQ_EOC_CMD   ((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
<< 32 | CMDQ_EOC_IRQ_EN)
 
+struct cmdq_instruction {
+   union {
+   u32 value;
+   u32 mask;
+   };
+   union {
+   u16 offset;
+   u16 event;
+   };
+   u8 subsys;
+   u8 op;
+};
+
 static void cmdq_client_timeout(struct timer_list *t)
 {
struct cmdq_client *client = from_timer(client, t, timer);
@@ -110,10 +122,10 @@ void cmdq_pkt_destroy(struct cmdq_pkt *pkt)
 }
 EXPORT_SYMBOL(cmdq_pkt_destroy);
 
-static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
-  u32 arg_a, u32 arg_b)
+static int cmdq_pkt_append_command(struct cmdq_pkt *pkt,
+  struct cmdq_instruction inst)
 {
-   u64 *cmd_ptr;
+   struct cmdq_instruction *cmd_ptr;
 
if (unlikely(pkt->cmd_buf_size + CMDQ_INST_SIZE > pkt->buf_size)) {
/*
@@ -129,8 +141,9 @@ static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, 
enum cmdq_code code,
__func__, (u32)pkt->buf_size);
return -ENOMEM;
}
+
cmd_ptr = pkt->va_base + pkt->cmd_buf_size;
-   (*cmd_ptr) = (u64)((code << CMDQ_OP_CODE_SHIFT) | arg_a) << 32 | arg_b;
+   *cmd_ptr = inst;
pkt->cmd_buf_size += CMDQ_INST_SIZE;
 
return 0;
@@ -138,24 +151,31 @@ static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, 
enum cmdq_code code,
 
 int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value)
 {
-   u32 arg_a = (offset & CMDQ_ARG_A_WRITE_MASK) |
-   (subsys << CMDQ_SUBSYS_SHIFT);
+   struct cmdq_instruction inst;
+
+   inst.op = CMDQ_CODE_WRITE;
+   inst.value = value;
+   inst.offset = offset;
+   inst.subsys = subsys;
 
-   return cmdq_pkt_append_command(pkt, CMDQ_CODE_WRITE, arg_a, value);
+   return cmdq_pkt_append_command(pkt, inst);
 }
 EXPORT_SYMBOL(cmdq_pkt_write);
 
 int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
u16 offset, u32 value, u32 mask)
 {
-   u32 offset_mask = offset;
+   struct cmdq_instruction inst = { {0} };
+   u16 offset_mask = offset;
int err = 0;
 
if (mask != 0x) {
-   err = cmdq_pkt_append_command(pkt, CMDQ_CODE_MASK, 0, ~mask);
+   inst.op = CMDQ_CODE_MASK;
+   inst.mask = ~mask;
+   err = cmdq_pkt_append_command(pkt, inst);
offset_mask |= CMDQ_WRITE_ENABLE_MASK;
}
-   err |= cmdq_pkt_write(pkt, value, subsys, offset_mask);
+   err |= cmdq_pkt_write(pkt, subsys, offset_mask, value);
 
return err;
 }
@@ -163,43 +183,48 @@ EXPORT_SYMBOL(cmdq_pkt_write_mask);
 
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
-   u32 arg_b;
+   struct cmdq_instruction inst = { {0} };
 
if (event >= CMDQ_MAX_EVENT)
return -EINVAL;
 
-   /*
-* WFE arg_b
-* bit 0-11: wait value
-* bit 15: 1 - wait, 0 - no wait
-* bit 16-27: update value
-* bit 31: 1 - update, 0 - no update
-*/
-   arg_b = CMDQ_WFE_UPDATE | CMDQ_WFE_WAIT | CMDQ_WFE_WAIT_VALUE;
+   inst.op = CMDQ_CODE_WFE;
+   inst.value = CMDQ_WFE_OPTION;
+   inst.event = event;
 
-   return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event, arg_b);
+   return cmdq_pkt_append_command(pkt, inst);
 }
 EXPORT_SYMBOL(cmdq_pkt_wfe);
 
 int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event)
 {
+   struct cmdq_instruction inst = { {0} };
+
if (event >= CMDQ_MAX_EVENT)
return -EINVAL;
 
-   return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event,
-  CMDQ_WFE_UPDATE);
+   inst.op = CMDQ_CODE_WFE;
+   inst.value = CMDQ_WFE_UPDATE;
+   inst.event = event;
+
+   return cmdq_pkt_append_command(pkt, inst);
 }
 EXPORT_SYMBOL(cmdq_pkt_clear_event);
 
 static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
-   int err;
+   struct cmdq_instruction inst = { {0} };
+   int err = 0;
 
/* insert 

  1   2   3   4   5   6   7   8   9   10   >