Re: [PATCH] net: sky2: switch from 'pci_' to 'dma_' API

2020-07-12 Thread Julia Lawall


On Sun, 12 Jul 2020, Christophe JAILLET wrote:

> Le 12/07/2020 à 08:32, Joe Perches a écrit :
> > On Sun, 2020-07-12 at 08:29 +0200, Christophe JAILLET wrote:
> > > Le 11/07/2020 à 23:20, Joe Perches a écrit :
> > > > On Sat, 2020-07-11 at 22:49 +0200, Christophe JAILLET wrote:
> > > > > The wrappers in include/linux/pci-dma-compat.h should go away.
> > > > why?
> > > >
> > > >
> > >   From Christoph Hellwig
> > > https://marc.info/?l=kernel-janitors&m=158745678307186&w=4
> > There's no why there.
> > There's just an assertion a wrapper should "go away".
> >
> > "the wrappers in include/linux/pci-dma-compat.h should go away"
> >
> > wrappers aren't all bad.
> >
> >
> Adding Christoph Hellwig to shed some light.

Neither the wrapped name nor the unwrapped name is higher or lower level.
Nothing much happens to the arguments.  The wrappers and the wrapped
functions are not used entirely consistently, eg some files, and perhaps
even some functions, use a mixture of the two.  There a set of confusingly
named constants associated with the two sets of functions, and these
constants are also not always used consistently.

julia

[PATCH] Staging: comedi: driver: Remove condition with no effect

2020-07-12 Thread Saurav Girepunje
Remove below warning in das1800.c
WARNING: possible condition with no effect (if == else)

Signed-off-by: Saurav Girepunje 
---
 drivers/staging/comedi/drivers/das1800.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/staging/comedi/drivers/das1800.c 
b/drivers/staging/comedi/drivers/das1800.c
index f16aa7e9f4f3..7ab72e83d3d0 100644
--- a/drivers/staging/comedi/drivers/das1800.c
+++ b/drivers/staging/comedi/drivers/das1800.c
@@ -1299,12 +1299,6 @@ static int das1800_attach(struct comedi_device *dev,
outb(DAC(i), dev->iobase + DAS1800_SELECT);
outw(0, dev->iobase + DAS1800_DAC);
}
-   } else if (board->id == DAS1800_ID_AO) {
-   /*
-* 'ao' boards have waveform analog outputs that are not
-* currently supported.
-*/
-   s->type = COMEDI_SUBD_UNUSED;
} else {
s->type = COMEDI_SUBD_UNUSED;
}
-- 
2.20.1



[no subject]

2020-07-12 Thread Jacob Wen

unsubscribe linux-kernel



Re: [PATCH RFC] leds: Add support for per-LED device triggers

2020-07-12 Thread Pavel Machek
On Sat 2020-07-11 23:01:11, Ondřej Jirman wrote:
> Hello Pavel,
> 
> On Sat, Jul 11, 2020 at 12:04:09PM +0200, Pavel Machek wrote:
> > Hi!
> > 
> > > Some LED controllers may come with an internal HW triggering mechanism
> > > for the LED and an ability to switch between user control of the LED,
> > > or the internal control. One such example is AXP20X PMIC, that allows
> > > wither for user control of the LED, or for internal control based on
> > > the state of the battery charger.
> > > 
> > > Add support for registering per-LED device trigger.
> > > 
> > > Names of private triggers need to be globally unique, but may clash
> > > with other private triggers. This is enforced during trigger
> > > registration. Developers can register private triggers just like
> > > the normal triggers, by setting private_led to a classdev
> > > of the LED the trigger is associated with.
> > 
> > What about this? Should address Marek's concerns about resource use...
> 
> What concerns? Marek's concerns seem to be about case where we register
> a trigger for (each led * self-working configuration) which I admit
> can be quite a lot of triggers if there are many functions. But that's
> not my proposal.
> 
> My proposal is to only register on trigger per LED at most. So on my
> system that's 1 extra trigger and on Marek's system that'd be 48 new
> triggers. Neither seems like a meaningful problem from resource
> use perspective.

So.. 48 triggers on Marek's systems means I'll not apply your patch.

Please take a look at my version, it is as simple and avoids that
problem.

If it works for you, you can submit it properly and I'll likely accept
it.

Best regards,
Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: PGP signature


Re: [PATCH v1] Bluetooth: Fix kernel oops triggered by hci_adv_monitors_clear()

2020-07-12 Thread Pavel Machek
On Tue 2020-07-07 17:38:46, Marcel Holtmann wrote:
> Hi Miao-chen,
> 
> > This fixes the kernel oops by removing unnecessary background scan
> > update from hci_adv_monitors_clear() which shouldn't invoke any work
> > queue.
> > 
> > The following test was performed.
> > - Run "rmmod btusb" and verify that no kernel oops is triggered.
> > 
> > Signed-off-by: Miao-chen Chou 
> > Reviewed-by: Abhishek Pandit-Subedi 
> > Reviewed-by: Alain Michaud 
> > ---
> > 
> > net/bluetooth/hci_core.c | 2 --
> > 1 file changed, 2 deletions(-)
> 
> patch has been applied to bluetooth-next tree.

Bluetooth no longer seems to oops for me... but there's different
showstopper in next (graphics -- i915 -- related). Oh well :-(.

Pavel

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


[PATCH] ARM: dts: vf610-zii-spb4: Add node for switch watchdog

2020-07-12 Thread Chris Healy
Add I2C child node for switch watchdog present on SPB4

Signed-off-by: Chris Healy 
---
 arch/arm/boot/dts/vf610-zii-spb4.dts | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm/boot/dts/vf610-zii-spb4.dts 
b/arch/arm/boot/dts/vf610-zii-spb4.dts
index a68eae88174a..9e5187ba3fa6 100644
--- a/arch/arm/boot/dts/vf610-zii-spb4.dts
+++ b/arch/arm/boot/dts/vf610-zii-spb4.dts
@@ -209,6 +209,18 @@
};
 };
 
+&i2c1 {
+   clock-frequency = <10>;
+   pinctrl-names = "default";
+   pinctrl-0 = <&pinctrl_i2c1>;
+   status = "okay";
+
+   watchdog@38 {
+   compatible = "zii,rave-wdt";
+   reg = <0x38>;
+   };
+};
+
 &snvsrtc {
status = "disabled";
 };
@@ -326,6 +338,13 @@
>;
};
 
+   pinctrl_i2c1: i2c1grp {
+   fsl,pins = <
+   VF610_PAD_PTB16__I2C1_SCL   0x37ff
+   VF610_PAD_PTB17__I2C1_SDA   0x37ff
+   >;
+   };
+
pinctrl_leds_debug: pinctrl-leds-debug {
fsl,pins = <
VF610_PAD_PTD3__GPIO_82 0x31c2
-- 
2.21.3



Re: [PATCH 1/1] leds: fix spelling mistake

2020-07-12 Thread Pavel Machek
On Wed 2020-06-10 08:16:31, Alexander Dahl wrote:
> That one made me laugh. :-)
> 
> Reviewed-by: Alexander Dahl 

:-).

Applied.
Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


Re: [PATCH] leds: trigger: gpio: Avoid warning on update of inverted

2020-07-12 Thread Pavel Machek
On Sat 2020-06-13 09:15:06, Jan Kiszka wrote:
> From: Jan Kiszka 
> 
> If the GPIO has not been configured yet, writing to inverted will raise
> a kernel warning.
> 
> Signed-off-by: Jan Kiszka 

Thanks, applied.
Pavel

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


Re: [PATCH v2] leds: core: Flush scheduled work for system suspend

2020-07-12 Thread Pavel Machek
Hi!

> >  EXPORT_SYMBOL_GPL(led_classdev_suspend);
> >
> 
> Acked-by: Jacek Anaszewski 
> 
> Pavel, this needs to go to stable as well, so let's add the tag:
> 
> Fixes: 81fe8e5b73e3 ("leds: core: Add led_set_brightness_nosleep{nopm}
> functions")

Applied, and I added the tag (thanks).

Documentation says stable is for "very bad" bugs, but ... stable
maintainers ignore documenation.

Best regards,
Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


drivers/gpu/drm/mediatek/mtk_dpi.c:721:2-9: line 721 is redundant because platform_get_irq() already prints an error (fwd)

2020-07-12 Thread Julia Lawall


-- Forwarded message --
Date: Sun, 12 Jul 2020 11:15:29 +0800
From: kernel test robot 
To: kbu...@lists.01.org
Cc: l...@intel.com, Julia Lawall 
Subject: drivers/gpu/drm/mediatek/mtk_dpi.c:721:2-9: line 721 is redundant
because platform_get_irq() already prints an error

CC: kbuild-...@lists.01.org
CC: linux-kernel@vger.kernel.org
TO: YueHaibing 
CC: "Greg Kroah-Hartman" 
CC: Stephen Boyd 

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 
master
head:   0aea6d5c5be33ce94c16f9ab2f64de1f481f424b
commit: ca7ce5a2710ad2a57bf7d0c4c712590bb69a5e1c coccinelle: platform_get_irq: 
Fix parse error
date:   10 months ago
:: branch date: 9 hours ago
:: commit date: 10 months ago
config: arm64-randconfig-c022-20200711 (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0

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


coccinelle warnings: (new ones prefixed by >>)

>> drivers/gpu/drm/mediatek/mtk_dpi.c:721:2-9: line 721 is redundant because 
>> platform_get_irq() already prints an error
--
>> drivers/gpu/drm/mediatek/mtk_dsi.c:1159:2-9: line 1159 is redundant because 
>> platform_get_irq() already prints an error

# 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ca7ce5a2710ad2a57bf7d0c4c712590bb69a5e1c
git remote add linus 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
git remote update linus
git checkout ca7ce5a2710ad2a57bf7d0c4c712590bb69a5e1c
vim +721 drivers/gpu/drm/mediatek/mtk_dpi.c

d08b5ab972449b0 chunhui dai 2018-10-03  674
9e629c17aa8d7a7 Jie Qiu 2016-01-04  675  static int mtk_dpi_probe(struct 
platform_device *pdev)
9e629c17aa8d7a7 Jie Qiu 2016-01-04  676  {
9e629c17aa8d7a7 Jie Qiu 2016-01-04  677 struct device *dev = &pdev->dev;
9e629c17aa8d7a7 Jie Qiu 2016-01-04  678 struct mtk_dpi *dpi;
9e629c17aa8d7a7 Jie Qiu 2016-01-04  679 struct resource *mem;
9e629c17aa8d7a7 Jie Qiu 2016-01-04  680 int comp_id;
9e629c17aa8d7a7 Jie Qiu 2016-01-04  681 int ret;
9e629c17aa8d7a7 Jie Qiu 2016-01-04  682
9e629c17aa8d7a7 Jie Qiu 2016-01-04  683 dpi = devm_kzalloc(dev, 
sizeof(*dpi), GFP_KERNEL);
9e629c17aa8d7a7 Jie Qiu 2016-01-04  684 if (!dpi)
9e629c17aa8d7a7 Jie Qiu 2016-01-04  685 return -ENOMEM;
9e629c17aa8d7a7 Jie Qiu 2016-01-04  686
9e629c17aa8d7a7 Jie Qiu 2016-01-04  687 dpi->dev = dev;
0ace4b993c7a524 chunhui dai 2018-10-03  688 dpi->conf = (struct 
mtk_dpi_conf *)of_device_get_match_data(dev);
9e629c17aa8d7a7 Jie Qiu 2016-01-04  689
9e629c17aa8d7a7 Jie Qiu 2016-01-04  690 mem = 
platform_get_resource(pdev, IORESOURCE_MEM, 0);
9e629c17aa8d7a7 Jie Qiu 2016-01-04  691 dpi->regs = 
devm_ioremap_resource(dev, mem);
9e629c17aa8d7a7 Jie Qiu 2016-01-04  692 if (IS_ERR(dpi->regs)) {
9e629c17aa8d7a7 Jie Qiu 2016-01-04  693 ret = 
PTR_ERR(dpi->regs);
9e629c17aa8d7a7 Jie Qiu 2016-01-04  694 dev_err(dev, "Failed to 
ioremap mem resource: %d\n", ret);
9e629c17aa8d7a7 Jie Qiu 2016-01-04  695 return ret;
9e629c17aa8d7a7 Jie Qiu 2016-01-04  696 }
9e629c17aa8d7a7 Jie Qiu 2016-01-04  697
9e629c17aa8d7a7 Jie Qiu 2016-01-04  698 dpi->engine_clk = 
devm_clk_get(dev, "engine");
9e629c17aa8d7a7 Jie Qiu 2016-01-04  699 if (IS_ERR(dpi->engine_clk)) {
9e629c17aa8d7a7 Jie Qiu 2016-01-04  700 ret = 
PTR_ERR(dpi->engine_clk);
9e629c17aa8d7a7 Jie Qiu 2016-01-04  701 dev_err(dev, "Failed to 
get engine clock: %d\n", ret);
9e629c17aa8d7a7 Jie Qiu 2016-01-04  702 return ret;
9e629c17aa8d7a7 Jie Qiu 2016-01-04  703 }
9e629c17aa8d7a7 Jie Qiu 2016-01-04  704
9e629c17aa8d7a7 Jie Qiu 2016-01-04  705 dpi->pixel_clk = 
devm_clk_get(dev, "pixel");
9e629c17aa8d7a7 Jie Qiu 2016-01-04  706 if (IS_ERR(dpi->pixel_clk)) {
9e629c17aa8d7a7 Jie Qiu 2016-01-04  707 ret = 
PTR_ERR(dpi->pixel_clk);
9e629c17aa8d7a7 Jie Qiu 2016-01-04  708 dev_err(dev, "Failed to 
get pixel clock: %d\n", ret);
9e629c17aa8d7a7 Jie Qiu 2016-01-04  709 return ret;
9e629c17aa8d7a7 Jie Qiu 2016-01-04  710 }
9e629c17aa8d7a7 Jie Qiu 2016-01-04  711
9e629c17aa8d7a7 Jie Qiu 2016-01-04  712 dpi->tvd_clk = 
devm_clk_get(dev, "pll");
9e629c17aa8d7a7 Jie Qiu 2016-01-04  713 if (IS_ERR(dpi->tvd_clk)) {
9e629c17aa8d7a7 Jie Qiu 2016-01-04  714 ret = 
PTR_ERR(dpi->tvd_clk);
9e629c17aa8d7a7 Jie Qiu 2016-01-04  715 dev_err(dev, "Failed to 
get tvdpll clock: %d\n", ret);
9e629c17aa8d7a7 Jie Qiu 2016-01-04  716 return ret;
9e629c17aa8d7a7 Jie Qiu 2016-01-04  717 }
9e629c17aa8d7a7 Jie Qiu 2016-01-04  718
9e629c17aa8d7a7 Jie Qiu 2016-01-04  719 dpi->irq = 
platform_get_irq(pdev, 0);
9e629c17aa8d7a7 Jie 

Re: [PATCH v3 1/3] devres: provide devm_krealloc()

2020-07-12 Thread Bartosz Golaszewski
On Sat, Jul 11, 2020 at 5:08 PM Andy Shevchenko
 wrote:
>
> On Fri, Jul 10, 2020 at 7:17 PM Bartosz Golaszewski  wrote:
> >
> > From: Bartosz Golaszewski 
> >
> > Implement the managed variant of krealloc(). This function works with
> > all memory allocated by devm_kmalloc() (or devres functions using it
> > implicitly like devm_kmemdup(), devm_kstrdup() etc.).
> >
> > Managed realloc'ed chunks can be manually released with devm_kfree().
>
> ...
>
> >devm_kfree()
> >devm_kmalloc()
> >devm_kmalloc_array()
> > +  devm_krealloc()
> >devm_kmemdup()
> >devm_kstrdup()
> >devm_kvasprintf()
>
> Order?
>

I didn't notice these were ordered alphabetically, I thought it was by
functionality.

> ...
>
> > +void *devm_krealloc(struct device *dev, void *ptr, size_t new_size, gfp_t 
> > gfp)
>
> Do we really need the 'new_' prefix in the parameter?
>

Yes, I think this is a good name for a function that's meant to modify
the size of a memory chunk.

> > +{
> > +   struct devres *old_dr, *new_dr;
> > +   struct list_head old_head;
> > +   unsigned long flags;
> > +   void *ret = NULL;
> > +   size_t tot_size;
>
> tot -> total.
>

Meh, ok.

> > +
> > +   if (unlikely(!new_size)) {
> > +   devm_kfree(dev, ptr);
> > +   return ZERO_SIZE_PTR;
> > +   }
>
> I guess here we need a comment of the possibilities below to have
> ZERO_SIZE_PTR as input.
>

Better yet: I'll just add a kernel doc for this function.

> > +   if (unlikely(ZERO_OR_NULL_PTR(ptr)))
> > +   return devm_kmalloc(dev, new_size, gfp);
> > +
> > +   if (WARN_ON(is_kernel_rodata((unsigned long)ptr)))
> > +   /*
> > +* We cannot reliably realloc a const string returned by
> > +* devm_kstrdup_const().
> > +*/
> > +   return NULL;
> > +
> > +   if (!check_dr_size(new_size, &tot_size))
> > +   return NULL;
> > +
> > +   spin_lock_irqsave(&dev->devres_lock, flags);
> > +
> > +   old_dr = find_dr(dev, devm_kmalloc_release, devm_kmalloc_match, 
> > ptr);
>
> > +   if (WARN_ON(!old_dr))
>
> Under spin lock? I would rather see spin unlock followed by WARN.
>

Yeah, can be done.

> > +   /* Memory chunk not managed or managed by a different 
> > device. */
> > +   goto out;
> > +
> > +   old_head = old_dr->node.entry;
> > +
> > +   new_dr = krealloc(old_dr, tot_size, gfp);
> > +   if (!new_dr)
> > +   goto out;
> > +
> > +   if (new_dr != old_dr)
> > +   list_replace(&old_head, &new_dr->node.entry);
> > +
> > +   ret = new_dr->data;
> > +
> > +out:
> > +   spin_unlock_irqrestore(&dev->devres_lock, flags);
> > +   return ret;
> > +}
>
> --
> With Best Regards,
> Andy Shevchenko

Bartosz


Re: [PATCH] docs/core-api: memory-allocation: describe reclaim behaviour

2020-07-12 Thread Mike Rapoport
Another ping :)

On Fri, Jul 03, 2020 at 12:55:04AM +0300, Mike Rapoport wrote:
> Gentle ping.
> 
> On Fri, Jun 26, 2020 at 05:29:50PM +0300, Mike Rapoport wrote:
> > From: Mike Rapoport 
> > 
> > Changelog of commit dcda9b04713c ("mm, tree wide: replace __GFP_REPEAT by
> > __GFP_RETRY_MAYFAIL with more useful semantic") has very nice description
> > of GFP flags that affect reclaim behaviour of the page allocator.
> > 
> > It would be pity to keep this description buried in the log so let's expose
> > it in the Documentation/ as well.
> > 
> > Cc: Michal Hocko 
> > Signed-off-by: Mike Rapoport 
> > ---
> > Hi,
> > 
> > I've been looking for something completely unrealated and found this
> > really nice piece of documentation.
> > 
> > Thanks Michal! ;-)
> > 
> >  Documentation/core-api/memory-allocation.rst | 44 
> >  1 file changed, 44 insertions(+)
> > 
> > diff --git a/Documentation/core-api/memory-allocation.rst 
> > b/Documentation/core-api/memory-allocation.rst
> > index 4aa82ddd01b8..4446a1ac36cc 100644
> > --- a/Documentation/core-api/memory-allocation.rst
> > +++ b/Documentation/core-api/memory-allocation.rst
> > @@ -84,6 +84,50 @@ driver for a device with such restrictions, avoid using 
> > these flags.
> >  And even with hardware with restrictions it is preferable to use
> >  `dma_alloc*` APIs.
> >  
> > +GFP flags and reclaim behavior
> > +--
> > +Memory allocations may trigger direct or background reclaim and it is
> > +useful to understand how hard the page allocator will try to satisfy that
> > +or another request.
> > +
> > +  * ``GFP_KERNEL & ~__GFP_RECLAIM`` - optimistic allocation without _any_
> > +attempt to free memory at all. The most light weight mode which even
> > +doesn't kick the background reclaim. Should be used carefully because 
> > it
> > +might deplete the memory and the next user might hit the more 
> > aggressive
> > +reclaim.
> > +
> > +  * ``GFP_KERNEL & ~__GFP_DIRECT_RECLAIM`` (or ``GFP_NOWAIT``)- optimistic
> > +allocation without any attempt to free memory from the current
> > +context but can wake kswapd to reclaim memory if the zone is below
> > +the low watermark. Can be used from either atomic contexts or when
> > +the request is a performance optimization and there is another
> > +fallback for a slow path.
> > +
> > +  * ``(GFP_KERNEL|__GFP_HIGH) & ~__GFP_DIRECT_RECLAIM`` (aka 
> > ``GFP_ATOMIC``) -
> > +non sleeping allocation with an expensive fallback so it can access
> > +some portion of memory reserves. Usually used from 
> > interrupt/bottom-half
> > +context with an expensive slow path fallback.
> > +
> > +  * ``GFP_KERNEL`` - both background and direct reclaim are allowed and the
> > +**default** page allocator behavior is used. That means that not costly
> > +allocation requests are basically no-fail but there is no guarantee of
> > +that behavior so failures have to be checked properly by callers
> > +(e.g. OOM killer victim is allowed to fail currently).
> > +
> > +  * ``GFP_KERNEL | __GFP_NORETRY`` - overrides the default allocator 
> > behavior
> > +and all allocation requests fail early rather than cause disruptive
> > +reclaim (one round of reclaim in this implementation). The OOM killer
> > +is not invoked.
> > +
> > +  * ``GFP_KERNEL | __GFP_RETRY_MAYFAIL`` - overrides the default allocator
> > +behavior and all allocation requests try really hard. The request
> > +will fail if the reclaim cannot make any progress. The OOM killer
> > +won't be triggered.
> > +
> > +  * ``GFP_KERNEL | __GFP_NOFAIL`` - overrides the default allocator 
> > behavior
> > +and all allocation requests will loop endlessly until they succeed.
> > +This might be really dangerous especially for larger orders.
> > +
> >  Selecting memory allocator
> >  ==
> >  
> > -- 
> > 2.25.4
> > 
> 
> -- 
> Sincerely yours,
> Mike.

-- 
Sincerely yours,
Mike.


Re: [PATCH v7 3/3] leds: trigger: implement a tty trigger

2020-07-12 Thread Pavel Machek
Hi!

> +++ b/Documentation/ABI/testing/sysfs-class-led-trigger-tty
> @@ -0,0 +1,6 @@
> +What:/sys/class/leds//ttyname
> +Date:Jul 2020
> +KernelVersion:   5.8
> +Contact: linux-l...@vger.kernel.org
> +Description:
> + Specifies the tty device name of the triggering tty
> diff --git a/drivers/leds/trigger/Kconfig b/drivers/leds/trigger/Kconfig
> index ce9429ca6dde..40ff08c93f56 100644
> --- a/drivers/leds/trigger/Kconfig
> +++ b/drivers/leds/trigger/Kconfig
> @@ -144,4 +144,11 @@ config LEDS_TRIGGER_AUDIO
> the audio mute and mic-mute changes.
> If unsure, say N
>  
> +config LEDS_TRIGGER_TTY
> + tristate "LED Trigger for TTY devices"
> + depends on TTY
> + help
> +   This allows LEDs to be controlled by activity on ttys which includes
> +   serial devices like /dev/ttyS0.

"This driver can be built as a module, resulting module will be
named.. If unsure, say N."

> +++ b/drivers/leds/trigger/ledtrig-tty.c
> @@ -0,0 +1,192 @@
> +// SPDX-License-Identifier: GPL-2.0

2.0+ is preffered.

> +
> + while (firstrun ||
> +icount.rx != trigger_data->rx ||
> +icount.tx != trigger_data->tx) {
> +
> + led_set_brightness(trigger_data->led_cdev, LED_ON);
> +
> + msleep(100);
> +
> + led_set_brightness(trigger_data->led_cdev, LED_OFF);

Is this good idea inside workqueue?

> + trigger_data->rx = icount.rx;
> + trigger_data->tx = icount.tx;
> + firstrun = false;
> +
> + ret = tty_get_icount(trigger_data->tty, &icount);
> + if (ret)
> + return;

Unbalanced locking.

> + }
> +
> +out:
> + mutex_unlock(&trigger_data->mutex);
> + schedule_delayed_work(&trigger_data->dwork, msecs_to_jiffies(100));
> +}

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


Re: [PATCH][next] leds: ns2: Use struct_size() in devm_kzalloc()

2020-07-12 Thread Pavel Machek
On Wed 2020-06-17 18:07:57, Gustavo A. R. Silva wrote:
> Make use of the struct_size() helper instead of an open-coded version
> in order to avoid any potential type mistakes. Also, remove unnecessary
> function sizeof_ns2_led_priv().
> 
> This code was detected with the help of Coccinelle and, audited and
> fixed manually.
> 
> Signed-off-by: Gustavo A. R. Silva 

Thanks, applied.
Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


Re: [PATCH][next] leds: gpio: Use struct_size() in devm_kzalloc()

2020-07-12 Thread Pavel Machek
On Fri 2020-06-19 17:14:03, Gustavo A. R. Silva wrote:
> Make use of the struct_size() helper instead of an open-coded version
> in order to avoid any potential type mistakes. Also, remove unnecessary
> function sizeof_gpio_leds_priv().
> 
> This code was detected with the help of Coccinelle and, audited and
> fixed manually.
> 
> Signed-off-by: Gustavo A. R. Silva 

Thanks, applied.
Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


[PATCH] mm/sparse: cleanup the code surrounding memory_present()

2020-07-12 Thread Mike Rapoport
From: Mike Rapoport 

After removal of CONFIG_HAVE_MEMBLOCK_NODE_MAP we have two equivalent
functions that call memory_present() for each region in memblock.memory:
sparse_memory_present_with_active_regions() and membocks_present().

Moreover, all architectures have a call to either of these functions
preceding the call to sparse_init() and in the most cases they are called
one after the other.

Mark the regions from memblock.memory as present during sparce_init() by
making sparse_init() call memblocks_present(), make memblocks_present() and
memory_present() functions static and remove redundant
sparse_memory_present_with_active_regions() function.

Also remove no longer required HAVE_MEMORY_PRESENT configuration option.

Signed-off-by: Mike Rapoport 
---
Hi,

The changes here are trivial so I've trimmed the spam list this time.

--
Sincerely yours,
Mike.

 Documentation/vm/memory-model.rst |  7 ++-
 arch/arm/mm/init.c|  9 ++---
 arch/arm64/mm/init.c  |  6 ++
 arch/ia64/mm/discontig.c  |  1 -
 arch/microblaze/mm/init.c |  3 ---
 arch/mips/kernel/setup.c  |  8 
 arch/mips/loongson64/numa.c   |  1 -
 arch/mips/sgi-ip27/ip27-memory.c  |  2 --
 arch/parisc/mm/init.c |  5 -
 arch/powerpc/mm/mem.c |  2 --
 arch/powerpc/mm/numa.c|  1 -
 arch/riscv/mm/init.c  |  1 -
 arch/s390/mm/init.c   |  1 -
 arch/sh/mm/init.c |  6 --
 arch/sh/mm/numa.c |  3 ---
 arch/sparc/mm/init_64.c   |  1 -
 arch/x86/mm/init_32.c |  2 --
 arch/x86/mm/init_64.c |  1 -
 include/linux/mm.h|  4 
 include/linux/mmzone.h| 14 --
 mm/Kconfig|  6 +-
 mm/page_alloc.c   | 16 
 mm/sparse.c   | 20 
 23 files changed, 19 insertions(+), 101 deletions(-)

diff --git a/Documentation/vm/memory-model.rst 
b/Documentation/vm/memory-model.rst
index 91228044ed16..c6d77a5ae64b 100644
--- a/Documentation/vm/memory-model.rst
+++ b/Documentation/vm/memory-model.rst
@@ -141,11 +141,8 @@ sections:
   `mem_section` objects and the number of rows is calculated to fit
   all the memory sections.
 
-The architecture setup code should call :c:func:`memory_present` for
-each active memory range or use :c:func:`memblocks_present` or
-:c:func:`sparse_memory_present_with_active_regions` wrappers to
-initialize the memory sections. Next, the actual memory maps should be
-set up using :c:func:`sparse_init`.
+The architecture setup code should call sparse_init() to
+initialize the memory sections and the memory maps.
 
 With SPARSEMEM there are two possible ways to convert a PFN to the
 corresponding `struct page` - a "classic sparse" and "sparse
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 01e18e43b174..000c1b48e973 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -243,13 +243,8 @@ void __init bootmem_init(void)
  (phys_addr_t)max_low_pfn << PAGE_SHIFT);
 
/*
-* Sparsemem tries to allocate bootmem in memory_present(),
-* so must be done after the fixed reservations
-*/
-   memblocks_present();
-
-   /*
-* sparse_init() needs the bootmem allocator up and running.
+* sparse_init() tries to allocate memory from memblock, so must be
+* done after the fixed reservations
 */
sparse_init();
 
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 1e93cfc7c47a..2fa9adf975db 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -430,11 +430,9 @@ void __init bootmem_init(void)
 #endif
 
/*
-* Sparsemem tries to allocate bootmem in memory_present(), so must be
-* done after the fixed reservations.
+* sparse_init() tries to allocate memory from memblock, so must be
+* done after the fixed reservations
 */
-   memblocks_present();
-
sparse_init();
zone_sizes_init(min, max);
 
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index dd8284bcbf16..680855a042fb 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -601,7 +601,6 @@ void __init paging_init(void)
 
max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
 
-   sparse_memory_present_with_active_regions(MAX_NUMNODES);
sparse_init();
 
 #ifdef CONFIG_VIRTUAL_MEM_MAP
diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c
index 521b59ba716c..0880a003573d 100644
--- a/arch/microblaze/mm/init.c
+++ b/arch/microblaze/mm/init.c
@@ -172,9 +172,6 @@ void __init setup_memory(void)
  &memblock.memory, 0);
}
 
-   /* XXX need to clip this if using highmem? */
-   sparse_memory_present_with_active_regions(0);
-
paging_init();
 }
 
diff --git a/arch/mips/kernel/setup.

Re: [PATCH v7 3/3] leds: trigger: implement a tty trigger

2020-07-12 Thread Greg Kroah-Hartman
On Sun, Jul 12, 2020 at 10:24:53AM +0200, Pavel Machek wrote:
> > +++ b/drivers/leds/trigger/ledtrig-tty.c
> > @@ -0,0 +1,192 @@
> > +// SPDX-License-Identifier: GPL-2.0
> 
> 2.0+ is preffered.

No it is not, that's up to the developer.

thanks,

greg k-h


KMSAN: uninit-value in path_openat

2020-07-12 Thread syzbot
Hello,

syzbot found the following crash on:

HEAD commit:f0d5ec90 kmsan: apply __no_sanitize_memory to dotraplinkag..
git tree:   https://github.com/google/kmsan.git master
console output: https://syzkaller.appspot.com/x/log.txt?x=159636b710
kernel config:  https://syzkaller.appspot.com/x/.config?x=86e4f8af239686c6
dashboard link: https://syzkaller.appspot.com/bug?extid=4191a44ad556eacc1a7a
compiler:   clang version 10.0.0 (https://github.com/llvm/llvm-project/ 
c2443155a0fb245c8f17f2c1c72b6ea391e86e81)
userspace arch: i386
syz repro:  https://syzkaller.appspot.com/x/repro.syz?x=1073c0bd10
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=13974b2f10

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

=
BUG: KMSAN: uninit-value in may_create_in_sticky fs/namei.c:1060 [inline]
BUG: KMSAN: uninit-value in do_open fs/namei.c:3207 [inline]
BUG: KMSAN: uninit-value in path_openat+0x48be/0x5d50 fs/namei.c:3346
CPU: 1 PID: 8815 Comm: syz-executor333 Not tainted 5.7.0-rc4-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 
01/01/2011
Call Trace:
 __dump_stack lib/dump_stack.c:77 [inline]
 dump_stack+0x1c9/0x220 lib/dump_stack.c:118
 kmsan_report+0xf7/0x1e0 mm/kmsan/kmsan_report.c:121
 __msan_warning+0x58/0xa0 mm/kmsan/kmsan_instr.c:215
 may_create_in_sticky fs/namei.c:1060 [inline]
 do_open fs/namei.c:3207 [inline]
 path_openat+0x48be/0x5d50 fs/namei.c:3346
 do_file_open_root+0x469/0xb40 fs/namei.c:3401
 file_open_root+0x6f1/0x760 fs/open.c:1128
 do_handle_open+0xa11/0xe30 fs/fhandle.c:232
 __do_compat_sys_open_by_handle_at fs/fhandle.c:277 [inline]
 __se_compat_sys_open_by_handle_at+0x8e/0xa0 fs/fhandle.c:274
 __ia32_compat_sys_open_by_handle_at+0x4a/0x70 fs/fhandle.c:274
 do_syscall_32_irqs_on arch/x86/entry/common.c:339 [inline]
 do_fast_syscall_32+0x3bf/0x6d0 arch/x86/entry/common.c:398
 entry_SYSENTER_compat+0x68/0x77 arch/x86/entry/entry_64_compat.S:139
RIP: 0023:0xf7f3bdd9
Code: 90 e8 0b 00 00 00 f3 90 0f ae e8 eb f9 8d 74 26 00 89 3c 24 c3 90 90 90 
90 90 90 90 90 90 90 90 90 51 52 55 89 e5 0f 34 cd 80 <5d> 5a 59 c3 90 90 90 90 
eb 0d 90 90 90 90 90 90 90 90 90 90 90 90
RSP: 002b:ff8507fc EFLAGS: 0207 ORIG_RAX: 0156
RAX: ffda RBX: ff9c RCX: 2200
RDX: 2f40 RSI: 0001 RDI: 080bb4c8
RBP: 0012 R08:  R09: 
R10:  R11:  R12: 
R13:  R14:  R15: 

Local variable nd@do_file_open_root created at:
 do_file_open_root+0xa4/0xb40 fs/namei.c:3385
 do_file_open_root+0xa4/0xb40 fs/namei.c:3385
=


---
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


Re: [PATCH v7 3/3] leds: trigger: implement a tty trigger

2020-07-12 Thread Pavel Machek
On Sun 2020-07-12 10:43:52, Greg Kroah-Hartman wrote:
> On Sun, Jul 12, 2020 at 10:24:53AM +0200, Pavel Machek wrote:
> > > +++ b/drivers/leds/trigger/ledtrig-tty.c
> > > @@ -0,0 +1,192 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > 
> > 2.0+ is preffered.
> 
> No it is not, that's up to the developer.

For code I maintain, yes it is.
Pavel
-- 
DENX Software Engineering GmbH,  Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany


signature.asc
Description: Digital signature


Re: [PATCH 00/22] add support for Clang LTO

2020-07-12 Thread Sedat Dilek
On Sat, Jul 11, 2020 at 6:32 PM Paul Menzel  wrote:
>
> Dear Sami,
>
>
> Am 24.06.20 um 22:31 schrieb Sami Tolvanen:
> > This patch series adds support for building x86_64 and arm64 kernels
> > with Clang's Link Time Optimization (LTO).
> >
> > In addition to performance, the primary motivation for LTO is to allow
> > Clang's Control-Flow Integrity (CFI) to be used in the kernel. Google's
> > Pixel devices have shipped with LTO+CFI kernels since 2018.
> >
> > Most of the patches are build system changes for handling LLVM bitcode,
> > which Clang produces with LTO instead of ELF object files, postponing
> > ELF processing until a later stage, and ensuring initcall ordering.
> >
> > Note that first objtool patch in the series is already in linux-next,
> > but as it's needed with LTO, I'm including it also here to make testing
> > easier.
>
> […]
>
> Thank you very much for sending these changes.
>
> Do you have a branch, where your current work can be pulled from? Your
> branch on GitHub [1] seems 15 months old.
>

Agreed it's easier to git-pull.
I have seen [1] - not sure if this is the latest version.
Alternatively, you can check patchwork LKML by searching for $submitter.
( You can open patch 01/22 and download the whole patch-series by
following the link "series", see [3]. )

- Sedat -

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild.git/log/?h=lto
[2] https://lore.kernel.org/patchwork/project/lkml/list/?series=&submitter=19676
[3] https://lore.kernel.org/patchwork/series/450026/mbox/


Re: [PATCH v7 3/3] leds: trigger: implement a tty trigger

2020-07-12 Thread Greg Kroah-Hartman
On Sun, Jul 12, 2020 at 10:50:59AM +0200, Pavel Machek wrote:
> On Sun 2020-07-12 10:43:52, Greg Kroah-Hartman wrote:
> > On Sun, Jul 12, 2020 at 10:24:53AM +0200, Pavel Machek wrote:
> > > > +++ b/drivers/leds/trigger/ledtrig-tty.c
> > > > @@ -0,0 +1,192 @@
> > > > +// SPDX-License-Identifier: GPL-2.0
> > > 
> > > 2.0+ is preffered.
> > 
> > No it is not, that's up to the developer.
> 
> For code I maintain, yes it is.

That's up to the developer of the code, not the maintainer, as the
maintainer is not the copyright holder of it.  For new files, it is up
to the author of that code.  No maintainer should impose a license rule
like this on their subsystem, that's just not ok at all.  The only
"rule" is that it is compatible with GPLv2, nothing else.

thanks,

greg k-h


Re: [PATCH v7 3/3] leds: trigger: implement a tty trigger

2020-07-12 Thread Pavel Machek
On Sun 2020-07-12 11:02:17, Greg Kroah-Hartman wrote:
> On Sun, Jul 12, 2020 at 10:50:59AM +0200, Pavel Machek wrote:
> > On Sun 2020-07-12 10:43:52, Greg Kroah-Hartman wrote:
> > > On Sun, Jul 12, 2020 at 10:24:53AM +0200, Pavel Machek wrote:
> > > > > +++ b/drivers/leds/trigger/ledtrig-tty.c
> > > > > @@ -0,0 +1,192 @@
> > > > > +// SPDX-License-Identifier: GPL-2.0
> > > > 
> > > > 2.0+ is preffered.
> > > 
> > > No it is not, that's up to the developer.
> > 
> > For code I maintain, yes it is.
> 
> That's up to the developer of the code, not the maintainer, as the
> maintainer is not the copyright holder of it.  For new files, it is up
> to the author of that code.  No maintainer should impose a license rule
> like this on their subsystem, that's just not ok at all.  The only
> "rule" is that it is compatible with GPLv2, nothing else.

No, see for example device tree rules.

Plus, IIRC it was you who asked the developer to "doublecheck with
their legal" when you seen GPL-2.0+. You can't really prevent me from
doing the same.

Pavel
-- 
DENX Software Engineering GmbH,  Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany


signature.asc
Description: Digital signature


[RESEND PATCH] ARM: dts: imx6sx-sdb: Add MQS support

2020-07-12 Thread Shengjiu Wang
Add MQS support. As the pin conflict with usdhc2, then need
to add a separate dts.

Signed-off-by: Shengjiu Wang 
---
changes in RESEND
- resolve the conflict with latest tree.

 arch/arm/boot/dts/Makefile   |  1 +
 arch/arm/boot/dts/imx6sx-sdb-mqs.dts | 48 
 arch/arm/boot/dts/imx6sx-sdb.dtsi|  7 
 arch/arm/boot/dts/imx6sx.dtsi|  6 
 4 files changed, 62 insertions(+)
 create mode 100644 arch/arm/boot/dts/imx6sx-sdb-mqs.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index e6a1cac0bfc7..04f85d6a2af3 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -592,6 +592,7 @@ dtb-$(CONFIG_SOC_IMX6SX) += \
imx6sx-sdb-reva.dtb \
imx6sx-sdb-sai.dtb \
imx6sx-sdb.dtb \
+   imx6sx-sdb-mqs.dtb \
imx6sx-softing-vining-2000.dtb \
imx6sx-udoo-neo-basic.dtb \
imx6sx-udoo-neo-extended.dtb \
diff --git a/arch/arm/boot/dts/imx6sx-sdb-mqs.dts 
b/arch/arm/boot/dts/imx6sx-sdb-mqs.dts
new file mode 100644
index ..a4ab2d3e960c
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-sdb-mqs.dts
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (C) 2014 Freescale Semiconductor, Inc.
+
+#include "imx6sx-sdb.dts"
+/ {
+
+   sound {
+   status = "disabled";
+   };
+
+   sound-mqs {
+   compatible = "fsl,imx6sx-sdb-mqs",
+"fsl,imx-audio-mqs";
+   model = "mqs-audio";
+   audio-cpu = <&sai1>;
+   audio-asrc = <&asrc>;
+   audio-codec = <&mqs>;
+   };
+};
+
+&usdhc2 {
+   /* pin conflict with mqs*/
+   status = "disabled";
+};
+
+&mqs {
+   pinctrl-names = "default";
+   pinctrl-0 = <&pinctrl_mqs>;
+   clocks = <&clks IMX6SX_CLK_SAI1>;
+   clock-names = "mclk";
+   status = "okay";
+};
+
+&sai1 {
+   pinctrl-0 = <>;
+   status = "okay";
+};
+
+&ssi2 {
+   status = "disabled";
+};
+
+&sdma {
+   gpr = <&gpr>;
+   /* SDMA event remap for SAI1 */
+   fsl,sdma-event-remap = <0 15 1>, <0 16 1>;
+};
diff --git a/arch/arm/boot/dts/imx6sx-sdb.dtsi 
b/arch/arm/boot/dts/imx6sx-sdb.dtsi
index 6673532018b2..05d1e9d2efab 100644
--- a/arch/arm/boot/dts/imx6sx-sdb.dtsi
+++ b/arch/arm/boot/dts/imx6sx-sdb.dtsi
@@ -522,6 +522,13 @@ MX6SX_PAD_LCD1_RESET__GPIO3_IO_27 0x4001b0b0
>;
};
 
+   pinctrl_mqs: mqsgrp {
+   fsl,pins = <
+   MX6SX_PAD_SD2_CLK__MQS_RIGHT 0x120b0
+   MX6SX_PAD_SD2_CMD__MQS_LEFT  0x120b0
+   >;
+   };
+
pinctrl_pcie: pciegrp {
fsl,pins = <
MX6SX_PAD_ENET1_COL__GPIO2_IO_0 0x10b0
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
index 5c2b78589aa5..fcb3d064d0cc 100644
--- a/arch/arm/boot/dts/imx6sx.dtsi
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -134,6 +134,12 @@ anaclk2: clock-anaclk2 {
clock-output-names = "anaclk2";
};
 
+   mqs: mqs {
+   compatible = "fsl,imx6sx-mqs";
+   gpr = <&gpr>;
+   status = "disabled";
+   };
+
pmu {
compatible = "arm,cortex-a9-pmu";
interrupt-parent = <&gpc>;
-- 
2.27.0



Re: [PATCH 0/5] Add audio support for imx6sx platform

2020-07-12 Thread S.j. Wang
Hi

> 
> On Thu, Jun 18, 2020 at 02:03:44PM +0800, Shengjiu Wang wrote:
> > Add audio support for imx6sx platform.
> > Enable ASRC, ESAI, SPDIF, MQS.
> >
> > Shengjiu Wang (5):
> >   ARM: dts: imx6sx: Enable ASRC device
> >   ARM: dts: imx6sx-sdb: Add MQS support
> 
> Applied the series, except this one which doesn't apply to my branch.

Thanks. I have resolved the conflict and resent this commit.

[RESEND PATCH] ARM: dts: imx6sx-sdb: Add MQS support

Best regards
Wang shengjiu



Re: [PATCH v2 3/5] irqchip: Allow QCOM_PDC to be loadable as a permanent module

2020-07-12 Thread Marc Zyngier
On Sat, 11 Jul 2020 00:27:45 +0100,
Stephen Boyd  wrote:
> 
> Quoting John Stultz (2020-07-10 15:44:18)
> > On Thu, Jul 9, 2020 at 11:02 PM Stephen Boyd  wrote:
> > >
> > > Does it work? I haven't looked in detail but I worry that the child
> > > irqdomain (i.e. pinctrl-msm) would need to delay probing until this
> > > parent irqdomain is registered. Or has the hierarchical irqdomain code
> > > been updated to handle the parent child relationship and wait for things
> > > to probe or be loaded?
> > 
> > So I can't say I know the underlying hardware particularly well, but
> > I've been using this successfully on the Dragonboard 845c with both
> > static builds as well as module enabled builds.
> > And the same patch has been in the android-mainline and android-5.4
> > kernels for a while without objections from QCOM.
> > 
> > As to the probe ordering question, Saravana can maybe speak in more
> > detail if it's involved in this case but the fw_devlink code has
> > addressed many of these sorts of ordering issues.
> > However, I'm not sure if I'm lucking into the right probe order, as we
> > have been able to boot android-mainline w/ both fw_devlink=on and
> > fw_devlink=off (though in the =off case, we need
> > deferred_probe_timeout=30 to give us a bit more time for modules to
> > load after init starts).
> > 
> 
> Ok I looked at the code (sorry for not checking earlier) and I see this in
> msm_gpio_init()
> 
> np = of_parse_phandle(pctrl->dev->of_node, "wakeup-parent", 0);
> if (np) {
> chip->irq.parent_domain = irq_find_matching_host(np,
>  DOMAIN_BUS_WAKEUP);
> of_node_put(np);
> if (!chip->irq.parent_domain)
> return -EPROBE_DEFER;
> 
> so it looks like we'll probe defer the pinctrl driver until the pdc module
> loads. Meaning it should work to have pinctrl builtin and pdc as a module.

What I hope is that eventually fw_devlink will become the norm (on by
default), and that probe deferral will become a thing of the past.

M.

-- 
Without deviation from the norm, progress is not possible.


GPS fun on Droid 4 and leste

2020-07-12 Thread Pavel Machek
Hi!

GPS on the droid 4 does not really work out of the box.

gpsd is not in default installation, maybe it should be?

What is worse, there's something broken with gpsd. Try:

/usr/sbin/gpsd -N -D 5 /dev/gnss0
gpspipe -w
# this seems to work, but do ^C and restart
gpspipe -w
...and it hangs.

xgps from gpsd-clients is broken: probably missing dependency
on gtk3 libraries.

user@devuan-droid4:/my/tui/lib$ xgps
Traceback (most recent call last):
  File "/usr/bin/xgps", line 30, in 
  gi.require_version('Gtk', '3.0')
 File "/usr/lib/python2.7/dist-packages/gi/__init__.py", line
 129, in require_version
 raise ValueError('Namespace %s not available' % namespace)
 ValueError: Namespace Gtk not available

Any ideas?

Best regards,
Pavel

-- 
DENX Software Engineering GmbH,  Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany


signature.asc
Description: Digital signature


Re: [PATCH v7 3/3] leds: trigger: implement a tty trigger

2020-07-12 Thread Greg Kroah-Hartman
On Sun, Jul 12, 2020 at 11:07:31AM +0200, Pavel Machek wrote:
> On Sun 2020-07-12 11:02:17, Greg Kroah-Hartman wrote:
> > On Sun, Jul 12, 2020 at 10:50:59AM +0200, Pavel Machek wrote:
> > > On Sun 2020-07-12 10:43:52, Greg Kroah-Hartman wrote:
> > > > On Sun, Jul 12, 2020 at 10:24:53AM +0200, Pavel Machek wrote:
> > > > > > +++ b/drivers/leds/trigger/ledtrig-tty.c
> > > > > > @@ -0,0 +1,192 @@
> > > > > > +// SPDX-License-Identifier: GPL-2.0
> > > > > 
> > > > > 2.0+ is preffered.
> > > > 
> > > > No it is not, that's up to the developer.
> > > 
> > > For code I maintain, yes it is.
> > 
> > That's up to the developer of the code, not the maintainer, as the
> > maintainer is not the copyright holder of it.  For new files, it is up
> > to the author of that code.  No maintainer should impose a license rule
> > like this on their subsystem, that's just not ok at all.  The only
> > "rule" is that it is compatible with GPLv2, nothing else.
> 
> No, see for example device tree rules.

Note, I don't agree with that rule, and if you have noticed, it's not
really enforced.

> Plus, IIRC it was you who asked the developer to "doublecheck with
> their legal" when you seen GPL-2.0+.  You can't really prevent me from
> doing the same.

Asking to verify that a specific license is what they really want it to
be and they know the ramifications of it is NOT the same as saying "For
code in the subsystem I maintain it has to be GPLv2+".

thanks,

greg k-h


[PATCH 2/5] firmware: tegra: Use consistent return variable name

2020-07-12 Thread Jon Hunter
Most functions in the BPMP driver use 'err' as the return variable
name but there are a few places that use 'ret'. Let's use 'err' to
be consistent.

Signed-off-by: Jon Hunter 
---
 drivers/firmware/tegra/bpmp-debugfs.c | 36 +--
 drivers/firmware/tegra/bpmp.c |  6 ++---
 2 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/drivers/firmware/tegra/bpmp-debugfs.c 
b/drivers/firmware/tegra/bpmp-debugfs.c
index 08e0f05f46c6..f7bf19248d15 100644
--- a/drivers/firmware/tegra/bpmp-debugfs.c
+++ b/drivers/firmware/tegra/bpmp-debugfs.c
@@ -206,7 +206,7 @@ static int debugfs_show(struct seq_file *m, void *p)
char buf[256];
const char *filename;
size_t len, nbytes;
-   int ret;
+   int err;
 
filename = get_filename(bpmp, file, buf, sizeof(buf));
if (!filename)
@@ -220,24 +220,24 @@ static int debugfs_show(struct seq_file *m, void *p)
datavirt = dma_alloc_coherent(bpmp->dev, datasize, &dataphys,
  GFP_KERNEL | GFP_DMA32);
if (!datavirt) {
-   ret = -ENOMEM;
+   err = -ENOMEM;
goto free_namebuf;
}
 
len = strlen(filename);
strncpy(namevirt, filename, namesize);
 
-   ret = mrq_debugfs_read(bpmp, namephys, len, dataphys, datasize,
+   err = mrq_debugfs_read(bpmp, namephys, len, dataphys, datasize,
   &nbytes);
 
-   if (!ret)
+   if (!err)
seq_write(m, datavirt, nbytes);
 
dma_free_coherent(bpmp->dev, datasize, datavirt, dataphys);
 free_namebuf:
dma_free_coherent(bpmp->dev, namesize, namevirt, namephys);
 
-   return ret;
+   return err;
 }
 
 static int debugfs_open(struct inode *inode, struct file *file)
@@ -257,7 +257,7 @@ static ssize_t debugfs_store(struct file *file, const char 
__user *buf,
char fnamebuf[256];
const char *filename;
size_t len;
-   int ret;
+   int err;
 
filename = get_filename(bpmp, file, fnamebuf, sizeof(fnamebuf));
if (!filename)
@@ -271,7 +271,7 @@ static ssize_t debugfs_store(struct file *file, const char 
__user *buf,
datavirt = dma_alloc_coherent(bpmp->dev, datasize, &dataphys,
  GFP_KERNEL | GFP_DMA32);
if (!datavirt) {
-   ret = -ENOMEM;
+   err = -ENOMEM;
goto free_namebuf;
}
 
@@ -279,11 +279,11 @@ static ssize_t debugfs_store(struct file *file, const 
char __user *buf,
strncpy(namevirt, filename, namesize);
 
if (copy_from_user(datavirt, buf, count)) {
-   ret = -EFAULT;
+   err = -EFAULT;
goto free_databuf;
}
 
-   ret = mrq_debugfs_write(bpmp, namephys, len, dataphys,
+   err = mrq_debugfs_write(bpmp, namephys, len, dataphys,
count);
 
 free_databuf:
@@ -291,7 +291,7 @@ static ssize_t debugfs_store(struct file *file, const char 
__user *buf,
 free_namebuf:
dma_free_coherent(bpmp->dev, namesize, namevirt, namephys);
 
-   return ret ?: count;
+   return err ?: count;
 }
 
 static const struct file_operations debugfs_fops = {
@@ -380,8 +380,8 @@ int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp)
void *virt;
const size_t sz = SZ_512K;
size_t nbytes;
-   int ret;
struct dentry *root;
+   int err;
 
if (!tegra_bpmp_mrq_is_supported(bpmp, MRQ_DEBUGFS))
return 0;
@@ -393,24 +393,24 @@ int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp)
virt = dma_alloc_coherent(bpmp->dev, sz, &phys,
  GFP_KERNEL | GFP_DMA32);
if (!virt) {
-   ret = -ENOMEM;
+   err = -ENOMEM;
goto out;
}
 
-   ret = mrq_debugfs_dumpdir(bpmp, phys, sz, &nbytes);
-   if (ret < 0) {
+   err = mrq_debugfs_dumpdir(bpmp, phys, sz, &nbytes);
+   if (err < 0) {
goto free;
} else if (nbytes > sz) {
-   ret = -EINVAL;
+   err = -EINVAL;
goto free;
}
 
-   ret = create_debugfs_mirror(bpmp, virt, nbytes, root);
+   err = create_debugfs_mirror(bpmp, virt, nbytes, root);
 free:
dma_free_coherent(bpmp->dev, sz, virt, phys);
 out:
-   if (ret < 0)
+   if (err < 0)
debugfs_remove(root);
 
-   return ret;
+   return err;
 }
diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c
index fe6702df24bf..4d93d8925e14 100644
--- a/drivers/firmware/tegra/bpmp.c
+++ b/drivers/firmware/tegra/bpmp.c
@@ -515,10 +515,10 @@ bool tegra_bpmp_mrq_is_supported(struct tegra_bpmp *bpmp, 
unsigned int mrq)
.size = sizeof(resp),
},
};
-   int ret;
+   int err;
 
-   ret = tegra_bpmp_transfer(bpmp, &msg);
-   if (ret || msg.rx.ret)
+ 

[PATCH 3/5] firmware: tegra: Prepare for supporting in-band debugfs

2020-07-12 Thread Jon Hunter
Currently, BPMP debug information is accessible via the Linux debugfs
file-system using a shared-memory scheme. More recent BPMP firmware now
supports accessing the debug information by in-band messaging which does
not require shared-memory. To prepare for adding in-band debugfs support
for the BPMP, move the shared-memory specific initialisation from the
tegra_bpmp_init_debugfs() into a sub-function.

Signed-off-by: Jon Hunter 
---
 drivers/firmware/tegra/bpmp-debugfs.c | 53 ---
 1 file changed, 23 insertions(+), 30 deletions(-)

diff --git a/drivers/firmware/tegra/bpmp-debugfs.c 
b/drivers/firmware/tegra/bpmp-debugfs.c
index f7bf19248d15..a1a1a3b9e667 100644
--- a/drivers/firmware/tegra/bpmp-debugfs.c
+++ b/drivers/firmware/tegra/bpmp-debugfs.c
@@ -354,32 +354,43 @@ static int bpmp_populate_dir(struct tegra_bpmp *bpmp, 
struct seqbuf *seqbuf,
return 0;
 }
 
-static int create_debugfs_mirror(struct tegra_bpmp *bpmp, void *buf,
-size_t bufsize, struct dentry *root)
+static int bpmp_populate_debugfs_shmem(struct tegra_bpmp *bpmp,
+  struct dentry *root)
 {
struct seqbuf seqbuf;
+   const size_t sz = SZ_512K;
+   dma_addr_t phys;
+   size_t nbytes;
+   void *virt;
int err;
 
bpmp->debugfs_mirror = debugfs_create_dir("debug", root);
if (!bpmp->debugfs_mirror)
return -ENOMEM;
 
-   seqbuf_init(&seqbuf, buf, bufsize);
-   err = bpmp_populate_dir(bpmp, &seqbuf, bpmp->debugfs_mirror, 0);
+   virt = dma_alloc_coherent(bpmp->dev, sz, &phys,
+ GFP_KERNEL | GFP_DMA32);
+   if (!virt)
+   return -ENOMEM;
+
+   err = mrq_debugfs_dumpdir(bpmp, phys, sz, &nbytes);
if (err < 0) {
-   debugfs_remove_recursive(bpmp->debugfs_mirror);
-   bpmp->debugfs_mirror = NULL;
+   goto free;
+   } else if (nbytes > sz) {
+   err = -EINVAL;
+   goto free;
}
 
+   seqbuf_init(&seqbuf, virt, nbytes);
+   err = bpmp_populate_dir(bpmp, &seqbuf, bpmp->debugfs_mirror, 0);
+free:
+   dma_free_coherent(bpmp->dev, sz, virt, phys);
+
return err;
 }
 
 int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp)
 {
-   dma_addr_t phys;
-   void *virt;
-   const size_t sz = SZ_512K;
-   size_t nbytes;
struct dentry *root;
int err;
 
@@ -390,27 +401,9 @@ int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp)
if (!root)
return -ENOMEM;
 
-   virt = dma_alloc_coherent(bpmp->dev, sz, &phys,
- GFP_KERNEL | GFP_DMA32);
-   if (!virt) {
-   err = -ENOMEM;
-   goto out;
-   }
-
-   err = mrq_debugfs_dumpdir(bpmp, phys, sz, &nbytes);
-   if (err < 0) {
-   goto free;
-   } else if (nbytes > sz) {
-   err = -EINVAL;
-   goto free;
-   }
-
-   err = create_debugfs_mirror(bpmp, virt, nbytes, root);
-free:
-   dma_free_coherent(bpmp->dev, sz, virt, phys);
-out:
+   err = bpmp_populate_debugfs_shmem(bpmp, root);
if (err < 0)
-   debugfs_remove(root);
+   debugfs_remove_recursive(root);
 
return err;
 }
-- 
2.17.1



[PATCH 1/5] firmware: tegra: add return code checks and increase debugfs size

2020-07-12 Thread Jon Hunter
From: Timo Alho 

Add checking of the BPMP-FW return code values for MRQ_DEBUGFS calls.

Also, development versions of the firmware may have debugfs with
directory structure larger than 256Kb. Hence increase the size of the
memory buffer to accommodate those firmware revisions.

And finally, ensure that no access outside of allocated memory buffer
happens in case BPMP-FW returns an invalid response size (nbytes) from
mrq_debugfs_dumpdir() call.

Signed-off-by: Timo Alho 
Signed-off-by: Jon Hunter 
---
 drivers/firmware/tegra/bpmp-debugfs.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/tegra/bpmp-debugfs.c 
b/drivers/firmware/tegra/bpmp-debugfs.c
index 3f0a89ce131a..08e0f05f46c6 100644
--- a/drivers/firmware/tegra/bpmp-debugfs.c
+++ b/drivers/firmware/tegra/bpmp-debugfs.c
@@ -127,6 +127,8 @@ static int mrq_debugfs_read(struct tegra_bpmp *bpmp,
err = tegra_bpmp_transfer(bpmp, &msg);
if (err < 0)
return err;
+   else if (msg.rx.ret < 0)
+   return -EINVAL;
 
*nbytes = (size_t)resp.fop.nbytes;
 
@@ -184,6 +186,8 @@ static int mrq_debugfs_dumpdir(struct tegra_bpmp *bpmp, 
dma_addr_t addr,
err = tegra_bpmp_transfer(bpmp, &msg);
if (err < 0)
return err;
+   else if (msg.rx.ret < 0)
+   return -EINVAL;
 
*nbytes = (size_t)resp.dumpdir.nbytes;
 
@@ -374,7 +378,7 @@ int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp)
 {
dma_addr_t phys;
void *virt;
-   const size_t sz = SZ_256K;
+   const size_t sz = SZ_512K;
size_t nbytes;
int ret;
struct dentry *root;
@@ -394,8 +398,12 @@ int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp)
}
 
ret = mrq_debugfs_dumpdir(bpmp, phys, sz, &nbytes);
-   if (ret < 0)
+   if (ret < 0) {
+   goto free;
+   } else if (nbytes > sz) {
+   ret = -EINVAL;
goto free;
+   }
 
ret = create_debugfs_mirror(bpmp, virt, nbytes, root);
 free:
-- 
2.17.1



[PATCH 5/5] firmware: tegra: Update BPMP ABI

2020-07-12 Thread Jon Hunter
Update the BPMP ABI to align with the the latest version.

Signed-off-by: Jon Hunter 
---
 include/soc/tegra/bpmp-abi.h | 748 +--
 1 file changed, 460 insertions(+), 288 deletions(-)

diff --git a/include/soc/tegra/bpmp-abi.h b/include/soc/tegra/bpmp-abi.h
index 4896227eef1a..bff99f23860c 100644
--- a/include/soc/tegra/bpmp-abi.h
+++ b/include/soc/tegra/bpmp-abi.h
@@ -3,28 +3,38 @@
  * Copyright (c) 2014-2020, NVIDIA CORPORATION.  All rights reserved.
  */
 
-#ifndef _ABI_BPMP_ABI_H_
-#define _ABI_BPMP_ABI_H_
+#ifndef ABI_BPMP_ABI_H
+#define ABI_BPMP_ABI_H
 
-#ifdef LK
+#if defined(LK) || defined(BPMP_ABI_HAVE_STDC)
+#include 
 #include 
 #endif
 
-#ifndef __ABI_PACKED
-#define __ABI_PACKED __attribute__((packed))
+#ifndef BPMP_ABI_PACKED
+#ifdef __ABI_PACKED
+#define BPMP_ABI_PACKED __ABI_PACKED
+#else
+#define BPMP_ABI_PACKED __attribute__((packed))
+#endif
 #endif
 
 #ifdef NO_GCC_EXTENSIONS
-#define EMPTY char empty;
-#define EMPTY_ARRAY 1
+#define BPMP_ABI_EMPTY char empty;
+#define BPMP_ABI_EMPTY_ARRAY 1
 #else
-#define EMPTY
-#define EMPTY_ARRAY 0
+#define BPMP_ABI_EMPTY
+#define BPMP_ABI_EMPTY_ARRAY 0
 #endif
 
-#ifndef __UNION_ANON
-#define __UNION_ANON
+#ifndef BPMP_UNION_ANON
+#ifdef __UNION_ANON
+#define BPMP_UNION_ANON __UNION_ANON
+#else
+#define BPMP_UNION_ANON
+#endif
 #endif
+
 /**
  * @file
  */
@@ -73,6 +83,7 @@
 struct mrq_request {
/** @brief MRQ number of the request */
uint32_t mrq;
+
/**
 * @brief Flags providing follow up directions to the receiver
 *
@@ -82,7 +93,7 @@ struct mrq_request {
 * | 0   | should be 1|
 */
uint32_t flags;
-} __ABI_PACKED;
+} BPMP_ABI_PACKED;
 
 /**
  * @ingroup MRQ_Format
@@ -98,18 +109,18 @@ struct mrq_response {
int32_t err;
/** @brief Reserved for future use */
uint32_t flags;
-} __ABI_PACKED;
+} BPMP_ABI_PACKED;
 
 /**
  * @ingroup MRQ_Format
  * Minimum needed size for an IPC message buffer
  */
-#define MSG_MIN_SZ 128
+#define MSG_MIN_SZ 128U
 /**
  * @ingroup MRQ_Format
  *  Minimum size guaranteed for data in an IPC message buffer
  */
-#define MSG_DATA_MIN_SZ120
+#define MSG_DATA_MIN_SZ120U
 
 /**
  * @ingroup MRQ_Codes
@@ -118,37 +129,36 @@ struct mrq_response {
  * @{
  */
 
-#define MRQ_PING   0
-#define MRQ_QUERY_TAG  1
-#define MRQ_MODULE_LOAD4
-#define MRQ_MODULE_UNLOAD  5
-#define MRQ_TRACE_MODIFY   7
-#define MRQ_WRITE_TRACE8
-#define MRQ_THREADED_PING  9
-#define MRQ_MODULE_MAIL11
-#define MRQ_DEBUGFS19
-#define MRQ_RESET  20
-#define MRQ_I2C21
-#define MRQ_CLK22
-#define MRQ_QUERY_ABI  23
-#define MRQ_PG_READ_STATE  25
-#define MRQ_PG_UPDATE_STATE26
-#define MRQ_THERMAL27
-#define MRQ_CPU_VHINT  28
-#define MRQ_ABI_RATCHET29
-#define MRQ_EMC_DVFS_LATENCY   31
-#define MRQ_TRACE_ITER 64
-#define MRQ_RINGBUF_CONSOLE65
-#define MRQ_PG 66
-#define MRQ_CPU_NDIV_LIMITS67
-#define MRQ_STRAP   68
-#define MRQ_UPHY   69
-#define MRQ_CPU_AUTO_CC3   70
-#define MRQ_QUERY_FW_TAG   71
-#define MRQ_FMON   72
-#define MRQ_EC 73
-#define MRQ_FBVOLT_STATUS  74
-#define MRQ_DEBUG  75
+#define MRQ_PING   0U
+#define MRQ_QUERY_TAG  1U
+#define MRQ_MODULE_LOAD4U
+#define MRQ_MODULE_UNLOAD  5U
+#define MRQ_TRACE_MODIFY   7U
+#define MRQ_WRITE_TRACE8U
+#define MRQ_THREADED_PING  9U
+#define MRQ_MODULE_MAIL11U
+#define MRQ_DEBUGFS19U
+#define MRQ_RESET  20U
+#define MRQ_I2C21U
+#define MRQ_CLK22U
+#define MRQ_QUERY_ABI  23U
+#define MRQ_PG_READ_STATE  25U
+#define MRQ_PG_UPDATE_STATE26U
+#define MRQ_THERMAL27U
+#define MRQ_CPU_VHINT  28U
+#define MRQ_ABI_RATCHET29U
+#define MRQ_EMC_DVFS_LATENCY   31U
+#define MRQ_TRACE_ITER 64U
+#define MRQ_RINGBUF_CONSOLE65U
+#define MRQ_PG 66U
+#define MRQ_CPU_NDIV_LIMITS67U
+#define MRQ_STRAP   68U
+#define MRQ_UPHY   69U
+#define MRQ_CPU_AUTO_CC3   70U
+#define MRQ_QUERY_FW_TAG   71U
+#define MRQ_FMON   72U
+#define MRQ_EC 73U
+#define MRQ_DEBUG  75U
 
 /** @} */
 
@@ -157,7 +167,7 @@ struct mrq_response {
  * @brief Maximum MRQ code to be sent by CPU software to
  * BPMP. Subject to change in future
  */
-#define MAX_CPU_MRQ_ID 75
+#define MAX_CPU_MRQ_ID 75U
 
 /**
  * @addtogroup MRQ_Payloads
@@ -224,7 +234,7 @@ struct mrq_response {
 struct mrq_ping_request {
 /** @brief Arbitrarily chosen value */
uint32_t challen

arch/mips/alchemy/devboards/db1300.c:(.text.db1300_wm97xx_probe+0x2c): undefined reference to `wm97xx_config_gpio'

2020-07-12 Thread kernel test robot
tree:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 
master
head:   0aea6d5c5be33ce94c16f9ab2f64de1f481f424b
commit: ff487d41036035376e47972c7c522490b839ab37 MIPS: Truncate link address 
into 32bit for 32bit kernel
date:   9 weeks ago
config: mips-randconfig-c023-20200712 (attached as .config)
compiler: mipsel-linux-gcc (GCC) 9.3.0

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

All errors (new ones prefixed by >>):

   mipsel-linux-ld: arch/mips/alchemy/devboards/db1300.o: in function 
`db1300_wm97xx_probe':
>> arch/mips/alchemy/devboards/db1300.c:(.text.db1300_wm97xx_probe+0x2c): 
>> undefined reference to `wm97xx_config_gpio'
>> mipsel-linux-ld: 
>> arch/mips/alchemy/devboards/db1300.c:(.text.db1300_wm97xx_probe+0x4c): 
>> undefined reference to `wm97xx_config_gpio'
>> mipsel-linux-ld: 
>> arch/mips/alchemy/devboards/db1300.c:(.text.db1300_wm97xx_probe+0x74): 
>> undefined reference to `wm97xx_register_mach_ops'

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


.config.gz
Description: application/gzip


[PATCH 4/5] firmware: tegra: Add support for in-band debug

2020-07-12 Thread Jon Hunter
Add support for retrieving BPMP debug information via in-band messaging
as opposed to using shared-memory which older BPMP firmware used. Note
that it is possible to detect at runtime whether the BPMP firmware being
used supports the in-band messaging for retrieving the debug
informaation. Therefore, if the BPMP firmware supports the in-band
messaging for debug use this and otherwise fall-back to using shared
memory.

Signed-off-by: Jon Hunter 
---
 drivers/firmware/tegra/bpmp-debugfs.c | 377 +-
 include/soc/tegra/bpmp-abi.h  | 189 -
 2 files changed, 557 insertions(+), 9 deletions(-)

diff --git a/drivers/firmware/tegra/bpmp-debugfs.c 
b/drivers/firmware/tegra/bpmp-debugfs.c
index a1a1a3b9e667..fb269f940a35 100644
--- a/drivers/firmware/tegra/bpmp-debugfs.c
+++ b/drivers/firmware/tegra/bpmp-debugfs.c
@@ -4,11 +4,14 @@
  */
 #include 
 #include 
+#include 
 #include 
 
 #include 
 #include 
 
+static DEFINE_MUTEX(bpmp_debug_lock);
+
 struct seqbuf {
char *buf;
size_t pos;
@@ -96,6 +99,354 @@ static const char *get_filename(struct tegra_bpmp *bpmp,
return filename;
 }
 
+static int mrq_debug_open(struct tegra_bpmp *bpmp, const char *name,
+ uint32_t *fd, uint32_t *len, bool write)
+{
+   struct mrq_debug_request req = {
+   .cmd = cpu_to_le32(write ? CMD_DEBUG_OPEN_WO : \
+  CMD_DEBUG_OPEN_RO),
+   };
+   struct mrq_debug_response resp;
+   struct tegra_bpmp_message msg = {
+   .mrq = MRQ_DEBUG,
+   .tx = {
+   .data = &req,
+   .size = sizeof(req),
+   },
+   .rx = {
+   .data = &resp,
+   .size = sizeof(resp),
+   },
+   };
+   ssize_t sz_name;
+   int err = 0;
+
+   sz_name = strscpy(req.fop.name, name, sizeof(req.fop.name));
+   if (sz_name < 0) {
+   pr_err("File name too large: %s\n", name);
+   return -EINVAL;
+   }
+
+   err = tegra_bpmp_transfer(bpmp, &msg);
+   if (err < 0)
+   return err;
+   else if (msg.rx.ret < 0)
+   return -EINVAL;
+
+   *len = resp.fop.datalen;
+   *fd = resp.fop.fd;
+
+   return 0;
+}
+
+static int mrq_debug_close(struct tegra_bpmp *bpmp, uint32_t fd)
+{
+   struct mrq_debug_request req = {
+   .cmd = cpu_to_le32(CMD_DEBUG_CLOSE),
+   .frd = {
+   .fd = fd,
+   },
+   };
+   struct mrq_debug_response resp;
+   struct tegra_bpmp_message msg = {
+   .mrq = MRQ_DEBUG,
+   .tx = {
+   .data = &req,
+   .size = sizeof(req),
+   },
+   .rx = {
+   .data = &resp,
+   .size = sizeof(resp),
+   },
+   };
+   int err = 0;
+
+   err = tegra_bpmp_transfer(bpmp, &msg);
+   if (err < 0)
+   return err;
+   else if (msg.rx.ret < 0)
+   return -EINVAL;
+
+   return 0;
+}
+
+static int mrq_debug_read(struct tegra_bpmp *bpmp, const char *name,
+ char *data, size_t sz_data, uint32_t *nbytes)
+{
+   struct mrq_debug_request req = {
+   .cmd = cpu_to_le32(CMD_DEBUG_READ),
+   };
+   struct mrq_debug_response resp;
+   struct tegra_bpmp_message msg = {
+   .mrq = MRQ_DEBUG,
+   .tx = {
+   .data = &req,
+   .size = sizeof(req),
+   },
+   .rx = {
+   .data = &resp,
+   .size = sizeof(resp),
+   },
+   };
+   uint32_t fd = 0, len = 0;
+   int remaining, err;
+
+   mutex_lock(&bpmp_debug_lock);
+   err = mrq_debug_open(bpmp, name, &fd, &len, 0);
+   if (err)
+   goto out;
+
+   if (len > sz_data) {
+   err = -EFBIG;
+   goto close;
+   }
+
+   req.frd.fd = fd;
+   remaining = len;
+
+   while (remaining > 0) {
+   err = tegra_bpmp_transfer(bpmp, &msg);
+   if (err < 0) {
+   goto close;
+   } else if (msg.rx.ret < 0) {
+   err = -EINVAL;
+   goto close;
+   }
+
+   if (resp.frd.readlen > remaining) {
+   pr_err("%s: read data length invalid\n", __func__);
+   err = -EINVAL;
+   goto close;
+   }
+
+   memcpy(data, resp.frd.data, resp.frd.readlen);
+   data += resp.frd.readlen;
+   remaining -= resp.frd.readlen;
+   }
+
+   *nbytes = len;
+
+close:
+   err = mrq_debug_close(bpmp, fd);
+out:
+   mutex_unlock(&bpmp_debug_lock);
+   return err;
+}
+
+stat

[PATCH 0/5] firmware: tegra: Add support for in-band debug

2020-07-12 Thread Jon Hunter
This series adds support for in-band debug messaging for the BPMP and
updates the BPMP ABI to align with the latest version.

Jon Hunter (4):
  firmware: tegra: Use consistent return variable name
  firmware: tegra: Prepare for supporting in-band debugfs
  firmware: tegra: Add support for in-band debug
  firmware: tegra: Update BPMP ABI

Timo Alho (1):
  firmware: tegra: add return code checks and increase debugfs size

 drivers/firmware/tegra/bpmp-debugfs.c | 436 ++--
 drivers/firmware/tegra/bpmp.c |   6 +-
 include/soc/tegra/bpmp-abi.h  | 913 ++
 3 files changed, 1038 insertions(+), 317 deletions(-)

-- 
2.17.1



RE: [PATCH v3] scsi: ufs: Cleanup completed request without interrupt notification

2020-07-12 Thread Avri Altman


> 
> Hi Avri,
> 
> On Thu, 2020-07-09 at 08:31 +, Avri Altman wrote:
> > >
> > > If somehow no interrupt notification is raised for a completed request
> > > and its doorbell bit is cleared by host, UFS driver needs to cleanup
> > > its outstanding bit in ufshcd_abort().
> > Theoretically, this case is already accounted for -
> > See line 6407: a proper error is issued and eventually outstanding req is
> cleared.
> >
> > Can you go over the scenario you are attending line by line,
> > And explain why ufshcd_abort does not account for it?
> 
> Sure.
> 
> If a request using tag N is completed by UFS device without interrupt
> notification till timeout happens, ufshcd_abort() will be invoked.
> 
> Since request completion flow is not executed, current status may be
> 
> - Tag N in hba->outstanding_reqs is set
> - Tag N in doorbell register is not set
> 
> In this case, ufshcd_abort() flow would be
> 
> - This log is printed: "ufshcd_abort: cmd was completed, but without a
> notifying intr, tag = N"
> - This log is printed: "ufshcd_abort: Device abort task at tag N"
> - If hba->req_abort_skip is zero, QUERY_TASK command is sent
> - Device responds "UPIU_TASK_MANAGEMENT_FUNC_COMPL"
> - This log is printed: "ufshcd_abort: cmd at tag N not pending in the
> device."
> - Doorbell tells that tag N is not set, so the driver goes to label
> "out" with this log printed: "ufshcd_abort: cmd at tag %d successfully
> cleared from DB."
> - In label "out" section, no cleanup will be made, and then ufshcd_abort
> exits
> - This request will be re-queued to request queue by SCSI timeout
> handler
> 
> Now, Inconsistent state shows-up: A request is "re-queued" but its
> corresponding resource in UFS layer is not cleared, below flow will
> trigger bad things,
> 
> - A new request with tag M is finished
> - Interrupt is raised and ufshcd_transfer_req_compl() found both tag N
> and M can process the completion flow
> - The post-processing flow for tag N will be executed while its request
> is still alive
> 
> I am sorry that below messages are only for old kernel in non-blk-mq
> case. However above scenario will also trigger bad thing in blk-mq case.

Ok.  Thanks.

> 
> >
> > >
> > > Otherwise, system may crash by below abnormal flow:
> > >
> > > After this request is requeued by SCSI layer with its
> > > outstanding bit set, the next completed request will trigger
> > > ufshcd_transfer_req_compl() to handle all "completed outstanding
> > > bits". In this time, the "abnormal outstanding bit" will be detected
> > > and the "requeued request" will be chosen to execute request
> > > post-processing flow. This is wrong and blk_finish_request() will
> > > BUG_ON because this request is still "alive".
> > >
> > > It is worth mentioning that before ufshcd_abort() cleans the timed-out
> > > request, driver need to check again if this request is really not
> > > handled by __ufshcd_transfer_req_compl() yet because it may be
> > > possible that the interrupt comes very lately before the cleaning.
> > What do you mean? Why checking the outstanding reqs isn't enough?
> >
> > >
> > > Signed-off-by: Stanley Chu 
> > > ---
> > >  drivers/scsi/ufs/ufshcd.c | 9 +++--
> > >  1 file changed, 7 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> > > index 8603b07045a6..f23fb14df9f6 100644
> > > --- a/drivers/scsi/ufs/ufshcd.c
> > > +++ b/drivers/scsi/ufs/ufshcd.c
> > > @@ -6462,7 +6462,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
> > > /* command completed already */
> > > dev_err(hba->dev, "%s: cmd at tag %d successfully 
> > > cleared
> from
> > > DB.\n",
> > > __func__, tag);
> > > -   goto out;
> > > +   goto cleanup;
> > But you've arrived here only if (!(test_bit(tag, &hba->outstanding_reqs))) -
> > See line 6400.
> >
> > > } else {
> > > dev_err(hba->dev,
> > > "%s: no response from device. tag = %d, 
> > > err %d\n",
> > > @@ -6496,9 +6496,14 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
> > > goto out;
> > > }
> > >
> > > +cleanup:
> > > +   spin_lock_irqsave(host->host_lock, flags);
> > > +   if (!test_bit(tag, &hba->outstanding_reqs)) {
Is this needed?  it was already checked in line 6439.

Thanks,
Avri

> > > +   spin_unlock_irqrestore(host->host_lock, flags);
> > > +   goto out;
> > > +   }
> > > scsi_dma_unmap(cmd);
> > >
> > > -   spin_lock_irqsave(host->host_lock, flags);
> > > ufshcd_outstanding_req_clear(hba, tag);
> > > hba->lrb[tag].cmd = NULL;
> > > spin_unlock_irqrestore(host->host_lock, flags);
> > > --
> > > 2.18.0



[PATCH 1/2] cpufreq: tegra186: Fix initial frequency

2020-07-12 Thread Jon Hunter
Commit 6cc3d0e9a097 ("cpufreq: tegra186: add
CPUFREQ_NEED_INITIAL_FREQ_CHECK flag") fixed CPUFREQ support for
Tegra186 but as a consequence the following warnings are now seen on
boot ...

 cpufreq: cpufreq_online: CPU0: Running at unlisted freq: 0 KHz
 cpufreq: cpufreq_online: CPU0: Unlisted initial frequency changed to: 2035200 
KHz
 cpufreq: cpufreq_online: CPU1: Running at unlisted freq: 0 KHz
 cpufreq: cpufreq_online: CPU1: Unlisted initial frequency changed to: 2035200 
KHz
 cpufreq: cpufreq_online: CPU2: Running at unlisted freq: 0 KHz
 cpufreq: cpufreq_online: CPU2: Unlisted initial frequency changed to: 2035200 
KHz
 cpufreq: cpufreq_online: CPU3: Running at unlisted freq: 0 KHz
 cpufreq: cpufreq_online: CPU3: Unlisted initial frequency changed to: 2035200 
KHz
 cpufreq: cpufreq_online: CPU4: Running at unlisted freq: 0 KHz
 cpufreq: cpufreq_online: CPU4: Unlisted initial frequency changed to: 2035200 
KHz
 cpufreq: cpufreq_online: CPU5: Running at unlisted freq: 0 KHz
 cpufreq: cpufreq_online: CPU5: Unlisted initial frequency changed to: 2035200 
KHz

Although we could fix this by adding a 'get' operator for the Tegra186
CPUFREQ driver, there is really little point because the CPUFREQ on
Tegra186 is set by writing a value stored in the frequency table to a
register and we just need to set the initial frequency. So for Tegra186
the simplest way to fix this is read the register that sets the
frequency for each CPU and set the initial frequency when initialising
the CPUFREQ driver.

Signed-off-by: Jon Hunter 
---
 drivers/cpufreq/tegra186-cpufreq.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/cpufreq/tegra186-cpufreq.c 
b/drivers/cpufreq/tegra186-cpufreq.c
index 3d2f143748ef..c44190ce3f03 100644
--- a/drivers/cpufreq/tegra186-cpufreq.c
+++ b/drivers/cpufreq/tegra186-cpufreq.c
@@ -59,6 +59,7 @@ static int tegra186_cpufreq_init(struct cpufreq_policy 
*policy)
struct tegra186_cpufreq_cluster *cluster = &data->clusters[i];
const struct tegra186_cpufreq_cluster_info *info =
cluster->info;
+   u32 edvd_val;
int core;
 
for (core = 0; core < ARRAY_SIZE(info->cpus); core++) {
@@ -71,6 +72,13 @@ static int tegra186_cpufreq_init(struct cpufreq_policy 
*policy)
policy->driver_data =
data->regs + info->offset + EDVD_CORE_VOLT_FREQ(core);
policy->freq_table = cluster->table;
+
+   edvd_val = readl(policy->driver_data);
+
+   for (i = 0; cluster->table[i].frequency != CPUFREQ_TABLE_END; 
i++) {
+   if (cluster->table[i].driver_data == edvd_val)
+   policy->cur = cluster->table[i].frequency;
+   }
break;
}
 
-- 
2.17.1



[PATCH 2/2] cpufreq: tegra186: Simplify probe return path

2020-07-12 Thread Jon Hunter
We always put the reference to BPMP device on exit of the Tegra186
CPUFREQ driver and so there is no need to have separate exit paths
for success and failure. Therefore, simplify the probe return path
in the Tegra186 CPUFREQ driver by combining the success and failure
paths.

Signed-off-by: Jon Hunter 
---
 drivers/cpufreq/tegra186-cpufreq.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/cpufreq/tegra186-cpufreq.c 
b/drivers/cpufreq/tegra186-cpufreq.c
index c44190ce3f03..bf8cab357277 100644
--- a/drivers/cpufreq/tegra186-cpufreq.c
+++ b/drivers/cpufreq/tegra186-cpufreq.c
@@ -231,15 +231,9 @@ static int tegra186_cpufreq_probe(struct platform_device 
*pdev)
}
}
 
-   tegra_bpmp_put(bpmp);
-
tegra186_cpufreq_driver.driver_data = data;
 
err = cpufreq_register_driver(&tegra186_cpufreq_driver);
-   if (err)
-   return err;
-
-   return 0;
 
 put_bpmp:
tegra_bpmp_put(bpmp);
-- 
2.17.1



[GIT PULL] Btrfs fixes for 5.8-rc5, part 2

2020-07-12 Thread David Sterba
Hi,

please pull two refcounting fixes and one prepartory patch for upcoming
splice cleanup. Thanks.

- fix double put of block group with nodatacow

- fix missing block group put when remounting with discard=async

- explicitly set splice callback (no functional change), to ease
  integrating splice cleanup patches


The following changes since commit 0465337c5599bbe360cdcff452992a1a6b7ed2d4:

  btrfs: reset tree root pointer after error in init_tree_roots (2020-07-02 
10:27:12 +0200)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git for-5.8-rc4-tag

for you to fetch changes up to d77765911385b65fc82d74ab71b8983cddfe0b58:

  btrfs: wire up iter_file_splice_write (2020-07-09 19:57:58 +0200)


Christoph Hellwig (1):
  btrfs: wire up iter_file_splice_write

Josef Bacik (1):
  btrfs: fix double put of block group with nocow

Qu Wenruo (1):
  btrfs: discard: add missing put when grabbing block group from unused list

 fs/btrfs/discard.c | 1 +
 fs/btrfs/file.c| 1 +
 fs/btrfs/inode.c   | 9 +
 3 files changed, 3 insertions(+), 8 deletions(-)


[PATCH 2/2] usb: tegra: Fix zero length memory allocation

2020-07-12 Thread Jon Hunter
After commit cad064f1bd52 ("devres: handle zero size in devm_kmalloc()")
was added system suspend started failing on Tegra186. The kernel log
showed that the Tegra XHCI driver was crashing on entry to suspend when
attemptin the save the USB context. The problem is caused because we
are trying to allocate a zero length array for the IPFS context on
Tegra186 and following commit cad064f1bd52 ("devres: handle zero size
in devm_kmalloc()") this now causes a NULL pointer deference crash
when we try to access the memory. Fix this by only allocating memory
for both the IPFS and FPCI contexts when required.

Cc: sta...@vger.kernel.org

Fixes: 5c4e8d3781bc ("usb: host: xhci-tegra: Add support for XUSB context 
save/restore")

Signed-off-by: Jon Hunter 
---
 drivers/usb/host/xhci-tegra.c | 22 ++
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c
index 014d79334f50..b2e4e1c128b0 100644
--- a/drivers/usb/host/xhci-tegra.c
+++ b/drivers/usb/host/xhci-tegra.c
@@ -851,15 +851,21 @@ static int tegra_xusb_init_context(struct tegra_xusb 
*tegra)
 {
const struct tegra_xusb_context_soc *soc = tegra->soc->context;
 
-   tegra->context.ipfs = devm_kcalloc(tegra->dev, soc->ipfs.num_offsets,
-  sizeof(u32), GFP_KERNEL);
-   if (!tegra->context.ipfs)
-   return -ENOMEM;
+   if (soc->ipfs.num_offsets > 0) {
+   tegra->context.ipfs = devm_kcalloc(tegra->dev,
+  soc->ipfs.num_offsets,
+  sizeof(u32), GFP_KERNEL);
+   if (!tegra->context.ipfs)
+   return -ENOMEM;
+   }
 
-   tegra->context.fpci = devm_kcalloc(tegra->dev, soc->fpci.num_offsets,
-  sizeof(u32), GFP_KERNEL);
-   if (!tegra->context.fpci)
-   return -ENOMEM;
+   if (soc->fpci.num_offsets > 0) {
+   tegra->context.fpci = devm_kcalloc(tegra->dev,
+  soc->fpci.num_offsets,
+  sizeof(u32), GFP_KERNEL);
+   if (!tegra->context.fpci)
+   return -ENOMEM;
+   }
 
return 0;
 }
-- 
2.17.1



[PATCH 1/2] usb: tegra: Fix allocation for the FPCI context

2020-07-12 Thread Jon Hunter
Commit 5c4e8d3781bc ("usb: host: xhci-tegra: Add support for XUSB
context save/restore") is using the IPFS 'num_offsets' value when
allocating memory for FPCI context instead of the FPCI 'num_offsets'.
We have not observed any specific issues because of this, but could
cause too much memory or too little memory to be allocated. Fix this
by using the FPCI 'num_offsets' for allocating the FPCI memory for
storing the FPCI state.

Cc: sta...@vger.kernel.org

Fixes: 5c4e8d3781bc ("usb: host: xhci-tegra: Add support for XUSB context 
save/restore")

Signed-off-by: Jon Hunter 
---
 drivers/usb/host/xhci-tegra.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c
index 9ce28ab47f4b..014d79334f50 100644
--- a/drivers/usb/host/xhci-tegra.c
+++ b/drivers/usb/host/xhci-tegra.c
@@ -856,7 +856,7 @@ static int tegra_xusb_init_context(struct tegra_xusb *tegra)
if (!tegra->context.ipfs)
return -ENOMEM;
 
-   tegra->context.fpci = devm_kcalloc(tegra->dev, soc->ipfs.num_offsets,
+   tegra->context.fpci = devm_kcalloc(tegra->dev, soc->fpci.num_offsets,
   sizeof(u32), GFP_KERNEL);
if (!tegra->context.fpci)
return -ENOMEM;
-- 
2.17.1



[PATCH v4] ARM: dts: am335x-pocketbeagle: set default mux for gpio pins

2020-07-12 Thread Drew Fustini
These pins on the PocketBeagle P1 and P2 headers are connected to AM3358
balls with gpio lines, and these pins are not used for any other
peripherals by default. These GPIO lines are unclaimed and could be used
by userspace program through the gpiod ABI.

This patch adds a "default" state in the am33xx_pinmux node and sets the
mux for those pins to gpio (mode 7) and input enable.

The "pinctrl-single,bias-pullup" and "pinctrl-single,bias-pulldown"
pinconf properties are also set for each pin per the ball reset state in
section 4.2 of the datasheet [0].

This is the AM335x pin control register format in Table 9-60 [1]:

 bit attribute  value
--
31-7 reserved   0 on reset
   6 slew   { 0: fast, 1: slow }
   5 rx_active  { 0: rx disable, 1: rx enabled }
   4 pu_typesel { 0: pulldown select, 1: pullup select }
   3 puden  { 0: pud enable, 1: disabled }
   2 mode   3 bits to selec mode 0 to 7
   1 mode
   0 mode

The values for the bias pinconf properties are derived as follows:

pinctrl-single,bias-pullup   = <[input] [enabled] [disable] [mask]>;
pinctrl-single,bias-pullup   = <  0x10  0x10  0x10   0x18 >;

  2^52^42^32^22^12^0  |
 0x20   0x10   0x08   0x04   0x02   0x01  |
--|
input   x  1  0 x  x  x   | 0x10
enabled x  1  0 x  x  x   | 0x10
disabledx  0  0 x  x  x   | 0x00
maskx  1  1 x  x  x   | 0x18

pinctrl-single,bias-pulldown = <[input] [enabled] [disable] [mask]>;
pinctrl-single,bias-pulldown = <   0x0   0x0  0x10   0x18 >;

  2^52^42^32^22^12^0  |
 0x20   0x10   0x08   0x04   0x02   0x01  |
--|
input   x  0  0 x  x  x   | 0x00
enabled x  0  0 x  x  x   | 0x00
disabledx  1  0 x  x  x   | 0x10
maskx  1  1 x  x  x   | 0x18

[0] http://www.ti.com/lit/ds/symlink/am3358.pdf
[1] https://www.ti.com/lit/ug/spruh73q/spruh73q.pdf

Signed-off-by: Drew Fustini 
---
v4 changes:
- patch on top of tony's omap-for-v5.9/dt as there is already
  e14d2c766392 ("ARM: dts: am335x-pocketbeagle: add gpio-line-names")

- correct values for input and disable in pinctrl-single,bias-pullup
  and pinctrl-single,bias-pulldown

v3 changes:
- add pinconf bias properties as it is necessary for pcs_pinconf_set()
  to find the requested bias parameter in the PIN_MAP_TYPE_CONFIGS_GROUP
  pinctrl map.

v2 changes:
- change default mux from output to input.  Input is safer as it does
  not drive the line.  If the user wants output, they will need to edit
  this device tree.

 arch/arm/boot/dts/am335x-pocketbeagle.dts | 125 ++
 1 file changed, 125 insertions(+)

diff --git a/arch/arm/boot/dts/am335x-pocketbeagle.dts 
b/arch/arm/boot/dts/am335x-pocketbeagle.dts
index e08b5f73ccb5..e083ea36184d 100644
--- a/arch/arm/boot/dts/am335x-pocketbeagle.dts
+++ b/arch/arm/boot/dts/am335x-pocketbeagle.dts
@@ -204,6 +204,131 @@ &gpio3 {
 };
 
 &am33xx_pinmux {
+
+   pinctrl-names = "default";
+
+   pinctrl-0 =   < &P2_03_gpio &P1_34_gpio &P2_19_gpio &P2_24_gpio
+   &P2_33_gpio &P2_22_gpio &P2_18_gpio &P2_10_gpio
+   &P2_06_gpio &P2_04_gpio &P2_02_gpio &P2_08_gpio
+   &P2_17_gpio >;
+
+   /* P2_03 (ZCZ ball T10) gpio0_23 0x824 PIN 9 */
+   P2_03_gpio: pinmux_P2_03_gpio {
+   pinctrl-single,pins = <
+   AM33XX_PADCONF(AM335X_PIN_GPMC_AD9, PIN_INPUT_PULLUP, 
MUX_MODE7)
+   >;
+   pinctrl-single,bias-pullup   =   < 0x10  0x10  0x00  0x18>;
+   pinctrl-single,bias-pulldown   = < 0x10  0x00  0x10  0x18>;
+   };
+
+   /* P1_34 (ZCZ ball T11) gpio0_26 0x828 PIN 10 */
+   P1_34_gpio: pinmux_P1_34_gpio {
+   pinctrl-single,pins = <
+   AM33XX_PADCONF(AM335X_PIN_GPMC_AD10, PIN_INPUT_PULLUP, 
MUX_MODE7)
+   >;
+   pinctrl-single,bias-pullup   =   < 0x10  0x10  0x00  0x18>;
+   pinctrl-single,bias-pulldown   = < 0x10  0x00  0x10  0x18>;
+   };
+
+   /* P2_19 (ZCZ ball U12) gpio0_27 0x82c PIN 11 */
+   P2_19_gpio: pinmux_P2_19_gpio {
+   pinctrl-single,pins = <
+   AM33XX_PADCONF(AM335X_PIN_GPMC_AD11, PIN_INPUT_PULLUP, 
MUX_MODE7)
+   >;
+   pinctrl-single,bias-pullup   =   < 0x10  0x10  0x00  0x18>;
+   pinctrl-single,bias-pulldown   = < 0x10  0x00  0x10  0x18>;
+   };
+
+   /* P2_24 (ZCZ ball T12) gpio1_12 0x830 PIN 12 */
+   P2_24_gpio: pinmux_P2_24_gpio {
+   pinctrl-single,pins = <
+   AM33XX_PADCONF(AM335X_PIN_GPMC_A

Re: [PATCH] SUPERH: Replace HTTP links with HTTPS ones

2020-07-12 Thread Rob Landley
On 7/8/20 9:17 PM, Alexander A. Klimov wrote:
> diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
> index 9fc2b010e938..bc91bdb0b665 100644
> --- a/arch/sh/Kconfig
> +++ b/arch/sh/Kconfig
> @@ -74,7 +74,7 @@ config SUPERH
> The SuperH is a RISC processor targeted for use in embedded systems
> and consumer electronics; it was also used in the Sega Dreamcast
> gaming console.  The SuperH port has a home page at
> -   .
> +   .

That's a historical page last edited in 2006 (according to
http://www.linux-sh.org/shwiki/RecentChanges/ anyway) with a self-signed
certificate that pops up a full page warning on chrome about the certificate
being invalid, in a wiki that can theoretically be edited by arbitrary third
parties anyway.

Not a huge man-in-the-middle target.

Rob


[PATCH] fbdev: Detect integer underflow at "struct fbcon_ops"->clear_margins.

2020-07-12 Thread Tetsuo Handa
I found that

  const int fd = open("/dev/fb0", O_ACCMODE);
  struct fb_var_screeninfo var = { };
  ioctl(fd, FBIOGET_VSCREENINFO, &var);
  var.xres = var.yres = 1;
  ioctl(fd, FBIOPUT_VSCREENINFO, &var);

causes general protection fault in bitfill_aligned(), for vc_do_resize()
updates vc->vc_{cols,rows} only when vc_do_resize() will return 0.

[   20.10] BUG: unable to handle page fault for address: b80500d7b000
[   20.102225] #PF: supervisor write access in kernel mode
[   20.102226] #PF: error_code(0x0002) - not-present page
[   20.102227] PGD 13a48c067 P4D 13a48c067 PUD 13a48d067 PMD 132525067 PTE 0
[   20.102230] Oops: 0002 [#1] SMP
[   20.102232] CPU: 3 PID: 2786 Comm: a.out Not tainted 5.8.0-rc4+ #749
[   20.102233] Hardware name: VMware, Inc. VMware Virtual Platform/440BX 
Desktop Reference Platform, BIOS 6.00 02/27/2020
[   20.102237] RIP: 0010:bitfill_aligned+0x87/0x120 [cfbfillrect]
[   20.102277] Call Trace:
[   20.102281]  cfb_fillrect+0x159/0x340 [cfbfillrect]
[   20.102747]  vmw_fb_fillrect+0x12/0x30 [vmwgfx]
[   20.102755]  bit_clear_margins+0x92/0xf0 [fb]
[   20.102760]  fbcon_clear_margins+0x4c/0x50 [fb]
[   20.102763]  fbcon_switch+0x321/0x570 [fb]
[   20.102771]  redraw_screen+0xe0/0x250
[   20.102775]  fbcon_modechanged+0x164/0x1b0 [fb]
[   20.102779]  fbcon_update_vcs+0x15/0x20 [fb]
[   20.102781]  fb_set_var+0x364/0x3c0 [fb]
[   20.102817]  do_fb_ioctl+0x2ff/0x3f0 [fb]
[   20.103139]  fb_ioctl+0x2e/0x40 [fb]
[   20.103141]  ksys_ioctl+0x86/0xc0
[   20.103146]  __x64_sys_ioctl+0x15/0x20
[   20.103148]  do_syscall_64+0x54/0xa0
[   20.103151]  entry_SYSCALL_64_after_hwframe+0x44/0xa9

If vc_do_resize() fails (e.g. kzalloc() failure) when var.xres or var.yres
is going to shrink, bit_clear_margins() hits integer underflow bug due to
info->var.xres < (vc->vc_cols * cw) or info->var.yres < (vc->vc_rows * ch).
Unexpectedly large rw or bh will try to overrun the __iomem region and
causes general protection fault.

This crash is easily reproducible by calling vc_do_resize(vc, 0, 0)
which the reproducer above will do. Since fbcon_modechanged() is doing

  cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
  rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
  cols /= vc->vc_font.width;
  rows /= vc->vc_font.height;
  vc_resize(vc, cols, rows);
  (...snipped...)
  update_screen(vc);

, var.xres < vc->vc_font.width makes cols = 0 and var.yres < vc->vc_font.height
makes rows = 0. But vc_do_resize() does not set vc->vc_cols = vc->vc_rows = 0
due to

  new_cols = (cols ? cols : vc->vc_cols);
  new_rows = (lines ? lines : vc->vc_rows);

exception.

Of course, the root problem is that callers of do_vc_resize() are not
handling vc_do_resize() failures, but it might not be easy to handle
them under complicated dependency. Therefore, as a band-aid workaround,
this patch checks integer underflow in "struct fbcon_ops"->clear_margins
call, assuming that vc->vc_cols * vc->vc_font.width and
vc->vc_rows * vc->vc_font.heigh do not cause integer overflow.

I hope that we can survive even if info->var.{xres,yres} were increased
but vc->vc_{cols,rows} were not increased due to kzalloc() failure, for
the __iomem memory for cfb_fillrect() seems to be allocated upon driver
load.

By the way, syzbot has several reports which are stalling inside filling
functions. Although reproducer for [1] is not found yet, it has tried

  r0 = openat$fb0(0xff9c, &(0x7f000180)='/dev/fb0\x00', 0x0, 
0x0)
  ioctl$FBIOPUT_VSCREENINFO(r0, 0x4601, &(0x7f00)={0x0, 0x0, 0x0, 
0x500, 0x0, 0x0, 0x4})

which corresponds to

  const int fd = open("/dev/fb0", O_ACCMODE);
  struct fb_var_screeninfo var = { };
  var.yres_virtual = 0x500;
  var.bits_per_pixel = 4;
  ioctl(fd, FBIOPUT_VSCREENINFO, &var);

and somehow hit unexpectedly long bit_clear_margins() loops. I don't know
why syzbot does not hit general protection fault, but it would depend on
environment because in my VMware environment ioctl(FBIOPUT_VSCREENINFO)
returns -EINVAL if var.xres == var.yres == 0.

[1] 
https://syzkaller.appspot.com/bug?id=91ecc3bf32ab1a551c33a39dab7fc0c8cd7b7e16

Signed-off-by: Tetsuo Handa 
---
 drivers/video/fbdev/core/bitblit.c   | 4 ++--
 drivers/video/fbdev/core/fbcon_ccw.c | 4 ++--
 drivers/video/fbdev/core/fbcon_cw.c  | 4 ++--
 drivers/video/fbdev/core/fbcon_ud.c  | 4 ++--
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/video/fbdev/core/bitblit.c 
b/drivers/video/fbdev/core/bitblit.c
index ca935c09a261..35ebeeccde4d 100644
--- a/drivers/video/fbdev/core/bitblit.c
+++ b/drivers/video/fbdev/core/bitblit.c
@@ -216,7 +216,7 @@ static void bit_clear_margins(struct vc_data *vc, struct 
fb_info *info,
region.color = color;
region.rop = ROP_COPY;
 
-   if (rw && !bottom_only) {
+   if ((int) rw > 0 && !bottom_only) {
region.dx = info->var.xoffset + rs;
region.dy = 0;
region.width = rw;
@@ -224,7 +224,7 @@ static v

[PATCH v3] vt: Reject zero-sized screen buffer size.

2020-07-12 Thread Tetsuo Handa
syzbot is reporting general protection fault in do_con_write() [1] caused
by vc->vc_screenbuf == ZERO_SIZE_PTR caused by vc->vc_screenbuf_size == 0
caused by vc->vc_cols == vc->vc_rows == vc->vc_size_row == 0 caused by
fb_set_var() from ioctl(FBIOPUT_VSCREENINFO) on /dev/fb0 , for
gotoxy(vc, 0, 0) from reset_terminal() from vc_init() from vc_allocate()
 from con_install() from tty_init_dev() from tty_open() on such console
causes vc->vc_pos == 0x1000e due to
((unsigned long) ZERO_SIZE_PTR) + -1U * 0 + (-1U << 1).

I don't think that a console with 0 column or 0 row makes sense. And it
seems that vc_do_resize() does not intend to allow resizing a console to
0 column or 0 row due to

  new_cols = (cols ? cols : vc->vc_cols);
  new_rows = (lines ? lines : vc->vc_rows);

exception.

Theoretically, cols and rows can be any range as long as
0 < cols * rows * 2 <= KMALLOC_MAX_SIZE is satisfied (e.g.
cols == 1048576 && rows == 2 is possible) because of

  vc->vc_size_row = vc->vc_cols << 1;
  vc->vc_screenbuf_size = vc->vc_rows * vc->vc_size_row;

in visual_init() and kzalloc(vc->vc_screenbuf_size) in vc_allocate().

Since we can detect cols == 0 or rows == 0 via screenbuf_size = 0 in
visual_init(), we can reject kzalloc(0). Then, vc_allocate() will return
an error, and con_write() will not be called on a console with 0 column
or 0 row.

We need to make sure that integer overflow in visual_init() won't happen.
Since vc_do_resize() restricts cols <= 32767 and rows <= 32767, applying
1 <= cols <= 32767 and 1 <= rows <= 32767 restrictions to vc_allocate()
will be practically fine.

This patch does not touch con_init(), for returning -EINVAL there
does not help when we are not returning -ENOMEM.

[1] https://syzkaller.appspot.com/bug?extid=017265e8553724e514e8

Reported-and-tested-by: syzbot 

Signed-off-by: Tetsuo Handa 
---
 drivers/tty/vt/vt.c | 29 ++---
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 48a8199f7845..42d8c67a481f 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -1092,10 +1092,19 @@ static const struct tty_port_operations vc_port_ops = {
.destruct = vc_port_destruct,
 };
 
+/*
+ * Change # of rows and columns (0 means unchanged/the size of fg_console)
+ * [this is to be used together with some user program
+ * like resize that changes the hardware videomode]
+ */
+#define VC_MAXCOL (32767)
+#define VC_MAXROW (32767)
+
 int vc_allocate(unsigned int currcons) /* return 0 on success */
 {
struct vt_notifier_param param;
struct vc_data *vc;
+   int err;
 
WARN_CONSOLE_UNLOCKED();
 
@@ -1125,6 +1134,11 @@ int vc_allocate(unsigned int currcons)   /* return 0 on 
success */
if (!*vc->vc_uni_pagedir_loc)
con_set_default_unimap(vc);
 
+   err = -EINVAL;
+   if (vc->vc_cols > VC_MAXCOL || vc->vc_rows > VC_MAXROW ||
+   vc->vc_screenbuf_size > KMALLOC_MAX_SIZE || !vc->vc_screenbuf_size)
+   goto err_free;
+   err = -ENOMEM;
vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_KERNEL);
if (!vc->vc_screenbuf)
goto err_free;
@@ -1143,7 +1157,7 @@ int vc_allocate(unsigned int currcons)/* return 0 on 
success */
visual_deinit(vc);
kfree(vc);
vc_cons[currcons].d = NULL;
-   return -ENOMEM;
+   return err;
 }
 
 static inline int resize_screen(struct vc_data *vc, int width, int height,
@@ -1158,14 +1172,6 @@ static inline int resize_screen(struct vc_data *vc, int 
width, int height,
return err;
 }
 
-/*
- * Change # of rows and columns (0 means unchanged/the size of fg_console)
- * [this is to be used together with some user program
- * like resize that changes the hardware videomode]
- */
-#define VC_RESIZE_MAXCOL (32767)
-#define VC_RESIZE_MAXROW (32767)
-
 /**
  * vc_do_resize-   resizing method for the tty
  * @tty: tty being resized
@@ -1201,7 +1207,7 @@ static int vc_do_resize(struct tty_struct *tty, struct 
vc_data *vc,
user = vc->vc_resize_user;
vc->vc_resize_user = 0;
 
-   if (cols > VC_RESIZE_MAXCOL || lines > VC_RESIZE_MAXROW)
+   if (cols > VC_MAXCOL || lines > VC_MAXROW)
return -EINVAL;
 
new_cols = (cols ? cols : vc->vc_cols);
@@ -1212,7 +1218,7 @@ static int vc_do_resize(struct tty_struct *tty, struct 
vc_data *vc,
if (new_cols == vc->vc_cols && new_rows == vc->vc_rows)
return 0;
 
-   if (new_screen_size > KMALLOC_MAX_SIZE)
+   if (new_screen_size > KMALLOC_MAX_SIZE || !new_screen_size)
return -EINVAL;
newscreen = kzalloc(new_screen_size, GFP_USER);
if (!newscreen)
@@ -3393,6 +3399,7 @@ static int __init con_init(void)
INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
tty_port_init(&vc->port);
visual_init(vc, currcons, 1);
+   /* Assuming vc->vc_{col

[PATCH] sh: Replace HTTP links with HTTPS ones

2020-07-12 Thread Alexander A. Klimov
Rationale:
Reduces attack surface on kernel devs opening the links for MITM
as HTTPS traffic is much harder to manipulate.

Deterministic algorithm:
For each file:
  If not .svg:
For each line:
  If doesn't contain `\bxmlns\b`:
For each link, `\bhttp://[^# \t\r\n]*(?:\w|/)`:
  If neither `\bgnu\.org/license`, nor `\bmozilla\.org/MPL\b`:
If both the HTTP and HTTPS versions
return 200 OK and serve the same content:
  Replace HTTP with HTTPS.

Signed-off-by: Alexander A. Klimov 
---
 Strange... it seems something went wrong while scanning.
 Now better?

 arch/sh/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 9fc2b010e938..2fb9233f031e 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -630,7 +630,7 @@ config SMP
  Y to "Enhanced Real Time Clock Support", below.
 
  See also  and 
the SMP-HOWTO
- available at .
+ available at .
 
  If you don't know what to do here, say N.
 
-- 
2.27.0



[PATCH v5 14/15] vfio: Document dual stage control

2020-07-12 Thread Liu Yi L
From: Eric Auger 

The VFIO API was enhanced to support nested stage control: a bunch of
new iotcls and usage guideline.

Let's document the process to follow to set up nested mode.

Cc: Kevin Tian 
CC: Jacob Pan 
Cc: Alex Williamson 
Cc: Eric Auger 
Cc: Jean-Philippe Brucker 
Cc: Joerg Roedel 
Cc: Lu Baolu 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Eric Auger 
Signed-off-by: Liu Yi L 
---
v3 -> v4:
*) add review-by from Stefan Hajnoczi

v2 -> v3:
*) address comments from Stefan Hajnoczi

v1 -> v2:
*) new in v2, compared with Eric's original version, pasid table bind
   and fault reporting is removed as this series doesn't cover them.
   Original version from Eric.
   https://lkml.org/lkml/2020/3/20/700
---
 Documentation/driver-api/vfio.rst | 67 +++
 1 file changed, 67 insertions(+)

diff --git a/Documentation/driver-api/vfio.rst 
b/Documentation/driver-api/vfio.rst
index f1a4d3c..0672c45 100644
--- a/Documentation/driver-api/vfio.rst
+++ b/Documentation/driver-api/vfio.rst
@@ -239,6 +239,73 @@ group and can access them as follows::
/* Gratuitous device reset and go... */
ioctl(device, VFIO_DEVICE_RESET);
 
+IOMMU Dual Stage Control
+
+
+Some IOMMUs support 2 stages/levels of translation. Stage corresponds to
+the ARM terminology while level corresponds to Intel's VTD terminology.
+In the following text we use either without distinction.
+
+This is useful when the guest is exposed with a virtual IOMMU and some
+devices are assigned to the guest through VFIO. Then the guest OS can use
+stage 1 (GIOVA -> GPA or GVA->GPA), while the hypervisor uses stage 2 for
+VM isolation (GPA -> HPA).
+
+Under dual stage translation, the guest gets ownership of the stage 1 page
+tables and also owns stage 1 configuration structures. The hypervisor owns
+the root configuration structure (for security reason), including stage 2
+configuration. This works as long as configuration structures and page table
+formats are compatible between the virtual IOMMU and the physical IOMMU.
+
+Assuming the HW supports it, this nested mode is selected by choosing the
+VFIO_TYPE1_NESTING_IOMMU type through:
+
+ioctl(container, VFIO_SET_IOMMU, VFIO_TYPE1_NESTING_IOMMU);
+
+This forces the hypervisor to use the stage 2, leaving stage 1 available
+for guest usage. The guest stage 1 format depends on IOMMU vendor, and
+it is the same with the nesting configuration method. User space should
+check the format and configuration method after setting nesting type by
+using:
+
+ioctl(container->fd, VFIO_IOMMU_GET_INFO, &nesting_info);
+
+Details can be found in Documentation/userspace-api/iommu.rst. For Intel
+VT-d, each stage 1 page table is bound to host by:
+
+nesting_op->flags = VFIO_IOMMU_NESTING_OP_BIND_PGTBL;
+memcpy(&nesting_op->data, &bind_data, sizeof(bind_data));
+ioctl(container->fd, VFIO_IOMMU_NESTING_OP, nesting_op);
+
+As mentioned above, guest OS may use stage 1 for GIOVA->GPA or GVA->GPA.
+GVA->GPA page tables are available when PASID (Process Address Space ID)
+is exposed to guest. e.g. guest with PASID-capable devices assigned. For
+such page table binding, the bind_data should include PASID info, which
+is allocated by guest itself or by host. This depends on hardware vendor.
+e.g. Intel VT-d requires to allocate PASID from host. This requirement is
+defined by the Virtual Command Support in VT-d 3.0 spec, guest software
+running on VT-d should allocate PASID from host kernel. To allocate PASID
+from host, user space should check the IOMMU_NESTING_FEAT_SYSWIDE_PASID
+bit of the nesting info reported from host kernel. VFIO reports the nesting
+info by VFIO_IOMMU_GET_INFO. User space could allocate PASID from host by:
+
+req.flags = VFIO_IOMMU_ALLOC_PASID;
+ioctl(container, VFIO_IOMMU_PASID_REQUEST, &req);
+
+With first stage/level page table bound to host, it allows to combine the
+guest stage 1 translation along with the hypervisor stage 2 translation to
+get final address.
+
+When the guest invalidates stage 1 related caches, invalidations must be
+forwarded to the host through
+
+nesting_op->flags = VFIO_IOMMU_NESTING_OP_CACHE_INVLD;
+memcpy(&nesting_op->data, &inv_data, sizeof(inv_data));
+ioctl(container->fd, VFIO_IOMMU_NESTING_OP, nesting_op);
+
+Those invalidations can happen at various granularity levels, page, context,
+...
+
 VFIO User API
 ---
 
-- 
2.7.4



[PATCH v5 10/15] vfio/type1: Support binding guest page tables to PASID

2020-07-12 Thread Liu Yi L
Nesting translation allows two-levels/stages page tables, with 1st level
for guest translations (e.g. GVA->GPA), 2nd level for host translations
(e.g. GPA->HPA). This patch adds interface for binding guest page tables
to a PASID. This PASID must have been allocated to user space before the
binding request.

Cc: Kevin Tian 
CC: Jacob Pan 
Cc: Alex Williamson 
Cc: Eric Auger 
Cc: Jean-Philippe Brucker 
Cc: Joerg Roedel 
Cc: Lu Baolu 
Signed-off-by: Jean-Philippe Brucker 
Signed-off-by: Liu Yi L 
Signed-off-by: Jacob Pan 
---
v3 -> v4:
*) address comments from Alex on v3

v2 -> v3:
*) use __iommu_sva_unbind_gpasid() for unbind call issued by VFIO
   
https://lore.kernel.org/linux-iommu/1592931837-58223-6-git-send-email-jacob.jun@linux.intel.com/

v1 -> v2:
*) rename subject from "vfio/type1: Bind guest page tables to host"
*) remove VFIO_IOMMU_BIND, introduce VFIO_IOMMU_NESTING_OP to support bind/
   unbind guet page table
*) replaced vfio_iommu_for_each_dev() with a group level loop since this
   series enforces one group per container w/ nesting type as start.
*) rename vfio_bind/unbind_gpasid_fn() to vfio_dev_bind/unbind_gpasid_fn()
*) vfio_dev_unbind_gpasid() always successful
*) use vfio_mm->pasid_lock to avoid race between PASID free and page table
   bind/unbind
---
 drivers/vfio/vfio_iommu_type1.c | 166 
 drivers/vfio/vfio_pasid.c   |  26 +++
 include/linux/vfio.h|  20 +
 include/uapi/linux/vfio.h   |  31 
 4 files changed, 243 insertions(+)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index 55b4065..f0f21ff 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -149,6 +149,30 @@ struct vfio_regions {
 #define DIRTY_BITMAP_PAGES_MAX  ((u64)INT_MAX)
 #define DIRTY_BITMAP_SIZE_MAX   DIRTY_BITMAP_BYTES(DIRTY_BITMAP_PAGES_MAX)
 
+struct domain_capsule {
+   struct vfio_group *group;
+   struct iommu_domain *domain;
+   void *data;
+};
+
+/* iommu->lock must be held */
+static struct vfio_group *vfio_find_nesting_group(struct vfio_iommu *iommu)
+{
+   struct vfio_domain *d;
+   struct vfio_group *group = NULL;
+
+   if (!iommu->nesting_info)
+   return NULL;
+
+   /* only support singleton container with nesting type */
+   list_for_each_entry(d, &iommu->domain_list, next) {
+   list_for_each_entry(group, &d->group_list, next) {
+   break;
+   }
+   }
+   return group;
+}
+
 static int put_pfn(unsigned long pfn, int prot);
 
 static struct vfio_group *vfio_iommu_find_iommu_group(struct vfio_iommu *iommu,
@@ -2349,6 +2373,48 @@ static int vfio_iommu_resv_refresh(struct vfio_iommu 
*iommu,
return ret;
 }
 
+static int vfio_dev_bind_gpasid_fn(struct device *dev, void *data)
+{
+   struct domain_capsule *dc = (struct domain_capsule *)data;
+   unsigned long arg = *(unsigned long *)dc->data;
+
+   return iommu_sva_bind_gpasid(dc->domain, dev, (void __user *)arg);
+}
+
+static int vfio_dev_unbind_gpasid_fn(struct device *dev, void *data)
+{
+   struct domain_capsule *dc = (struct domain_capsule *)data;
+   unsigned long arg = *(unsigned long *)dc->data;
+
+   iommu_sva_unbind_gpasid(dc->domain, dev, (void __user *)arg);
+   return 0;
+}
+
+static int __vfio_dev_unbind_gpasid_fn(struct device *dev, void *data)
+{
+   struct domain_capsule *dc = (struct domain_capsule *)data;
+   struct iommu_gpasid_bind_data *unbind_data =
+   (struct iommu_gpasid_bind_data *)dc->data;
+
+   __iommu_sva_unbind_gpasid(dc->domain, dev, unbind_data);
+   return 0;
+}
+
+static void vfio_group_unbind_gpasid_fn(ioasid_t pasid, void *data)
+{
+   struct domain_capsule *dc = (struct domain_capsule *)data;
+   struct iommu_gpasid_bind_data unbind_data;
+
+   unbind_data.argsz = offsetof(struct iommu_gpasid_bind_data, vendor);
+   unbind_data.flags = 0;
+   unbind_data.hpasid = pasid;
+
+   dc->data = &unbind_data;
+
+   iommu_group_for_each_dev(dc->group->iommu_group,
+dc, __vfio_dev_unbind_gpasid_fn);
+}
+
 static void vfio_iommu_type1_detach_group(void *iommu_data,
  struct iommu_group *iommu_group)
 {
@@ -2392,6 +2458,21 @@ static void vfio_iommu_type1_detach_group(void 
*iommu_data,
if (!group)
continue;
 
+   if (iommu->nesting_info && iommu->vmm &&
+   (iommu->nesting_info->features &
+   IOMMU_NESTING_FEAT_BIND_PGTBL)) {
+   struct domain_capsule dc = { .group = group,
+.domain = domain->domain,
+.data = NULL };
+
+   /*
+* Unbind page tables bound w

[PATCH v5 00/15] vfio: expose virtual Shared Virtual Addressing to VMs

2020-07-12 Thread Liu Yi L
Shared Virtual Addressing (SVA), a.k.a, Shared Virtual Memory (SVM) on
Intel platforms allows address space sharing between device DMA and
applications. SVA can reduce programming complexity and enhance security.

This VFIO series is intended to expose SVA usage to VMs. i.e. Sharing
guest application address space with passthru devices. This is called
vSVA in this series. The whole vSVA enabling requires QEMU/VFIO/IOMMU
changes. For IOMMU and QEMU changes, they are in separate series (listed
in the "Related series").

The high-level architecture for SVA virtualization is as below, the key
design of vSVA support is to utilize the dual-stage IOMMU translation (
also known as IOMMU nesting translation) capability in host IOMMU.


.-.  .---.
|   vIOMMU|  | Guest process CR3, FL only|
| |  '---'
./
| PASID Entry |--- PASID cache flush -
'-'   |
| |   V
| |CR3 in GPA
'-'
Guest
--| Shadow |--|
  vv  v
Host
.-.  .--.
|   pIOMMU|  | Bind FL for GVA-GPA  |
| |  '--'
./  |
| PASID Entry | V (Nested xlate)
'\.--.
| |   |SL for GPA-HPA, default domain|
| |   '--'
'-'
Where:
 - FL = First level/stage one page tables
 - SL = Second level/stage two page tables

Patch Overview:
 1. a refactor to vfio_iommu_type1 ioctl (patch 0001)
 2. reports IOMMU nesting info to userspace ( patch 0002, 0003, 0004 and 0015)
 3. vfio support for PASID allocation and free for VMs (patch 0005, 0006, 0007)
 4. vfio support for binding guest page table to host (patch 0008, 0009, 0010)
 5. vfio support for IOMMU cache invalidation from VMs (patch 0011)
 6. vfio support for vSVA usage on IOMMU-backed mdevs (patch 0012)
 7. expose PASID capability to VM (patch 0013)
 8. add doc for VFIO dual stage control (patch 0014)

The complete vSVA kernel upstream patches are divided into three phases:
1. Common APIs and PCI device direct assignment
2. IOMMU-backed Mediated Device assignment
3. Page Request Services (PRS) support

This patchset is aiming for the phase 1 and phase 2, and based on Jacob's
below series.
*) [PATCH v4 0/5] IOMMU user API enhancement - wip
   
https://lore.kernel.org/linux-iommu/1594165429-20075-1-git-send-email-jacob.jun@linux.intel.com/

*) [PATCH 00/10] IOASID extensions for guest SVA - wip
   https://lkml.org/lkml/2020/3/25/874

The latest IOASID code added below new interface for itertate all PASIDs of an
ioasid_set. The implementation is not sent out yet as Jacob needs some cleanup,
it can be found in branch vsva-linux-5.8-rc3-v5 on github (mentioned below):
 int ioasid_set_for_each_ioasid(int sid, void (*fn)(ioasid_t id, void *data), 
void *data);

Complete set for current vSVA can be found in below branch.
https://github.com/luxis1999/linux-vsva.git: vsva-linux-5.8-rc3-v5

The corresponding QEMU patch series is included in below branch:
https://github.com/luxis1999/qemu.git: vsva_5.8_rc3_qemu_rfcv8


Regards,
Yi Liu

Changelog:
- Patch v4 -> Patch v5:
  a) Address comments against v4
  Patch v4: 
https://lore.kernel.org/kvm/1593861989-35920-1-git-send-email-yi.l@intel.com/

- Patch v3 -> Patch v4:
  a) Address comments against v3
  b) Add rb from Stefan on patch 14/15
  Patch v3: 
https://lore.kernel.org/linux-iommu/1592988927-48009-1-git-send-email-yi.l@intel.com/

- Patch v2 -> Patch v3:
  a) Rebase on top of Jacob's v3 iommu uapi patchset
  b) Address comments from Kevin and Stefan Hajnoczi
  c) Reuse DOMAIN_ATTR_NESTING to get iommu nesting info
  d) Drop [PATCH v2 07/15] iommu/uapi: Add iommu_gpasid_unbind_data
  Patch v2: 
https://lore.kernel.org/linux-iommu/1591877734-66527-1-git-send-email-yi.l@intel.com/#r

- Patch v1 -> Patch v2:
  a) Refactor vfio_iommu_type1_ioctl() per suggestion from Christoph
 Hellwig.
  b) Re-sequence the patch series for better bisect support.
  c) Report IOMMU nesting cap info in detail instead of a format in
 v1.
  d) Enforce one group per nesting type container for vfio iommu type1
 driver.
  e) Build the vfio_mm related code from vfio.c to be a separate
 vfio_pasid.ko.
  f) Add PASID ownership check in IOMMU driver.
  g) Adopted to latest IOMMU UAPI design. Removed IOMMU UAPI version
 check. Added iommu_gpasid_unbind_data for unbind requests from
 userspace.
  h) Define a single ioctl:VFIO

[PATCH v5 05/15] vfio: Add PASID allocation/free support

2020-07-12 Thread Liu Yi L
Shared Virtual Addressing (a.k.a Shared Virtual Memory) allows sharing
multiple process virtual address spaces with the device for simplified
programming model. PASID is used to tag an virtual address space in DMA
requests and to identify the related translation structure in IOMMU. When
a PASID-capable device is assigned to a VM, we want the same capability
of using PASID to tag guest process virtual address spaces to achieve
virtual SVA (vSVA).

PASID management for guest is vendor specific. Some vendors (e.g. Intel
VT-d) requires system-wide managed PASIDs cross all devices, regardless
of whether a device is used by host or assigned to guest. Other vendors
(e.g. ARM SMMU) may allow PASIDs managed per-device thus could be fully
delegated to the guest for assigned devices.

For system-wide managed PASIDs, this patch introduces a vfio module to
handle explicit PASID alloc/free requests from guest. Allocated PASIDs
are associated to a process (or, mm_struct) in IOASID core. A vfio_mm
object is introduced to track mm_struct. Multiple VFIO containers within
a process share the same vfio_mm object.

A quota mechanism is provided to prevent malicious user from exhausting
available PASIDs. Currently the quota is a global parameter applied to
all VFIO devices. In the future per-device quota might be supported too.

Cc: Kevin Tian 
CC: Jacob Pan 
Cc: Eric Auger 
Cc: Jean-Philippe Brucker 
Cc: Joerg Roedel 
Cc: Lu Baolu 
Suggested-by: Alex Williamson 
Signed-off-by: Liu Yi L 
---
v4 -> v5:
*) address comments from Eric Auger.
*) address the comments from Alex on the pasid free range support. Added
   per vfio_mm pasid r-b tree.
   https://lore.kernel.org/kvm/20200709082751.32074...@x1.home/

v3 -> v4:
*) fix lock leam in vfio_mm_get_from_task()
*) drop pasid_quota field in struct vfio_mm
*) vfio_mm_get_from_task() returns ERR_PTR(-ENOTTY) when !CONFIG_VFIO_PASID

v1 -> v2:
*) added in v2, split from the pasid alloc/free support of v1
---
 drivers/vfio/Kconfig  |   5 +
 drivers/vfio/Makefile |   1 +
 drivers/vfio/vfio_pasid.c | 235 ++
 include/linux/vfio.h  |  28 ++
 4 files changed, 269 insertions(+)
 create mode 100644 drivers/vfio/vfio_pasid.c

diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig
index fd17db9..3d8a108 100644
--- a/drivers/vfio/Kconfig
+++ b/drivers/vfio/Kconfig
@@ -19,6 +19,11 @@ config VFIO_VIRQFD
depends on VFIO && EVENTFD
default n
 
+config VFIO_PASID
+   tristate
+   depends on IOASID && VFIO
+   default n
+
 menuconfig VFIO
tristate "VFIO Non-Privileged userspace driver framework"
depends on IOMMU_API
diff --git a/drivers/vfio/Makefile b/drivers/vfio/Makefile
index de67c47..bb836a3 100644
--- a/drivers/vfio/Makefile
+++ b/drivers/vfio/Makefile
@@ -3,6 +3,7 @@ vfio_virqfd-y := virqfd.o
 
 obj-$(CONFIG_VFIO) += vfio.o
 obj-$(CONFIG_VFIO_VIRQFD) += vfio_virqfd.o
+obj-$(CONFIG_VFIO_PASID) += vfio_pasid.o
 obj-$(CONFIG_VFIO_IOMMU_TYPE1) += vfio_iommu_type1.o
 obj-$(CONFIG_VFIO_IOMMU_SPAPR_TCE) += vfio_iommu_spapr_tce.o
 obj-$(CONFIG_VFIO_SPAPR_EEH) += vfio_spapr_eeh.o
diff --git a/drivers/vfio/vfio_pasid.c b/drivers/vfio/vfio_pasid.c
new file mode 100644
index 000..66e6054e
--- /dev/null
+++ b/drivers/vfio/vfio_pasid.c
@@ -0,0 +1,235 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 Intel Corporation.
+ * Author: Liu Yi L 
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DRIVER_VERSION  "0.1"
+#define DRIVER_AUTHOR   "Liu Yi L "
+#define DRIVER_DESC "PASID management for VFIO bus drivers"
+
+#define VFIO_DEFAULT_PASID_QUOTA   1000
+static int pasid_quota = VFIO_DEFAULT_PASID_QUOTA;
+module_param_named(pasid_quota, pasid_quota, uint, 0444);
+MODULE_PARM_DESC(pasid_quota,
+" Set the quota for max number of PASIDs that an application 
is allowed to request (default 1000)");
+
+struct vfio_mm_token {
+   unsigned long long val;
+};
+
+struct vfio_mm {
+   struct kref kref;
+   int ioasid_sid;
+   struct mutexpasid_lock;
+   struct rb_root  pasid_list;
+   struct list_headnext;
+   struct vfio_mm_tokentoken;
+};
+
+static struct mutexvfio_mm_lock;
+static struct list_headvfio_mm_list;
+
+struct vfio_pasid {
+   struct rb_node  node;
+   ioasid_tpasid;
+};
+
+static void vfio_remove_all_pasids(struct vfio_mm *vmm);
+
+/* called with vfio.vfio_mm_lock held */
+static void vfio_mm_release(struct kref *kref)
+{
+   struct vfio_mm *vmm = container_of(kref, struct vfio_mm, kref);
+
+   list_del(&vmm->next);
+   mutex_unlock(&vfio_mm_lock);
+   vfio_remove_all_pasids(vmm);
+   ioasid_free_set(vmm->ioasid_sid, true);
+   kfree(vmm);
+}
+
+void vfio_mm_put(struct vfio_mm *vmm)
+{
+   kref_put_mutex(&vmm->kref, vfio_mm_release, &vfio_mm

[PATCH v5 08/15] iommu: Pass domain to sva_unbind_gpasid()

2020-07-12 Thread Liu Yi L
From: Yi Sun 

Current interface is good enough for SVA virtualization on an assigned
physical PCI device, but when it comes to mediated devices, a physical
device may attached with multiple aux-domains. Also, for guest unbind,
the PASID to be unbind should be allocated to the VM. This check requires
to know the ioasid_set which is associated with the domain.

So this interface needs to pass in domain info. Then the iommu driver is
able to know which domain will be used for the 2nd stage translation of
the nesting mode and also be able to do PASID ownership check. This patch
passes @domain per the above reason.

Cc: Kevin Tian 
CC: Jacob Pan 
Cc: Alex Williamson 
Cc: Eric Auger 
Cc: Jean-Philippe Brucker 
Cc: Joerg Roedel 
Cc: Lu Baolu 
Signed-off-by: Yi Sun 
Signed-off-by: Liu Yi L 
---
v2 -> v3:
*) pass in domain info only
*) use ioasid_t for pasid instead of int type

v1 -> v2:
*) added in v2.
---
 drivers/iommu/intel/svm.c   | 3 ++-
 drivers/iommu/iommu.c   | 2 +-
 include/linux/intel-iommu.h | 3 ++-
 include/linux/iommu.h   | 3 ++-
 4 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/intel/svm.c b/drivers/iommu/intel/svm.c
index b9a9c55..d2c0e1a 100644
--- a/drivers/iommu/intel/svm.c
+++ b/drivers/iommu/intel/svm.c
@@ -432,7 +432,8 @@ int intel_svm_bind_gpasid(struct iommu_domain *domain, 
struct device *dev,
return ret;
 }
 
-int intel_svm_unbind_gpasid(struct device *dev, int pasid)
+int intel_svm_unbind_gpasid(struct iommu_domain *domain,
+   struct device *dev, ioasid_t pasid)
 {
struct intel_iommu *iommu = intel_svm_device_to_iommu(dev);
struct intel_svm_dev *sdev;
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 7910249..d3e554c 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2151,7 +2151,7 @@ int __iommu_sva_unbind_gpasid(struct iommu_domain 
*domain, struct device *dev,
if (unlikely(!domain->ops->sva_unbind_gpasid))
return -ENODEV;
 
-   return domain->ops->sva_unbind_gpasid(dev, data->hpasid);
+   return domain->ops->sva_unbind_gpasid(domain, dev, data->hpasid);
 }
 EXPORT_SYMBOL_GPL(__iommu_sva_unbind_gpasid);
 
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index 0d0ab32..18f292e 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -738,7 +738,8 @@ extern int intel_svm_enable_prq(struct intel_iommu *iommu);
 extern int intel_svm_finish_prq(struct intel_iommu *iommu);
 int intel_svm_bind_gpasid(struct iommu_domain *domain, struct device *dev,
  struct iommu_gpasid_bind_data *data);
-int intel_svm_unbind_gpasid(struct device *dev, int pasid);
+int intel_svm_unbind_gpasid(struct iommu_domain *domain,
+   struct device *dev, ioasid_t pasid);
 struct iommu_sva *intel_svm_bind(struct device *dev, struct mm_struct *mm,
 void *drvdata);
 void intel_svm_unbind(struct iommu_sva *handle);
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index e84a1d5..ca5edd8 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -303,7 +303,8 @@ struct iommu_ops {
int (*sva_bind_gpasid)(struct iommu_domain *domain,
struct device *dev, struct iommu_gpasid_bind_data 
*data);
 
-   int (*sva_unbind_gpasid)(struct device *dev, int pasid);
+   int (*sva_unbind_gpasid)(struct iommu_domain *domain,
+struct device *dev, ioasid_t pasid);
 
int (*def_domain_type)(struct device *dev);
 
-- 
2.7.4



[PATCH v5 04/15] vfio/type1: Report iommu nesting info to userspace

2020-07-12 Thread Liu Yi L
This patch exports iommu nesting capability info to user space through
VFIO. User space is expected to check this info for supported uAPIs (e.g.
PASID alloc/free, bind page table, and cache invalidation) and the vendor
specific format information for first level/stage page table that will be
bound to.

The nesting info is available only after the nesting iommu type is set
for a container. Current implementation imposes one limitation - one
nesting container should include at most one group. The philosophy of
vfio container is having all groups/devices within the container share
the same IOMMU context. When vSVA is enabled, one IOMMU context could
include one 2nd-level address space and multiple 1st-level address spaces.
While the 2nd-level address space is reasonably sharable by multiple groups
, blindly sharing 1st-level address spaces across all groups within the
container might instead break the guest expectation. In the future sub/
super container concept might be introduced to allow partial address space
sharing within an IOMMU context. But for now let's go with this restriction
by requiring singleton container for using nesting iommu features. Below
link has the related discussion about this decision.

https://lkml.org/lkml/2020/5/15/1028

Cc: Kevin Tian 
CC: Jacob Pan 
Cc: Alex Williamson 
Cc: Eric Auger 
Cc: Jean-Philippe Brucker 
Cc: Joerg Roedel 
Cc: Lu Baolu 
Signed-off-by: Liu Yi L 
---
v4 -> v5:
*) address comments from Eric Auger.
*) return struct iommu_nesting_info for VFIO_IOMMU_TYPE1_INFO_CAP_NESTING as
   cap is much "cheap", if needs extension in future, just define another cap.
   https://lore.kernel.org/kvm/20200708132947.5b7ee...@x1.home/

v3 -> v4:
*) address comments against v3.

v1 -> v2:
*) added in v2
---
 drivers/vfio/vfio_iommu_type1.c | 102 +++-
 include/uapi/linux/vfio.h   |  19 
 2 files changed, 109 insertions(+), 12 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index 3bd70ff..ed80104 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -62,18 +62,20 @@ MODULE_PARM_DESC(dma_entry_limit,
 "Maximum number of user DMA mappings per container (65535).");
 
 struct vfio_iommu {
-   struct list_headdomain_list;
-   struct list_headiova_list;
-   struct vfio_domain  *external_domain; /* domain for external user */
-   struct mutexlock;
-   struct rb_root  dma_list;
-   struct blocking_notifier_head notifier;
-   unsigned intdma_avail;
-   uint64_tpgsize_bitmap;
-   boolv2;
-   boolnesting;
-   booldirty_page_tracking;
-   boolpinned_page_dirty_scope;
+   struct list_headdomain_list;
+   struct list_headiova_list;
+   /* domain for external user */
+   struct vfio_domain  *external_domain;
+   struct mutexlock;
+   struct rb_root  dma_list;
+   struct blocking_notifier_head   notifier;
+   unsigned intdma_avail;
+   uint64_tpgsize_bitmap;
+   boolv2;
+   boolnesting;
+   booldirty_page_tracking;
+   boolpinned_page_dirty_scope;
+   struct iommu_nesting_info   *nesting_info;
 };
 
 struct vfio_domain {
@@ -130,6 +132,9 @@ struct vfio_regions {
 #define IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu)\
(!list_empty(&iommu->domain_list))
 
+#define CONTAINER_HAS_DOMAIN(iommu)(((iommu)->external_domain) || \
+(!list_empty(&(iommu)->domain_list)))
+
 #define DIRTY_BITMAP_BYTES(n)  (ALIGN(n, BITS_PER_TYPE(u64)) / BITS_PER_BYTE)
 
 /*
@@ -1929,6 +1934,13 @@ static void vfio_iommu_iova_insert_copy(struct 
vfio_iommu *iommu,
 
list_splice_tail(iova_copy, iova);
 }
+
+static void vfio_iommu_release_nesting_info(struct vfio_iommu *iommu)
+{
+   kfree(iommu->nesting_info);
+   iommu->nesting_info = NULL;
+}
+
 static int vfio_iommu_type1_attach_group(void *iommu_data,
 struct iommu_group *iommu_group)
 {
@@ -1959,6 +1971,12 @@ static int vfio_iommu_type1_attach_group(void 
*iommu_data,
}
}
 
+   /* Nesting type container can include only one group */
+   if (iommu->nesting && CONTAINER_HAS_DOMAIN(iommu)) {
+   mutex_unlock(&iommu->lock);
+   return -EINVAL;
+   }
+
group = kzalloc(sizeof(*group), GFP_KERNEL);
domain = kzalloc(sizeof(*domain), GFP_KERNEL);
if (!group || !domain) {
@@ -2029,6 +2047,32 @@ static int vfio_iommu_type1_attach_group(void 
*io

[PATCH v5 12/15] vfio/type1: Add vSVA support for IOMMU-backed mdevs

2020-07-12 Thread Liu Yi L
Recent years, mediated device pass-through framework (e.g. vfio-mdev)
is used to achieve flexible device sharing across domains (e.g. VMs).
Also there are hardware assisted mediated pass-through solutions from
platform vendors. e.g. Intel VT-d scalable mode which supports Intel
Scalable I/O Virtualization technology. Such mdevs are called IOMMU-
backed mdevs as there are IOMMU enforced DMA isolation for such mdevs.
In kernel, IOMMU-backed mdevs are exposed to IOMMU layer by aux-domain
concept, which means mdevs are protected by an iommu domain which is
auxiliary to the domain that the kernel driver primarily uses for DMA
API. Details can be found in the KVM presentation as below:

https://events19.linuxfoundation.org/wp-content/uploads/2017/12/\
Hardware-Assisted-Mediated-Pass-Through-with-VFIO-Kevin-Tian-Intel.pdf

This patch extends NESTING_IOMMU ops to IOMMU-backed mdev devices. The
main requirement is to use the auxiliary domain associated with mdev.

Cc: Kevin Tian 
CC: Jacob Pan 
CC: Jun Tian 
Cc: Alex Williamson 
Cc: Eric Auger 
Cc: Jean-Philippe Brucker 
Cc: Joerg Roedel 
Cc: Lu Baolu 
Signed-off-by: Liu Yi L 
---
v1 -> v2:
*) check the iommu_device to ensure the handling mdev is IOMMU-backed
---
 drivers/vfio/vfio_iommu_type1.c | 39 +++
 1 file changed, 35 insertions(+), 4 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index 960cc59..f1f1ae2 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -2373,20 +2373,41 @@ static int vfio_iommu_resv_refresh(struct vfio_iommu 
*iommu,
return ret;
 }
 
+static struct device *vfio_get_iommu_device(struct vfio_group *group,
+   struct device *dev)
+{
+   if (group->mdev_group)
+   return vfio_mdev_get_iommu_device(dev);
+   else
+   return dev;
+}
+
 static int vfio_dev_bind_gpasid_fn(struct device *dev, void *data)
 {
struct domain_capsule *dc = (struct domain_capsule *)data;
unsigned long arg = *(unsigned long *)dc->data;
+   struct device *iommu_device;
+
+   iommu_device = vfio_get_iommu_device(dc->group, dev);
+   if (!iommu_device)
+   return -EINVAL;
 
-   return iommu_sva_bind_gpasid(dc->domain, dev, (void __user *)arg);
+   return iommu_sva_bind_gpasid(dc->domain, iommu_device,
+(void __user *)arg);
 }
 
 static int vfio_dev_unbind_gpasid_fn(struct device *dev, void *data)
 {
struct domain_capsule *dc = (struct domain_capsule *)data;
unsigned long arg = *(unsigned long *)dc->data;
+   struct device *iommu_device;
 
-   iommu_sva_unbind_gpasid(dc->domain, dev, (void __user *)arg);
+   iommu_device = vfio_get_iommu_device(dc->group, dev);
+   if (!iommu_device)
+   return -EINVAL;
+
+   iommu_sva_unbind_gpasid(dc->domain, iommu_device,
+   (void __user *)arg);
return 0;
 }
 
@@ -2395,8 +2416,13 @@ static int __vfio_dev_unbind_gpasid_fn(struct device 
*dev, void *data)
struct domain_capsule *dc = (struct domain_capsule *)data;
struct iommu_gpasid_bind_data *unbind_data =
(struct iommu_gpasid_bind_data *)dc->data;
+   struct device *iommu_device;
+
+   iommu_device = vfio_get_iommu_device(dc->group, dev);
+   if (!iommu_device)
+   return -EINVAL;
 
-   __iommu_sva_unbind_gpasid(dc->domain, dev, unbind_data);
+   __iommu_sva_unbind_gpasid(dc->domain, iommu_device, unbind_data);
return 0;
 }
 
@@ -3077,8 +3103,13 @@ static int vfio_dev_cache_invalidate_fn(struct device 
*dev, void *data)
 {
struct domain_capsule *dc = (struct domain_capsule *)data;
unsigned long arg = *(unsigned long *)dc->data;
+   struct device *iommu_device;
+
+   iommu_device = vfio_get_iommu_device(dc->group, dev);
+   if (!iommu_device)
+   return -EINVAL;
 
-   iommu_cache_invalidate(dc->domain, dev, (void __user *)arg);
+   iommu_cache_invalidate(dc->domain, iommu_device, (void __user *)arg);
return 0;
 }
 
-- 
2.7.4



[PATCH v5 13/15] vfio/pci: Expose PCIe PASID capability to guest

2020-07-12 Thread Liu Yi L
This patch exposes PCIe PASID capability to guest for assigned devices.
Existing vfio_pci driver hides it from guest by setting the capability
length as 0 in pci_ext_cap_length[].

And this patch only exposes PASID capability for devices which has PCIe
PASID extended struture in its configuration space. So VFs, will will
not see PASID capability on VFs as VF doesn't implement PASID extended
structure in its configuration space. For VF, it is a TODO in future.
Related discussion can be found in below link:

https://lkml.org/lkml/2020/4/7/693

Cc: Kevin Tian 
CC: Jacob Pan 
Cc: Alex Williamson 
Cc: Eric Auger 
Cc: Jean-Philippe Brucker 
Cc: Joerg Roedel 
Cc: Lu Baolu 
Signed-off-by: Liu Yi L 
---
v1 -> v2:
*) added in v2, but it was sent in a separate patchseries before
---
 drivers/vfio/pci/vfio_pci_config.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/vfio/pci/vfio_pci_config.c 
b/drivers/vfio/pci/vfio_pci_config.c
index d98843f..07ff2e6 100644
--- a/drivers/vfio/pci/vfio_pci_config.c
+++ b/drivers/vfio/pci/vfio_pci_config.c
@@ -95,7 +95,7 @@ static const u16 pci_ext_cap_length[PCI_EXT_CAP_ID_MAX + 1] = 
{
[PCI_EXT_CAP_ID_LTR]=   PCI_EXT_CAP_LTR_SIZEOF,
[PCI_EXT_CAP_ID_SECPCI] =   0,  /* not yet */
[PCI_EXT_CAP_ID_PMUX]   =   0,  /* not yet */
-   [PCI_EXT_CAP_ID_PASID]  =   0,  /* not yet */
+   [PCI_EXT_CAP_ID_PASID]  =   PCI_EXT_CAP_PASID_SIZEOF,
 };
 
 /*
-- 
2.7.4



[PATCH v5 15/15] iommu/vt-d: Support reporting nesting capability info

2020-07-12 Thread Liu Yi L
Cc: Kevin Tian 
CC: Jacob Pan 
Cc: Alex Williamson 
Cc: Eric Auger 
Cc: Jean-Philippe Brucker 
Cc: Joerg Roedel 
Cc: Lu Baolu 
Signed-off-by: Liu Yi L 
Signed-off-by: Jacob Pan 
---
v2 -> v3:
*) remove cap/ecap_mask in iommu_nesting_info.
---
 drivers/iommu/intel/iommu.c | 81 +++--
 include/linux/intel-iommu.h | 16 +
 2 files changed, 95 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index a9504cb..9f7ad1a 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -5659,12 +5659,16 @@ static inline bool iommu_pasid_support(void)
 static inline bool nested_mode_support(void)
 {
struct dmar_drhd_unit *drhd;
-   struct intel_iommu *iommu;
+   struct intel_iommu *iommu, *prev = NULL;
bool ret = true;
 
rcu_read_lock();
for_each_active_iommu(iommu, drhd) {
-   if (!sm_supported(iommu) || !ecap_nest(iommu->ecap)) {
+   if (!prev)
+   prev = iommu;
+   if (!sm_supported(iommu) || !ecap_nest(iommu->ecap) ||
+   (VTD_CAP_MASK & (iommu->cap ^ prev->cap)) ||
+   (VTD_ECAP_MASK & (iommu->ecap ^ prev->ecap))) {
ret = false;
break;
}
@@ -6079,6 +6083,78 @@ intel_iommu_domain_set_attr(struct iommu_domain *domain,
return ret;
 }
 
+static int intel_iommu_get_nesting_info(struct iommu_domain *domain,
+   struct iommu_nesting_info *info)
+{
+   struct dmar_domain *dmar_domain = to_dmar_domain(domain);
+   u64 cap = VTD_CAP_MASK, ecap = VTD_ECAP_MASK;
+   struct device_domain_info *domain_info;
+   struct iommu_nesting_info_vtd vtd;
+   unsigned long flags;
+   unsigned int size;
+
+   if (domain->type != IOMMU_DOMAIN_UNMANAGED ||
+   !(dmar_domain->flags & DOMAIN_FLAG_NESTING_MODE))
+   return -ENODEV;
+
+   if (!info)
+   return -EINVAL;
+
+   size = sizeof(struct iommu_nesting_info) +
+   sizeof(struct iommu_nesting_info_vtd);
+   /*
+* if provided buffer size is smaller than expected, should
+* return 0 and also the expected buffer size to caller.
+*/
+   if (info->size < size) {
+   info->size = size;
+   return 0;
+   }
+
+   spin_lock_irqsave(&device_domain_lock, flags);
+   /*
+* arbitrary select the first domain_info as all nesting
+* related capabilities should be consistent across iommu
+* units.
+*/
+   domain_info = list_first_entry(&dmar_domain->devices,
+  struct device_domain_info, link);
+   cap &= domain_info->iommu->cap;
+   ecap &= domain_info->iommu->ecap;
+   spin_unlock_irqrestore(&device_domain_lock, flags);
+
+   info->format = IOMMU_PASID_FORMAT_INTEL_VTD;
+   info->features = IOMMU_NESTING_FEAT_SYSWIDE_PASID |
+IOMMU_NESTING_FEAT_BIND_PGTBL |
+IOMMU_NESTING_FEAT_CACHE_INVLD;
+   info->addr_width = dmar_domain->gaw;
+   info->pasid_bits = ilog2(intel_pasid_max_id);
+   info->padding = 0;
+   vtd.flags = 0;
+   vtd.padding = 0;
+   vtd.cap_reg = cap;
+   vtd.ecap_reg = ecap;
+
+   memcpy(info->data, &vtd, sizeof(vtd));
+   return 0;
+}
+
+static int intel_iommu_domain_get_attr(struct iommu_domain *domain,
+  enum iommu_attr attr, void *data)
+{
+   switch (attr) {
+   case DOMAIN_ATTR_NESTING:
+   {
+   struct iommu_nesting_info *info =
+   (struct iommu_nesting_info *)data;
+
+   return intel_iommu_get_nesting_info(domain, info);
+   }
+   default:
+   return -ENODEV;
+   }
+}
+
 /*
  * Check that the device does not live on an external facing PCI port that is
  * marked as untrusted. Such devices should not be able to apply quirks and
@@ -6101,6 +6177,7 @@ const struct iommu_ops intel_iommu_ops = {
.domain_alloc   = intel_iommu_domain_alloc,
.domain_free= intel_iommu_domain_free,
.domain_set_attr= intel_iommu_domain_set_attr,
+   .domain_get_attr= intel_iommu_domain_get_attr,
.attach_dev = intel_iommu_attach_device,
.detach_dev = intel_iommu_detach_device,
.aux_attach_dev = intel_iommu_aux_attach_device,
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index 18f292e..c4ed0d4 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -197,6 +197,22 @@
 #define ecap_max_handle_mask(e) ((e >> 20) & 0xf)
 #define ecap_sc_support(e) ((e >> 7) & 0x1) /* Snooping Control */
 
+/* Nesting Support Capability Alignment */
+#define VTD_CAP_FL1GP  BI

[PATCH v5 01/15] vfio/type1: Refactor vfio_iommu_type1_ioctl()

2020-07-12 Thread Liu Yi L
This patch refactors the vfio_iommu_type1_ioctl() to use switch instead of
if-else, and each command got a helper function.

Cc: Kevin Tian 
CC: Jacob Pan 
Cc: Alex Williamson 
Cc: Eric Auger 
Cc: Jean-Philippe Brucker 
Cc: Joerg Roedel 
Cc: Lu Baolu 
Reviewed-by: Eric Auger 
Suggested-by: Christoph Hellwig 
Signed-off-by: Liu Yi L 
---
v4 -> v5:
*) address comments from Eric Auger, add r-b from Eric.
---
 drivers/vfio/vfio_iommu_type1.c | 394 ++--
 1 file changed, 213 insertions(+), 181 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index 5e556ac..3bd70ff 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -2453,6 +2453,23 @@ static int vfio_domains_have_iommu_cache(struct 
vfio_iommu *iommu)
return ret;
 }
 
+static int vfio_iommu_type1_check_extension(struct vfio_iommu *iommu,
+   unsigned long arg)
+{
+   switch (arg) {
+   case VFIO_TYPE1_IOMMU:
+   case VFIO_TYPE1v2_IOMMU:
+   case VFIO_TYPE1_NESTING_IOMMU:
+   return 1;
+   case VFIO_DMA_CC_IOMMU:
+   if (!iommu)
+   return 0;
+   return vfio_domains_have_iommu_cache(iommu);
+   default:
+   return 0;
+   }
+}
+
 static int vfio_iommu_iova_add_cap(struct vfio_info_cap *caps,
 struct vfio_iommu_type1_info_cap_iova_range *cap_iovas,
 size_t size)
@@ -2529,241 +2546,256 @@ static int vfio_iommu_migration_build_caps(struct 
vfio_iommu *iommu,
return vfio_info_add_capability(caps, &cap_mig.header, sizeof(cap_mig));
 }
 
-static long vfio_iommu_type1_ioctl(void *iommu_data,
-  unsigned int cmd, unsigned long arg)
+static int vfio_iommu_type1_get_info(struct vfio_iommu *iommu,
+unsigned long arg)
 {
-   struct vfio_iommu *iommu = iommu_data;
+   struct vfio_iommu_type1_info info;
unsigned long minsz;
+   struct vfio_info_cap caps = { .buf = NULL, .size = 0 };
+   unsigned long capsz;
+   int ret;
 
-   if (cmd == VFIO_CHECK_EXTENSION) {
-   switch (arg) {
-   case VFIO_TYPE1_IOMMU:
-   case VFIO_TYPE1v2_IOMMU:
-   case VFIO_TYPE1_NESTING_IOMMU:
-   return 1;
-   case VFIO_DMA_CC_IOMMU:
-   if (!iommu)
-   return 0;
-   return vfio_domains_have_iommu_cache(iommu);
-   default:
-   return 0;
-   }
-   } else if (cmd == VFIO_IOMMU_GET_INFO) {
-   struct vfio_iommu_type1_info info;
-   struct vfio_info_cap caps = { .buf = NULL, .size = 0 };
-   unsigned long capsz;
-   int ret;
-
-   minsz = offsetofend(struct vfio_iommu_type1_info, iova_pgsizes);
+   minsz = offsetofend(struct vfio_iommu_type1_info, iova_pgsizes);
 
-   /* For backward compatibility, cannot require this */
-   capsz = offsetofend(struct vfio_iommu_type1_info, cap_offset);
+   /* For backward compatibility, cannot require this */
+   capsz = offsetofend(struct vfio_iommu_type1_info, cap_offset);
 
-   if (copy_from_user(&info, (void __user *)arg, minsz))
-   return -EFAULT;
+   if (copy_from_user(&info, (void __user *)arg, minsz))
+   return -EFAULT;
 
-   if (info.argsz < minsz)
-   return -EINVAL;
+   if (info.argsz < minsz)
+   return -EINVAL;
 
-   if (info.argsz >= capsz) {
-   minsz = capsz;
-   info.cap_offset = 0; /* output, no-recopy necessary */
-   }
+   if (info.argsz >= capsz) {
+   minsz = capsz;
+   info.cap_offset = 0; /* output, no-recopy necessary */
+   }
 
-   mutex_lock(&iommu->lock);
-   info.flags = VFIO_IOMMU_INFO_PGSIZES;
+   mutex_lock(&iommu->lock);
+   info.flags = VFIO_IOMMU_INFO_PGSIZES;
 
-   info.iova_pgsizes = iommu->pgsize_bitmap;
+   info.iova_pgsizes = iommu->pgsize_bitmap;
 
-   ret = vfio_iommu_migration_build_caps(iommu, &caps);
+   ret = vfio_iommu_migration_build_caps(iommu, &caps);
 
-   if (!ret)
-   ret = vfio_iommu_iova_build_caps(iommu, &caps);
+   if (!ret)
+   ret = vfio_iommu_iova_build_caps(iommu, &caps);
 
-   mutex_unlock(&iommu->lock);
+   mutex_unlock(&iommu->lock);
 
-   if (ret)
-   return ret;
+   if (ret)
+   return ret;
 
-   if (caps.size) {
-   info.flags |= VFIO_IOMMU_INFO_CAPS;
+   if (caps.size) {
+   info.flags |= VFIO_IOMMU_INFO_CAPS;
 
-

[PATCH v5 11/15] vfio/type1: Allow invalidating first-level/stage IOMMU cache

2020-07-12 Thread Liu Yi L
This patch provides an interface allowing the userspace to invalidate
IOMMU cache for first-level page table. It is required when the first
level IOMMU page table is not managed by the host kernel in the nested
translation setup.

Cc: Kevin Tian 
CC: Jacob Pan 
Cc: Alex Williamson 
Cc: Eric Auger 
Cc: Jean-Philippe Brucker 
Cc: Joerg Roedel 
Cc: Lu Baolu 
Signed-off-by: Liu Yi L 
Signed-off-by: Eric Auger 
Signed-off-by: Jacob Pan 
---
v1 -> v2:
*) rename from "vfio/type1: Flush stage-1 IOMMU cache for nesting type"
*) rename vfio_cache_inv_fn() to vfio_dev_cache_invalidate_fn()
*) vfio_dev_cache_inv_fn() always successful
*) remove VFIO_IOMMU_CACHE_INVALIDATE, and reuse VFIO_IOMMU_NESTING_OP
---
 drivers/vfio/vfio_iommu_type1.c | 50 +
 include/uapi/linux/vfio.h   |  3 +++
 2 files changed, 53 insertions(+)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index f0f21ff..960cc59 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -3073,6 +3073,53 @@ static long vfio_iommu_handle_pgtbl_op(struct vfio_iommu 
*iommu,
return ret;
 }
 
+static int vfio_dev_cache_invalidate_fn(struct device *dev, void *data)
+{
+   struct domain_capsule *dc = (struct domain_capsule *)data;
+   unsigned long arg = *(unsigned long *)dc->data;
+
+   iommu_cache_invalidate(dc->domain, dev, (void __user *)arg);
+   return 0;
+}
+
+static long vfio_iommu_invalidate_cache(struct vfio_iommu *iommu,
+   unsigned long arg)
+{
+   struct domain_capsule dc = { .data = &arg };
+   struct vfio_group *group;
+   struct vfio_domain *domain;
+   int ret = 0;
+   struct iommu_nesting_info *info;
+
+   mutex_lock(&iommu->lock);
+   /*
+* Cache invalidation is required for any nesting IOMMU,
+* so no need to check system-wide PASID support.
+*/
+   info = iommu->nesting_info;
+   if (!info || !(info->features & IOMMU_NESTING_FEAT_CACHE_INVLD)) {
+   ret = -EOPNOTSUPP;
+   goto out_unlock;
+   }
+
+   group = vfio_find_nesting_group(iommu);
+   if (!group) {
+   ret = -EINVAL;
+   goto out_unlock;
+   }
+
+   domain = list_first_entry(&iommu->domain_list,
+ struct vfio_domain, next);
+   dc.group = group;
+   dc.domain = domain->domain;
+   iommu_group_for_each_dev(group->iommu_group, &dc,
+vfio_dev_cache_invalidate_fn);
+
+out_unlock:
+   mutex_unlock(&iommu->lock);
+   return ret;
+}
+
 static long vfio_iommu_type1_nesting_op(struct vfio_iommu *iommu,
unsigned long arg)
 {
@@ -3095,6 +3142,9 @@ static long vfio_iommu_type1_nesting_op(struct vfio_iommu 
*iommu,
case VFIO_IOMMU_NESTING_OP_UNBIND_PGTBL:
ret = vfio_iommu_handle_pgtbl_op(iommu, false, arg + minsz);
break;
+   case VFIO_IOMMU_NESTING_OP_CACHE_INVLD:
+   ret = vfio_iommu_invalidate_cache(iommu, arg + minsz);
+   break;
default:
ret = -EINVAL;
}
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index a8ad786..845a5800 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -1225,6 +1225,8 @@ struct vfio_iommu_type1_pasid_request {
  * +-+---+
  * | UNBIND_PGTBL|  struct iommu_gpasid_bind_data|
  * +-+---+
+ * | CACHE_INVLD |  struct iommu_cache_invalidate_info   |
+ * +-+---+
  *
  * returns: 0 on success, -errno on failure.
  */
@@ -1237,6 +1239,7 @@ struct vfio_iommu_type1_nesting_op {
 
 #define VFIO_IOMMU_NESTING_OP_BIND_PGTBL   (0)
 #define VFIO_IOMMU_NESTING_OP_UNBIND_PGTBL (1)
+#define VFIO_IOMMU_NESTING_OP_CACHE_INVLD  (2)
 
 #define VFIO_IOMMU_NESTING_OP  _IO(VFIO_TYPE, VFIO_BASE + 19)
 
-- 
2.7.4



[PATCH v5 07/15] vfio/type1: Add VFIO_IOMMU_PASID_REQUEST (alloc/free)

2020-07-12 Thread Liu Yi L
This patch allows user space to request PASID allocation/free, e.g. when
serving the request from the guest.

PASIDs that are not freed by userspace are automatically freed when the
IOASID set is destroyed when process exits.

Cc: Kevin Tian 
CC: Jacob Pan 
Cc: Alex Williamson 
Cc: Eric Auger 
Cc: Jean-Philippe Brucker 
Cc: Joerg Roedel 
Cc: Lu Baolu 
Signed-off-by: Liu Yi L 
Signed-off-by: Yi Sun 
Signed-off-by: Jacob Pan 
---
v4 -> v5:
*) address comments from Eric Auger.
*) the comments for the PASID_FREE request is addressed in patch 5/15 of
   this series.

v3 -> v4:
*) address comments from v3, except the below comment against the range
   of PASID_FREE request. needs more help on it.
"> +if (req.range.min > req.range.max)

Is it exploitable that a user can spin the kernel for a long time in
the case of a free by calling this with [0, MAX_UINT] regardless of
their actual allocations?"
https://lore.kernel.org/linux-iommu/20200702151832.048b4...@x1.home/

v1 -> v2:
*) move the vfio_mm related code to be a seprate module
*) use a single structure for alloc/free, could support a range of PASIDs
*) fetch vfio_mm at group_attach time instead of at iommu driver open time
---
 drivers/vfio/Kconfig|  1 +
 drivers/vfio/vfio_iommu_type1.c | 85 +
 drivers/vfio/vfio_pasid.c   | 10 +
 include/linux/vfio.h|  6 +++
 include/uapi/linux/vfio.h   | 37 ++
 5 files changed, 139 insertions(+)

diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig
index 3d8a108..95d90c6 100644
--- a/drivers/vfio/Kconfig
+++ b/drivers/vfio/Kconfig
@@ -2,6 +2,7 @@
 config VFIO_IOMMU_TYPE1
tristate
depends on VFIO
+   select VFIO_PASID if (X86)
default n
 
 config VFIO_IOMMU_SPAPR_TCE
diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index ed80104..55b4065 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -76,6 +76,7 @@ struct vfio_iommu {
booldirty_page_tracking;
boolpinned_page_dirty_scope;
struct iommu_nesting_info   *nesting_info;
+   struct vfio_mm  *vmm;
 };
 
 struct vfio_domain {
@@ -1937,6 +1938,11 @@ static void vfio_iommu_iova_insert_copy(struct 
vfio_iommu *iommu,
 
 static void vfio_iommu_release_nesting_info(struct vfio_iommu *iommu)
 {
+   if (iommu->vmm) {
+   vfio_mm_put(iommu->vmm);
+   iommu->vmm = NULL;
+   }
+
kfree(iommu->nesting_info);
iommu->nesting_info = NULL;
 }
@@ -2071,6 +2077,26 @@ static int vfio_iommu_type1_attach_group(void 
*iommu_data,
iommu->nesting_info);
if (ret)
goto out_detach;
+
+   if (iommu->nesting_info->features &
+   IOMMU_NESTING_FEAT_SYSWIDE_PASID) {
+   struct vfio_mm *vmm;
+   int sid;
+
+   vmm = vfio_mm_get_from_task(current);
+   if (IS_ERR(vmm)) {
+   ret = PTR_ERR(vmm);
+   goto out_detach;
+   }
+   iommu->vmm = vmm;
+
+   sid = vfio_mm_ioasid_sid(vmm);
+   ret = iommu_domain_set_attr(domain->domain,
+   DOMAIN_ATTR_IOASID_SID,
+   &sid);
+   if (ret)
+   goto out_detach;
+   }
}
 
/* Get aperture info */
@@ -2855,6 +2881,63 @@ static int vfio_iommu_type1_dirty_pages(struct 
vfio_iommu *iommu,
return -EINVAL;
 }
 
+static int vfio_iommu_type1_pasid_alloc(struct vfio_iommu *iommu,
+   unsigned int min,
+   unsigned int max)
+{
+   int ret = -EOPNOTSUPP;
+
+   mutex_lock(&iommu->lock);
+   if (iommu->vmm)
+   ret = vfio_pasid_alloc(iommu->vmm, min, max);
+   mutex_unlock(&iommu->lock);
+   return ret;
+}
+
+static int vfio_iommu_type1_pasid_free(struct vfio_iommu *iommu,
+  unsigned int min,
+  unsigned int max)
+{
+   int ret = -EOPNOTSUPP;
+
+   mutex_lock(&iommu->lock);
+   if (iommu->vmm) {
+   vfio_pasid_free_range(iommu->vmm, min, max);
+   ret = 0;
+   }
+   mutex_unlock(&iommu->lock);
+   return ret;
+}
+
+static int vfio_iommu_type1_pasid_request(struct vfio_iommu *iommu,
+ unsigned long arg)
+{
+   struct vfio_iommu_type1_pasid_request req;
+   unsigned long minsz;
+
+   minsz = offsetofend(struct vfio_iommu_type1_pasid_request, range);
+

[PATCH v5 03/15] iommu/smmu: Report empty domain nesting info

2020-07-12 Thread Liu Yi L
This patch is added as instead of returning a boolean for DOMAIN_ATTR_NESTING,
iommu_domain_get_attr() should return an iommu_nesting_info handle.

Cc: Will Deacon 
Cc: Robin Murphy 
Cc: Eric Auger 
Cc: Jean-Philippe Brucker 
Suggested-by: Jean-Philippe Brucker 
Signed-off-by: Liu Yi L 
Signed-off-by: Jacob Pan 
---
v4 -> v5:
*) address comments from Eric Auger.
---
 drivers/iommu/arm-smmu-v3.c | 29 +++--
 drivers/iommu/arm-smmu.c| 29 +++--
 2 files changed, 54 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index f578677..ec815d7 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -3019,6 +3019,32 @@ static struct iommu_group *arm_smmu_device_group(struct 
device *dev)
return group;
 }
 
+static int arm_smmu_domain_nesting_info(struct arm_smmu_domain *smmu_domain,
+   void *data)
+{
+   struct iommu_nesting_info *info = (struct iommu_nesting_info *)data;
+   unsigned int size;
+
+   if (!info || smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED)
+   return -ENODEV;
+
+   size = sizeof(struct iommu_nesting_info);
+
+   /*
+* if provided buffer size is smaller than expected, should
+* return 0 and also the expected buffer size to caller.
+*/
+   if (info->size < size) {
+   info->size = size;
+   return 0;
+   }
+
+   /* report an empty iommu_nesting_info for now */
+   memset(info, 0x0, size);
+   info->size = size;
+   return 0;
+}
+
 static int arm_smmu_domain_get_attr(struct iommu_domain *domain,
enum iommu_attr attr, void *data)
 {
@@ -3028,8 +3054,7 @@ static int arm_smmu_domain_get_attr(struct iommu_domain 
*domain,
case IOMMU_DOMAIN_UNMANAGED:
switch (attr) {
case DOMAIN_ATTR_NESTING:
-   *(int *)data = (smmu_domain->stage == 
ARM_SMMU_DOMAIN_NESTED);
-   return 0;
+   return arm_smmu_domain_nesting_info(smmu_domain, data);
default:
return -ENODEV;
}
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 243bc4c..09e2f1b 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1506,6 +1506,32 @@ static struct iommu_group *arm_smmu_device_group(struct 
device *dev)
return group;
 }
 
+static int arm_smmu_domain_nesting_info(struct arm_smmu_domain *smmu_domain,
+   void *data)
+{
+   struct iommu_nesting_info *info = (struct iommu_nesting_info *)data;
+   unsigned int size;
+
+   if (!info || smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED)
+   return -ENODEV;
+
+   size = sizeof(struct iommu_nesting_info);
+
+   /*
+* if provided buffer size is smaller than expected, should
+* return 0 and also the expected buffer size to caller.
+*/
+   if (info->size < size) {
+   info->size = size;
+   return 0;
+   }
+
+   /* report an empty iommu_nesting_info for now */
+   memset(info, 0x0, size);
+   info->size = size;
+   return 0;
+}
+
 static int arm_smmu_domain_get_attr(struct iommu_domain *domain,
enum iommu_attr attr, void *data)
 {
@@ -1515,8 +1541,7 @@ static int arm_smmu_domain_get_attr(struct iommu_domain 
*domain,
case IOMMU_DOMAIN_UNMANAGED:
switch (attr) {
case DOMAIN_ATTR_NESTING:
-   *(int *)data = (smmu_domain->stage == 
ARM_SMMU_DOMAIN_NESTED);
-   return 0;
+   return arm_smmu_domain_nesting_info(smmu_domain, data);
default:
return -ENODEV;
}
-- 
2.7.4



[PATCH v5 06/15] iommu/vt-d: Support setting ioasid set to domain

2020-07-12 Thread Liu Yi L
>From IOMMU p.o.v., PASIDs allocated and managed by external components
(e.g. VFIO) will be passed in for gpasid_bind/unbind operation. IOMMU
needs some knowledge to check the PASID ownership, hence add an interface
for those components to tell the PASID owner.

In latest kernel design, PASID ownership is managed by IOASID set where
the PASID is allocated from. This patch adds support for setting ioasid
set ID to the domains used for nesting/vSVA. Subsequent SVA operations
on the PASID will be checked against its IOASID set for proper ownership.

Cc: Kevin Tian 
CC: Jacob Pan 
Cc: Alex Williamson 
Cc: Eric Auger 
Cc: Jean-Philippe Brucker 
Cc: Joerg Roedel 
Cc: Lu Baolu 
Signed-off-by: Liu Yi L 
Signed-off-by: Jacob Pan 
---
v4 -> v5:
*) address comments from Eric Auger.
---
 drivers/iommu/intel/iommu.c | 22 ++
 include/linux/intel-iommu.h |  4 
 include/linux/iommu.h   |  1 +
 3 files changed, 27 insertions(+)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 72ae6a2..4d54198 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -1793,6 +1793,7 @@ static struct dmar_domain *alloc_domain(int flags)
if (first_level_by_default())
domain->flags |= DOMAIN_FLAG_USE_FIRST_LEVEL;
domain->has_iotlb_device = false;
+   domain->ioasid_sid = INVALID_IOASID_SET;
INIT_LIST_HEAD(&domain->devices);
 
return domain;
@@ -6039,6 +6040,27 @@ intel_iommu_domain_set_attr(struct iommu_domain *domain,
}
spin_unlock_irqrestore(&device_domain_lock, flags);
break;
+   case DOMAIN_ATTR_IOASID_SID:
+   {
+   int sid = *(int *)data;
+
+   if (!(dmar_domain->flags & DOMAIN_FLAG_NESTING_MODE)) {
+   ret = -ENODEV;
+   break;
+   }
+   spin_lock_irqsave(&device_domain_lock, flags);
+   if (dmar_domain->ioasid_sid != INVALID_IOASID_SET &&
+   dmar_domain->ioasid_sid != sid) {
+   pr_warn_ratelimited("multi ioasid_set (%d:%d) setting",
+   dmar_domain->ioasid_sid, sid);
+   ret = -EBUSY;
+   spin_unlock_irqrestore(&device_domain_lock, flags);
+   break;
+   }
+   dmar_domain->ioasid_sid = sid;
+   spin_unlock_irqrestore(&device_domain_lock, flags);
+   break;
+   }
default:
ret = -EINVAL;
break;
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index 3f23c26..0d0ab32 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -549,6 +549,10 @@ struct dmar_domain {
   2 == 1GiB, 3 == 512GiB, 4 == 1TiB */
u64 max_addr;   /* maximum mapped address */
 
+   int ioasid_sid; /*
+* the ioasid set which tracks all
+* PASIDs used by the domain.
+*/
int default_pasid;  /*
 * The default pasid used for non-SVM
 * traffic on mediated devices.
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 7ca9d48..e84a1d5 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -124,6 +124,7 @@ enum iommu_attr {
DOMAIN_ATTR_FSL_PAMUV1,
DOMAIN_ATTR_NESTING,/* two stages of translation */
DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE,
+   DOMAIN_ATTR_IOASID_SID,
DOMAIN_ATTR_MAX,
 };
 
-- 
2.7.4



[PATCH v5 09/15] iommu/vt-d: Check ownership for PASIDs from user-space

2020-07-12 Thread Liu Yi L
When an IOMMU domain with nesting attribute is used for guest SVA, a
system-wide PASID is allocated for binding with the device and the domain.
For security reason, we need to check the PASID passsed from user-space.
e.g. page table bind/unbind and PASID related cache invalidation.

Cc: Kevin Tian 
CC: Jacob Pan 
Cc: Alex Williamson 
Cc: Eric Auger 
Cc: Jean-Philippe Brucker 
Cc: Joerg Roedel 
Cc: Lu Baolu 
Signed-off-by: Liu Yi L 
Signed-off-by: Jacob Pan 
---
 drivers/iommu/intel/iommu.c | 10 ++
 drivers/iommu/intel/svm.c   |  7 +--
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 4d54198..a9504cb 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -5436,6 +5436,7 @@ intel_iommu_sva_invalidate(struct iommu_domain *domain, 
struct device *dev,
int granu = 0;
u64 pasid = 0;
u64 addr = 0;
+   void *pdata;
 
granu = to_vtd_granularity(cache_type, inv_info->granularity);
if (granu == -EINVAL) {
@@ -5456,6 +5457,15 @@ intel_iommu_sva_invalidate(struct iommu_domain *domain, 
struct device *dev,
 (inv_info->granu.addr_info.flags & 
IOMMU_INV_ADDR_FLAGS_PASID))
pasid = inv_info->granu.addr_info.pasid;
 
+   pdata = ioasid_find(dmar_domain->ioasid_sid, pasid, NULL);
+   if (!pdata) {
+   ret = -EINVAL;
+   goto out_unlock;
+   } else if (IS_ERR(pdata)) {
+   ret = PTR_ERR(pdata);
+   goto out_unlock;
+   }
+
switch (BIT(cache_type)) {
case IOMMU_CACHE_INV_TYPE_IOTLB:
/* HW will ignore LSB bits based on address mask */
diff --git a/drivers/iommu/intel/svm.c b/drivers/iommu/intel/svm.c
index d2c0e1a..212dee0 100644
--- a/drivers/iommu/intel/svm.c
+++ b/drivers/iommu/intel/svm.c
@@ -319,7 +319,7 @@ int intel_svm_bind_gpasid(struct iommu_domain *domain, 
struct device *dev,
dmar_domain = to_dmar_domain(domain);
 
mutex_lock(&pasid_mutex);
-   svm = ioasid_find(INVALID_IOASID_SET, data->hpasid, NULL);
+   svm = ioasid_find(dmar_domain->ioasid_sid, data->hpasid, NULL);
if (IS_ERR(svm)) {
ret = PTR_ERR(svm);
goto out;
@@ -436,6 +436,7 @@ int intel_svm_unbind_gpasid(struct iommu_domain *domain,
struct device *dev, ioasid_t pasid)
 {
struct intel_iommu *iommu = intel_svm_device_to_iommu(dev);
+   struct dmar_domain *dmar_domain;
struct intel_svm_dev *sdev;
struct intel_svm *svm;
int ret = -EINVAL;
@@ -443,8 +444,10 @@ int intel_svm_unbind_gpasid(struct iommu_domain *domain,
if (WARN_ON(!iommu))
return -EINVAL;
 
+   dmar_domain = to_dmar_domain(domain);
+
mutex_lock(&pasid_mutex);
-   svm = ioasid_find(INVALID_IOASID_SET, pasid, NULL);
+   svm = ioasid_find(dmar_domain->ioasid_sid, pasid, NULL);
if (!svm) {
ret = -EINVAL;
goto out;
-- 
2.7.4



[PATCH v5 02/15] iommu: Report domain nesting info

2020-07-12 Thread Liu Yi L
IOMMUs that support nesting translation needs report the capability info
to userspace, e.g. the format of first level/stage paging structures.

This patch reports nesting info by DOMAIN_ATTR_NESTING. Caller can get
nesting info after setting DOMAIN_ATTR_NESTING.

Cc: Kevin Tian 
CC: Jacob Pan 
Cc: Alex Williamson 
Cc: Eric Auger 
Cc: Jean-Philippe Brucker 
Cc: Joerg Roedel 
Cc: Lu Baolu 
Signed-off-by: Liu Yi L 
Signed-off-by: Jacob Pan 
---
v4 -> v5:
*) address comments from Eric Auger.

v3 -> v4:
*) split the SMMU driver changes to be a separate patch
*) move the @addr_width and @pasid_bits from vendor specific
   part to generic part.
*) tweak the description for the @features field of struct
   iommu_nesting_info.
*) add description on the @data[] field of struct iommu_nesting_info

v2 -> v3:
*) remvoe cap/ecap_mask in iommu_nesting_info.
*) reuse DOMAIN_ATTR_NESTING to get nesting info.
*) return an empty iommu_nesting_info for SMMU drivers per Jean'
   suggestion.
---
 include/uapi/linux/iommu.h | 77 ++
 1 file changed, 77 insertions(+)

diff --git a/include/uapi/linux/iommu.h b/include/uapi/linux/iommu.h
index 1afc661..d2a47c4 100644
--- a/include/uapi/linux/iommu.h
+++ b/include/uapi/linux/iommu.h
@@ -332,4 +332,81 @@ struct iommu_gpasid_bind_data {
} vendor;
 };
 
+/*
+ * struct iommu_nesting_info - Information for nesting-capable IOMMU.
+ *user space should check it before using
+ *nesting capability.
+ *
+ * @size:  size of the whole structure
+ * @format:PASID table entry format, the same definition as struct
+ * iommu_gpasid_bind_data @format.
+ * @features:  supported nesting features.
+ * @flags: currently reserved for future extension.
+ * @addr_width:The output addr width of first level/stage translation
+ * @pasid_bits:Maximum supported PASID bits, 0 represents no PASID
+ * support.
+ * @data:  vendor specific cap info. data[] structure type can be deduced
+ * from @format field.
+ *
+ * +===+==+
+ * | feature   |  Notes   |
+ * +===+==+
+ * | SYSWIDE_PASID |  PASIDs are managed in system-wide, instead of per   |
+ * |   |  device. When a device is assigned to userspace or   |
+ * |   |  VM, proper uAPI (userspace driver framework uAPI,   |
+ * |   |  e.g. VFIO) must be used to allocate/free PASIDs for |
+ * |   |  the assigned device.|
+ * +---+--+
+ * | BIND_PGTBL|  The owner of the first level/stage page table must  |
+ * |   |  explicitly bind the page table to associated PASID  |
+ * |   |  (either the one specified in bind request or the|
+ * |   |  default PASID of iommu domain), through userspace   |
+ * |   |  driver framework uAPI (e.g. VFIO_IOMMU_NESTING_OP). |
+ * +---+--+
+ * | CACHE_INVLD   |  The owner of the first level/stage page table must  |
+ * |   |  explicitly invalidate the IOMMU cache through uAPI  |
+ * |   |  provided by userspace driver framework (e.g. VFIO)  |
+ * |   |  according to vendor-specific requirement when   |
+ * |   |  changing the page table.|
+ * +---+--+
+ *
+ * @data[] types defined for @format:
+ * ++=+
+ * | @format| @data[] |
+ * ++=+
+ * | IOMMU_PASID_FORMAT_INTEL_VTD   | struct iommu_nesting_info_vtd   |
+ * ++-+
+ *
+ */
+struct iommu_nesting_info {
+   __u32   size;
+   __u32   format;
+#define IOMMU_NESTING_FEAT_SYSWIDE_PASID   (1 << 0)
+#define IOMMU_NESTING_FEAT_BIND_PGTBL  (1 << 1)
+#define IOMMU_NESTING_FEAT_CACHE_INVLD (1 << 2)
+   __u32   features;
+   __u32   flags;
+   __u16   addr_width;
+   __u16   pasid_bits;
+   __u32   padding;
+   __u8data[];
+};
+
+/*
+ * struct iommu_nesting_info_vtd - Intel VT-d specific nesting info
+ *
+ * @flags: VT-d specific flags. Currently reserved for future
+ * extension.
+ * @cap_reg:   Describe basic capabilities as defined in VT-d capability
+ * register.
+ * @ecap_reg:  Describe the extended capabilities as defined in VT-d
+ * extended capability register.
+ */
+struct iommu_nesting_info_vtd {
+  

Re: [PATCH 1/3] iio: dac: ad5592r: fix unbalanced mutex unlocks in ad5592r_read_raw()

2020-07-12 Thread Jonathan Cameron
On Mon, 6 Jul 2020 16:36:09 +
"Ardelean, Alexandru"  wrote:

> On Mon, 2020-07-06 at 14:02 +0300, Alexandru Ardelean wrote:
> > [External]
> > 
> > There are 2 exit paths where the lock isn't held, but try to unlock the
> > mutex when exiting. In these places we should just return from the
> > function.
> > 
> > A neater approach would be to cleanup the ad5592r_read_raw(), but that
> > would make this patch more difficult to backport to stable versions.
> >   
> 
> I was a bit too hasty with this.
> Apologies.
> I'd like to add a tag here.
> 
> Reported-by: Charles Stanhope 
Applied to the fixes-togreg branch of iio.git.

I'll have to wait for this to trickle through to the togreg branch though
before I can do anything with the next two patches.  As ever, if I've
clearly lost them give me a poke!

Jonathan

> 
> > Fixes 56ca9db862bf3: ("iio: dac: Add support for the AD5592R/AD5593R
> > ADCs/DACs")
> > Signed-off-by: Alexandru Ardelean 
> > ---
> >  drivers/iio/dac/ad5592r-base.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/iio/dac/ad5592r-base.c b/drivers/iio/dac/ad5592r-
> > base.c
> > index 5c4e5ff70380..cc4875660a69 100644
> > --- a/drivers/iio/dac/ad5592r-base.c
> > +++ b/drivers/iio/dac/ad5592r-base.c
> > @@ -413,7 +413,7 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev,
> > s64 tmp = *val * (3767897513LL / 25LL);
> > *val = div_s64_rem(tmp, 10LL, val2);
> >  
> > -   ret = IIO_VAL_INT_PLUS_MICRO;
> > +   return IIO_VAL_INT_PLUS_MICRO;
> > } else {
> > int mult;
> >  
> > @@ -444,7 +444,7 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev,
> > ret =  IIO_VAL_INT;
> > break;
> > default:
> > -   ret = -EINVAL;
> > +   return -EINVAL;
> > }
> >  
> >  unlock:  



Re: [PATCH v8 1/6] dt-bindings: iio/adc: Convert ingenic-adc docs to YAML.

2020-07-12 Thread Jonathan Cameron
On Thu,  9 Jul 2020 17:21:55 +0200
Artur Rojek  wrote:

> Convert the textual documentation of Device Tree bindings for the
> Ingenic JZ47xx SoCs ADC controller to YAML.
> 
> The `interrupts` property is now explicitly listed and marked as
> required. While missing from the previous textual documentation, this
> property has been used with all the boards which probe this driver.
> 
> Signed-off-by: Artur Rojek 
> Tested-by: Paul Cercueil 
> Reviewed-by: Rob Herring 

Given this is a good change on it's own. I'll apply it before even
reading the rest of the series.  If we do need to go to a v9 at least
it'll be shorter ;) 

Applied to the togreg branch of iio.git and pushed out as testing
for the autobuilders to poke at it.

Thanks,

Jonathan

> ---
> 
>  Changes:
> 
>  v6: new patch
> 
>  v7: - specify `maxItems: 1` for single entry properties
>  - get rid of redundant descriptions of said properties
> 
>  v8: no change
> 
>  .../bindings/iio/adc/ingenic,adc.txt  | 49 -
>  .../bindings/iio/adc/ingenic,adc.yaml | 71 +++
>  2 files changed, 71 insertions(+), 49 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/iio/adc/ingenic,adc.txt
>  create mode 100644 Documentation/devicetree/bindings/iio/adc/ingenic,adc.yaml
> 
> diff --git a/Documentation/devicetree/bindings/iio/adc/ingenic,adc.txt 
> b/Documentation/devicetree/bindings/iio/adc/ingenic,adc.txt
> deleted file mode 100644
> index cd9048cf9dcf..
> --- a/Documentation/devicetree/bindings/iio/adc/ingenic,adc.txt
> +++ /dev/null
> @@ -1,49 +0,0 @@
> -* Ingenic JZ47xx ADC controller IIO bindings
> -
> -Required properties:
> -
> -- compatible: Should be one of:
> -  * ingenic,jz4725b-adc
> -  * ingenic,jz4740-adc
> -  * ingenic,jz4770-adc
> -- reg: ADC controller registers location and length.
> -- clocks: phandle to the SoC's ADC clock.
> -- clock-names: Must be set to "adc".
> -- #io-channel-cells: Must be set to <1> to indicate channels are selected
> -  by index.
> -
> -ADC clients must use the format described in iio-bindings.txt, giving
> -a phandle and IIO specifier pair ("io-channels") to the ADC controller.
> -
> -Example:
> -
> -#include 
> -
> -adc: adc@1007 {
> - compatible = "ingenic,jz4740-adc";
> - #io-channel-cells = <1>;
> -
> - reg = <0x1007 0x30>;
> -
> - clocks = <&cgu JZ4740_CLK_ADC>;
> - clock-names = "adc";
> -
> - interrupt-parent = <&intc>;
> - interrupts = <18>;
> -};
> -
> -adc-keys {
> - ...
> - compatible = "adc-keys";
> - io-channels = <&adc INGENIC_ADC_AUX>;
> - io-channel-names = "buttons";
> - ...
> -};
> -
> -battery {
> - ...
> - compatible = "ingenic,jz4740-battery";
> - io-channels = <&adc INGENIC_ADC_BATTERY>;
> - io-channel-names = "battery";
> - ...
> -};
> diff --git a/Documentation/devicetree/bindings/iio/adc/ingenic,adc.yaml 
> b/Documentation/devicetree/bindings/iio/adc/ingenic,adc.yaml
> new file mode 100644
> index ..9f414dbdae86
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/adc/ingenic,adc.yaml
> @@ -0,0 +1,71 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +# Copyright 2019-2020 Artur Rojek
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/iio/adc/ingenic,adc.yaml#";
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#";
> +
> +title: Ingenic JZ47xx ADC controller IIO bindings
> +
> +maintainers:
> +  - Artur Rojek 
> +
> +description: >
> +  Industrial I/O subsystem bindings for ADC controller found in
> +  Ingenic JZ47xx SoCs.
> +
> +  ADC clients must use the format described in iio-bindings.txt, giving
> +  a phandle and IIO specifier pair ("io-channels") to the ADC controller.
> +
> +properties:
> +  compatible:
> +enum:
> +  - ingenic,jz4725b-adc
> +  - ingenic,jz4740-adc
> +  - ingenic,jz4770-adc
> +
> +  '#io-channel-cells':
> +const: 1
> +description:
> +  Must be set to <1> to indicate channels are selected by index.
> +
> +  reg:
> +maxItems: 1
> +
> +  clocks:
> +maxItems: 1
> +
> +  clock-names:
> +items:
> +  - const: adc
> +
> +  interrupts:
> +maxItems: 1
> +
> +required:
> +  - compatible
> +  - '#io-channel-cells'
> +  - reg
> +  - clocks
> +  - clock-names
> +  - interrupts
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +#include 
> +#include 
> +
> +adc@1007 {
> +compatible = "ingenic,jz4740-adc";
> +#io-channel-cells = <1>;
> +
> +reg = <0x1007 0x30>;
> +
> +clocks = <&cgu JZ4740_CLK_ADC>;
> +clock-names = "adc";
> +
> +interrupt-parent = <&intc>;
> +interrupts = <18>;
> +};



Re: [PATCH] sh: Replace HTTP links with HTTPS ones

2020-07-12 Thread Rob Landley
On 7/12/20 6:11 AM, Alexander A. Klimov wrote:
> Rationale:
> Reduces attack surface on kernel devs opening the links for MITM
> as HTTPS traffic is much harder to manipulate.

Trimmed just to the one site without the self-signed certficate: check.

> Deterministic algorithm:
> For each file:
>   If not .svg:
> For each line:
>   If doesn't contain `\bxmlns\b`:
> For each link, `\bhttp://[^# \t\r\n]*(?:\w|/)`:
> If neither `\bgnu\.org/license`, nor `\bmozilla\.org/MPL\b`:
> If both the HTTP and HTTPS versions
> return 200 OK and serve the same content:
>   Replace HTTP with HTTPS.
> 
> Signed-off-by: Alexander A. Klimov 

Acked-by: Rob Landley 

Rob


Re: kvm crash on 5.7-rc1 and later

2020-07-12 Thread Woody Suwalski

Xiaoyao Li wrote:

On 7/12/2020 2:21 AM, Peter Zijlstra wrote:

On Fri, Jul 03, 2020 at 11:15:31AM -0400, Woody Suwalski wrote:

I am observing a 100% reproducible kvm crash on kernels starting with
5.7-rc1, always with the same opcode .
It happens during wake up from the host suspended state. Worked OK 
on 5.6

and older.
The host is based on Debian testing, Thinkpad T440, i5 cpu.

[   61.576664] kernel BUG at arch/x86/kvm/x86.c:387!
[   61.576672] invalid opcode:  [#1] PREEMPT SMP NOPTI
[   61.576678] CPU: 0 PID: 3851 Comm: qemu-system-x86 Not tainted 
5.7-pingu

#0
[   61.576680] Hardware name: LENOVO 20B6005JUS/20B6005JUS, BIOS 
GJETA4WW

(2.54 ) 03/27/2020
[   61.576700] RIP: 0010:kvm_spurious_fault+0xa/0x10 [kvm]

Crash results in a dead kvm and occasionally a very unstable system.

Bisecting the problem between v5.6 and v5.7-rc1 points to

commit 6650cdd9a8ccf00555dbbe743d58541ad8feb6a7
Author: Peter Zijlstra (Intel) 
Date:   Sun Jan 26 12:05:35 2020 -0800

 x86/split_lock: Enable split lock detection by kernel

Reversing that patch seems to actually "cure" the issue.

The problem is present in all kernels past 5.7-rc1, however the 
patch is not
reversing directly in later source trees, so can not retest the 
logic on

recent kernels.

Peter, would you have idea how to debug that (or even better - would 
you

happen to know the fix)?

I have attached dmesg logs from a "good" 5.6.9 kernel, and then 
"bad" 5.7.0

and 5.8-rc3


I have no clue about kvm. Nor do I actually have hardware with SLD on.
I've Cc'ed a bunch of folks who might have more ideas.



I think this bug is the same as the one found by Sean, and is already 
fixed in 5.8-rc4.


https://lore.kernel.org/kvm/20200605192605.7439-1-sean.j.christopher...@intel.com/ 



You are right, kvm works OK on 5.8-rc4.
The fix will need to be backported to 5.7.

Thanks, Woody



Re: [PATCH v8 2/6] IIO: Ingenic JZ47xx: Error check clk_enable calls.

2020-07-12 Thread Jonathan Cameron
On Thu,  9 Jul 2020 17:21:56 +0200
Artur Rojek  wrote:

> Introduce error checks for the clk_enable calls used in this driver.
> As part of the changes, move clk_enable/clk_disable calls out of
> ingenic_adc_set_config and into respective logic of its callers.
> 
> Signed-off-by: Artur Rojek 
> Tested-by: Paul Cercueil 
Applied.

Thanks,

Jonathan

> ---
> 
>  Changes:
> 
>  v6: new patch
> 
>  v7: no change
> 
>  v8: move `clk_disable` outside the lock
> 
>  drivers/iio/adc/ingenic-adc.c | 25 +
>  1 file changed, 21 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/iio/adc/ingenic-adc.c b/drivers/iio/adc/ingenic-adc.c
> index 39c0a609fc94..c1946a9f1cca 100644
> --- a/drivers/iio/adc/ingenic-adc.c
> +++ b/drivers/iio/adc/ingenic-adc.c
> @@ -73,7 +73,6 @@ static void ingenic_adc_set_config(struct ingenic_adc *adc,
>  {
>   uint32_t cfg;
>  
> - clk_enable(adc->clk);
>   mutex_lock(&adc->lock);
>  
>   cfg = readl(adc->base + JZ_ADC_REG_CFG) & ~mask;
> @@ -81,7 +80,6 @@ static void ingenic_adc_set_config(struct ingenic_adc *adc,
>   writel(cfg, adc->base + JZ_ADC_REG_CFG);
>  
>   mutex_unlock(&adc->lock);
> - clk_disable(adc->clk);
>  }
>  
>  static void ingenic_adc_enable(struct ingenic_adc *adc,
> @@ -124,6 +122,8 @@ static int ingenic_adc_write_raw(struct iio_dev *iio_dev,
>long m)
>  {
>   struct ingenic_adc *adc = iio_priv(iio_dev);
> + struct device *dev = iio_dev->dev.parent;
> + int ret;
>  
>   switch (m) {
>   case IIO_CHAN_INFO_SCALE:
> @@ -131,6 +131,14 @@ static int ingenic_adc_write_raw(struct iio_dev *iio_dev,
>   case INGENIC_ADC_BATTERY:
>   if (!adc->soc_data->battery_vref_mode)
>   return -EINVAL;
> +
> + ret = clk_enable(adc->clk);
> + if (ret) {
> + dev_err(dev, "Failed to enable clock: %d\n",
> + ret);
> + return ret;
> + }
> +
>   if (val > JZ_ADC_BATTERY_LOW_VREF) {
>   ingenic_adc_set_config(adc,
>  JZ_ADC_REG_CFG_BAT_MD,
> @@ -142,6 +150,9 @@ static int ingenic_adc_write_raw(struct iio_dev *iio_dev,
>  JZ_ADC_REG_CFG_BAT_MD);
>   adc->low_vref_mode = true;
>   }
> +
> + clk_disable(adc->clk);
> +
>   return 0;
>   default:
>   return -EINVAL;
> @@ -317,6 +328,13 @@ static int ingenic_adc_read_chan_info_raw(struct 
> ingenic_adc *adc,
> int *val)
>  {
>   int bit, ret, engine = (chan->channel == INGENIC_ADC_BATTERY);
> + struct device *dev = iio_priv_to_dev(adc)->dev.parent;
> +
> + ret = clk_enable(adc->clk);
> + if (ret) {
> + dev_err(dev, "Failed to enable clock: %d\n", ret);
> + return ret;
> + }
>  
>   /* We cannot sample AUX/AUX2 in parallel. */
>   mutex_lock(&adc->aux_lock);
> @@ -325,7 +343,6 @@ static int ingenic_adc_read_chan_info_raw(struct 
> ingenic_adc *adc,
>   ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_AUX_MD, bit);
>   }
>  
> - clk_enable(adc->clk);
>   ret = ingenic_adc_capture(adc, engine);
>   if (ret)
>   goto out;
> @@ -342,8 +359,8 @@ static int ingenic_adc_read_chan_info_raw(struct 
> ingenic_adc *adc,
>  
>   ret = IIO_VAL_INT;
>  out:
> - clk_disable(adc->clk);
>   mutex_unlock(&adc->aux_lock);
> + clk_disable(adc->clk);
>  
>   return ret;
>  }



Re: [PATCH v2 2/2] arm64: tlb: Use the TLBI RANGE feature in arm64

2020-07-12 Thread Catalin Marinas
On Sat, Jul 11, 2020 at 02:50:46PM +0800, Zhenyu Ye wrote:
> On 2020/7/11 2:31, Catalin Marinas wrote:
> > On Fri, Jul 10, 2020 at 05:44:20PM +0800, Zhenyu Ye wrote:
> >> -  if ((end - start) >= (MAX_TLBI_OPS * stride)) {
> >> +  if ((!cpus_have_const_cap(ARM64_HAS_TLBI_RANGE) &&
> >> +  (end - start) >= (MAX_TLBI_OPS * stride)) ||
> >> +  pages >= MAX_TLBI_RANGE_PAGES) {
> >>flush_tlb_mm(vma->vm_mm);
> >>return;
> >>}
> > 
> > I think we can use strictly greater here rather than greater or equal.
> > MAX_TLBI_RANGE_PAGES can be encoded as num 31, scale 3.
> 
> Sorry, we can't.
> For a boundary value (such as 2^6), we have two way to express it
> in TLBI RANGE operations:
> 1. scale = 0, num = 31.
> 2. scale = 1, num = 0.
> 
> I used the second way in following implementation.  However, for the
> MAX_TLBI_RANGE_PAGES, we can only use scale = 3, num = 31.
> So if use strictly greater here, ERROR will happen when range pages
> equal to MAX_TLBI_RANGE_PAGES.

You are right, I got confused by the __TLBI_RANGE_NUM() macro which
doesn't return the actual 'num' for the TLBI argument as it would go
from 0 to 31. After subtracting 1, num end sup from -1 to 30, so we
never get the maximum range. I think for scale 3 and num 31, this would
be 8GB with 4K pages, so the maximum we'd cover 8GB - 64K * 4K.

> There are two ways to avoid this bug:
> 1. Just keep 'greater or equal' here.  The ARM64 specification does
> not specify how we flush tlb entries in this case, flush_tlb_mm()
> is also a good choice for such a wide range of pages.

I'll go for this option, I don't think it would make much difference in
practice if we stop at 8GB - 256M range.

> 2. Add check in the loop, just like: (this may cause the codes a bit ugly)
> 
>   num = __TLBI_RANGE_NUM(pages, scale) - 1;
> 
>   /* scale = 4, num = 0 is equal to scale = 3, num = 31. */
>   if (scale == 4 && num == 0) {
>   scale = 3;
>   num = 31;
>   }
> 
>   if (num >= 0) {
>   ...
> 
> Which one do you prefer and how do you want to fix this error? Just
> a fix patch again?

I'll fold the diff below and refresh the patch:

diff --git a/arch/arm64/include/asm/tlbflush.h 
b/arch/arm64/include/asm/tlbflush.h
index 1eb0588718fb..0300e433ffe6 100644
--- a/arch/arm64/include/asm/tlbflush.h
+++ b/arch/arm64/include/asm/tlbflush.h
@@ -147,9 +147,13 @@ static inline unsigned long get_trans_granule(void)
 #define __TLBI_RANGE_PAGES(num, scale) (((num) + 1) << (5 * (scale) + 1))
 #define MAX_TLBI_RANGE_PAGES   __TLBI_RANGE_PAGES(31, 3)
 
+/*
+ * Generate 'num' values from -1 to 30 with -1 rejected by the
+ * __flush_tlb_range() loop below.
+ */
 #define TLBI_RANGE_MASKGENMASK_ULL(4, 0)
 #define __TLBI_RANGE_NUM(range, scale) \
-   (((range) >> (5 * (scale) + 1)) & TLBI_RANGE_MASK)
+   range) >> (5 * (scale) + 1)) & TLBI_RANGE_MASK) - 1)
 
 /*
  * TLB Invalidation
@@ -285,8 +289,8 @@ static inline void __flush_tlb_range(struct vm_area_struct 
*vma,
pages = (end - start) >> PAGE_SHIFT;
 
if ((!cpus_have_const_cap(ARM64_HAS_TLB_RANGE) &&
-(end - start) > (MAX_TLBI_OPS * stride)) ||
-   pages > MAX_TLBI_RANGE_PAGES) {
+(end - start) >= (MAX_TLBI_OPS * stride)) ||
+   pages >= MAX_TLBI_RANGE_PAGES) {
flush_tlb_mm(vma->vm_mm);
return;
}
@@ -306,6 +310,10 @@ static inline void __flush_tlb_range(struct vm_area_struct 
*vma,
 *Start from scale = 0, flush the corresponding number of pages
 *((num+1)*2^(5*scale+1) starting from 'addr'), then increase it
 *until no pages left.
+*
+* Note that certain ranges can be represented by either num = 31 and
+* scale or num = 0 and scale + 1. The loop below favours the latter
+* since num is limited to 30 by the __TLBI_RANGE_NUM() macro.
 */
while (pages > 0) {
if (!cpus_have_const_cap(ARM64_HAS_TLB_RANGE) ||
@@ -323,7 +331,7 @@ static inline void __flush_tlb_range(struct vm_area_struct 
*vma,
continue;
}
 
-   num = __TLBI_RANGE_NUM(pages, scale) - 1;
+   num = __TLBI_RANGE_NUM(pages, scale);
if (num >= 0) {
addr = __TLBI_VADDR_RANGE(start, asid, scale,
  num, tlb_level);

> >> -  /* Convert the stride into units of 4k */
> >> -  stride >>= 12;
> >> +  dsb(ishst);
> >>  
> >> -  start = __TLBI_VADDR(start, asid);
> >> -  end = __TLBI_VADDR(end, asid);
> >> +  /*
> >> +   * When cpu does not support TLBI RANGE feature, we flush the tlb
> >> +   * entries one by one at the granularity of 'stride'.
> >> +   * When cpu supports the TLBI RANGE feature, then:
> >> +   * 1. If pages is odd, flush the first page through non-RANGE
> >> +   *instruction;
> >> +   * 2. For remaining pag

Re: [PATCH v8 3/6] IIO: Ingenic JZ47xx: Add xlate cb to retrieve correct channel idx

2020-07-12 Thread Jonathan Cameron
On Thu,  9 Jul 2020 17:21:57 +0200
Artur Rojek  wrote:

> Provide an of_xlate callback in order to retrieve the correct channel
> specifier index from the IIO channels array.
> 
> Signed-off-by: Artur Rojek 
> Tested-by: Paul Cercueil 
Applied.  Thanks,

Jonathan

> ---
> 
>  Changes:
> 
>  v2-v8: no change
> 
>  drivers/iio/adc/ingenic-adc.c | 16 
>  1 file changed, 16 insertions(+)
> 
> diff --git a/drivers/iio/adc/ingenic-adc.c b/drivers/iio/adc/ingenic-adc.c
> index c1946a9f1cca..89019fb59d48 100644
> --- a/drivers/iio/adc/ingenic-adc.c
> +++ b/drivers/iio/adc/ingenic-adc.c
> @@ -400,6 +400,21 @@ static int ingenic_adc_read_raw(struct iio_dev *iio_dev,
>   }
>  }
>  
> +static int ingenic_adc_of_xlate(struct iio_dev *iio_dev,
> + const struct of_phandle_args *iiospec)
> +{
> + int i;
> +
> + if (!iiospec->args_count)
> + return -EINVAL;
> +
> + for (i = 0; i < iio_dev->num_channels; ++i)
> + if (iio_dev->channels[i].channel == iiospec->args[0])
> + return i;
> +
> + return -EINVAL;
> +}
> +
>  static void ingenic_adc_clk_cleanup(void *data)
>  {
>   clk_unprepare(data);
> @@ -409,6 +424,7 @@ static const struct iio_info ingenic_adc_info = {
>   .write_raw = ingenic_adc_write_raw,
>   .read_raw = ingenic_adc_read_raw,
>   .read_avail = ingenic_adc_read_avail,
> + .of_xlate = ingenic_adc_of_xlate,
>  };
>  
>  static const struct iio_chan_spec ingenic_channels[] = {



Re: [PATCH v8 4/6] iio/adc: ingenic: Retrieve channels list from soc data struct

2020-07-12 Thread Jonathan Cameron
On Thu,  9 Jul 2020 17:21:58 +0200
Artur Rojek  wrote:

> From: Paul Cercueil 
> 
> Instead of having one array of struct iio_chan_spec for all SoCs, and
> have some SoCs remove the last item of the array as they can't use it,
> have each SoC define its array of supported channels.
> 
> Signed-off-by: Paul Cercueil 
> Tested-by: Artur Rojek 
Applied to the togreg branch of iio.git and pushed out as testing for
autobuilders to play with it.

Thanks,

Jonathan

> ---
> 
>  Changes:
> 
>  v8: new patch
> 
>  drivers/iio/adc/ingenic-adc.c | 99 +++
>  1 file changed, 65 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/iio/adc/ingenic-adc.c b/drivers/iio/adc/ingenic-adc.c
> index 89019fb59d48..0233a9055c86 100644
> --- a/drivers/iio/adc/ingenic-adc.c
> +++ b/drivers/iio/adc/ingenic-adc.c
> @@ -55,6 +55,8 @@ struct ingenic_adc_soc_data {
>   size_t battery_scale_avail_size;
>   unsigned int battery_vref_mode: 1;
>   unsigned int has_aux2: 1;
> + const struct iio_chan_spec *channels;
> + unsigned int num_channels;
>   int (*init_clk_div)(struct device *dev, struct ingenic_adc *adc);
>  };
>  
> @@ -262,6 +264,61 @@ static int jz4770_adc_init_clk_div(struct device *dev, 
> struct ingenic_adc *adc)
>   return 0;
>  }
>  
> +static const struct iio_chan_spec jz4740_channels[] = {
> + {
> + .extend_name = "aux",
> + .type = IIO_VOLTAGE,
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> +   BIT(IIO_CHAN_INFO_SCALE),
> + .indexed = 1,
> + .channel = INGENIC_ADC_AUX,
> + .scan_index = -1,
> + },
> + {
> + .extend_name = "battery",
> + .type = IIO_VOLTAGE,
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> +   BIT(IIO_CHAN_INFO_SCALE),
> + .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW) |
> + BIT(IIO_CHAN_INFO_SCALE),
> + .indexed = 1,
> + .channel = INGENIC_ADC_BATTERY,
> + .scan_index = -1,
> + },
> +};
> +
> +static const struct iio_chan_spec jz4770_channels[] = {
> + {
> + .extend_name = "aux",
> + .type = IIO_VOLTAGE,
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> +   BIT(IIO_CHAN_INFO_SCALE),
> + .indexed = 1,
> + .channel = INGENIC_ADC_AUX,
> + .scan_index = -1,
> + },
> + {
> + .extend_name = "battery",
> + .type = IIO_VOLTAGE,
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> +   BIT(IIO_CHAN_INFO_SCALE),
> + .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW) |
> + BIT(IIO_CHAN_INFO_SCALE),
> + .indexed = 1,
> + .channel = INGENIC_ADC_BATTERY,
> + .scan_index = -1,
> + },
> + {
> + .extend_name = "aux2",
> + .type = IIO_VOLTAGE,
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> +   BIT(IIO_CHAN_INFO_SCALE),
> + .indexed = 1,
> + .channel = INGENIC_ADC_AUX2,
> + .scan_index = -1,
> + },
> +};
> +
>  static const struct ingenic_adc_soc_data jz4725b_adc_soc_data = {
>   .battery_high_vref = JZ4725B_ADC_BATTERY_HIGH_VREF,
>   .battery_high_vref_bits = JZ4725B_ADC_BATTERY_HIGH_VREF_BITS,
> @@ -271,6 +328,8 @@ static const struct ingenic_adc_soc_data 
> jz4725b_adc_soc_data = {
>   .battery_scale_avail_size = ARRAY_SIZE(jz4725b_adc_battery_scale_avail),
>   .battery_vref_mode = true,
>   .has_aux2 = false,
> + .channels = jz4740_channels,
> + .num_channels = ARRAY_SIZE(jz4740_channels),
>   .init_clk_div = jz4725b_adc_init_clk_div,
>  };
>  
> @@ -283,6 +342,8 @@ static const struct ingenic_adc_soc_data 
> jz4740_adc_soc_data = {
>   .battery_scale_avail_size = ARRAY_SIZE(jz4740_adc_battery_scale_avail),
>   .battery_vref_mode = true,
>   .has_aux2 = false,
> + .channels = jz4740_channels,
> + .num_channels = ARRAY_SIZE(jz4740_channels),
>   .init_clk_div = NULL, /* no ADCLK register on JZ4740 */
>  };
>  
> @@ -295,6 +356,8 @@ static const struct ingenic_adc_soc_data 
> jz4770_adc_soc_data = {
>   .battery_scale_avail_size = ARRAY_SIZE(jz4770_adc_battery_scale_avail),
>   .battery_vref_mode = false,
>   .has_aux2 = true,
> + .channels = jz4770_channels,
> + .num_channels = ARRAY_SIZE(jz4770_channels),
>   .init_clk_div = jz4770_adc_init_clk_div,
>  };
>  
> @@ -427,35 +490,6 @@ static const struct iio_info ingenic_adc_info = {
>   .of_xlate = ingenic_adc_of_xlate,
>  };
>  
> -static const struct iio_chan_spec ingenic_channels[] = {
> - {
> - .extend_name = "aux",
> 

Re: [PATCH v8 4/6] iio/adc: ingenic: Retrieve channels list from soc data struct

2020-07-12 Thread Jonathan Cameron
On Sun, 12 Jul 2020 13:07:13 +0100
Jonathan Cameron  wrote:

> On Thu,  9 Jul 2020 17:21:58 +0200
> Artur Rojek  wrote:
> 
> > From: Paul Cercueil 
> > 
> > Instead of having one array of struct iio_chan_spec for all SoCs, and
> > have some SoCs remove the last item of the array as they can't use it,
> > have each SoC define its array of supported channels.
> > 
> > Signed-off-by: Paul Cercueil 
> > Tested-by: Artur Rojek   
> Applied to the togreg branch of iio.git and pushed out as testing for
> autobuilders to play with it.
Actually removed from tree again.

Artur, as you sent this patch on to me, you need to sign-off on it
so we maintain the DCO related records of how this got to the kernel.
You can just reply here to give it.

Thanks,

Jonathan

> 
> Thanks,
> 
> Jonathan
> 
> > ---
> > 
> >  Changes:
> > 
> >  v8: new patch
> > 
> >  drivers/iio/adc/ingenic-adc.c | 99 +++
> >  1 file changed, 65 insertions(+), 34 deletions(-)
> > 
> > diff --git a/drivers/iio/adc/ingenic-adc.c b/drivers/iio/adc/ingenic-adc.c
> > index 89019fb59d48..0233a9055c86 100644
> > --- a/drivers/iio/adc/ingenic-adc.c
> > +++ b/drivers/iio/adc/ingenic-adc.c
> > @@ -55,6 +55,8 @@ struct ingenic_adc_soc_data {
> > size_t battery_scale_avail_size;
> > unsigned int battery_vref_mode: 1;
> > unsigned int has_aux2: 1;
> > +   const struct iio_chan_spec *channels;
> > +   unsigned int num_channels;
> > int (*init_clk_div)(struct device *dev, struct ingenic_adc *adc);
> >  };
> >  
> > @@ -262,6 +264,61 @@ static int jz4770_adc_init_clk_div(struct device *dev, 
> > struct ingenic_adc *adc)
> > return 0;
> >  }
> >  
> > +static const struct iio_chan_spec jz4740_channels[] = {
> > +   {
> > +   .extend_name = "aux",
> > +   .type = IIO_VOLTAGE,
> > +   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> > + BIT(IIO_CHAN_INFO_SCALE),
> > +   .indexed = 1,
> > +   .channel = INGENIC_ADC_AUX,
> > +   .scan_index = -1,
> > +   },
> > +   {
> > +   .extend_name = "battery",
> > +   .type = IIO_VOLTAGE,
> > +   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> > + BIT(IIO_CHAN_INFO_SCALE),
> > +   .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW) |
> > +   BIT(IIO_CHAN_INFO_SCALE),
> > +   .indexed = 1,
> > +   .channel = INGENIC_ADC_BATTERY,
> > +   .scan_index = -1,
> > +   },
> > +};
> > +
> > +static const struct iio_chan_spec jz4770_channels[] = {
> > +   {
> > +   .extend_name = "aux",
> > +   .type = IIO_VOLTAGE,
> > +   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> > + BIT(IIO_CHAN_INFO_SCALE),
> > +   .indexed = 1,
> > +   .channel = INGENIC_ADC_AUX,
> > +   .scan_index = -1,
> > +   },
> > +   {
> > +   .extend_name = "battery",
> > +   .type = IIO_VOLTAGE,
> > +   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> > + BIT(IIO_CHAN_INFO_SCALE),
> > +   .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW) |
> > +   BIT(IIO_CHAN_INFO_SCALE),
> > +   .indexed = 1,
> > +   .channel = INGENIC_ADC_BATTERY,
> > +   .scan_index = -1,
> > +   },
> > +   {
> > +   .extend_name = "aux2",
> > +   .type = IIO_VOLTAGE,
> > +   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> > + BIT(IIO_CHAN_INFO_SCALE),
> > +   .indexed = 1,
> > +   .channel = INGENIC_ADC_AUX2,
> > +   .scan_index = -1,
> > +   },
> > +};
> > +
> >  static const struct ingenic_adc_soc_data jz4725b_adc_soc_data = {
> > .battery_high_vref = JZ4725B_ADC_BATTERY_HIGH_VREF,
> > .battery_high_vref_bits = JZ4725B_ADC_BATTERY_HIGH_VREF_BITS,
> > @@ -271,6 +328,8 @@ static const struct ingenic_adc_soc_data 
> > jz4725b_adc_soc_data = {
> > .battery_scale_avail_size = ARRAY_SIZE(jz4725b_adc_battery_scale_avail),
> > .battery_vref_mode = true,
> > .has_aux2 = false,
> > +   .channels = jz4740_channels,
> > +   .num_channels = ARRAY_SIZE(jz4740_channels),
> > .init_clk_div = jz4725b_adc_init_clk_div,
> >  };
> >  
> > @@ -283,6 +342,8 @@ static const struct ingenic_adc_soc_data 
> > jz4740_adc_soc_data = {
> > .battery_scale_avail_size = ARRAY_SIZE(jz4740_adc_battery_scale_avail),
> > .battery_vref_mode = true,
> > .has_aux2 = false,
> > +   .channels = jz4740_channels,
> > +   .num_channels = ARRAY_SIZE(jz4740_channels),
> > .init_clk_div = NULL, /* no ADCLK register on JZ4740 */
> >  };
> >  
> > @@ -295,6 +356,8 @@ static const struct ingenic_adc_soc_data 
> > jz4770_adc_soc_data = {
> > .battery_scale_avail_size = ARRAY_SIZE(jz4770_adc_battery_scale_avail),
> > .battery_vref_mode = false,
> > .

SDX - breaks a vain cycle.

2020-07-12 Thread Ywe Cærlyn
An interesting observation I want to share with interested, is a problem 
in democratic politics where politics end up in a vain cycle due to the 
peoples interests but lack of knowledge.


Brexit seems to be such a thing, where supposedly people want to return 
to a nations values, that is monarchic, that again in Englands case is 
Bal, that again is the Bibles God, again Tor turned cider, and Jesus 
water to wine scenarios.


In old mesopotamia it is a similar scenario called The Bal Cycle, where 
kings cycle according to the definitions of their gods.


If we rather focus on a supply and demand principles, which is 
monotheistic, we break this cycle.


And then we also gain the adamic background on fair pay.

Serenity,
Ywe Cærlyn.

Den 11.07.2020 17:30, skrev Ywe Cærlyn:
I discussed earlier also the monotheistic angle on this, and I think the 
easiest route is considering what latin alphabet supports, and using the 
four letter definite form, The Ilah here.


Since Islam is an intelligent religion, and the ban on Amanita is the 
beginning of civilized principles, and the root of written fair pay 
principles, I think this is very good for computing space.


Serenity,
Ywe Cærlyn.
https://www.youtube.com/channel/UCR3gmLVjHS5A702wo4bol_Q

Den 08.07.2020 13:48, skrev Ywe Cærlyn:
A complete correction of the unix name actually becomes SDX, supply 
and demand OS.


So this is now what it is called, with all things discussed included.

Supply and Demand being a monotheistic principle that decides what 
happens on the OS, like indeed school teaches.




[PATCH] staging: r8188eu: remove unused members of struct xmit_buf

2020-07-12 Thread Ivan Safonov
Remove unused members of struct xmit_buf: alloc_sz, ff_hwaddr,
dma_transfer_addr, bpending and last.

Signed-off-by: Ivan Safonov 
---
 drivers/staging/rtl8188eu/include/rtw_xmit.h  | 5 -
 drivers/staging/rtl8188eu/os_dep/xmit_linux.c | 1 -
 2 files changed, 6 deletions(-)

diff --git a/drivers/staging/rtl8188eu/include/rtw_xmit.h 
b/drivers/staging/rtl8188eu/include/rtw_xmit.h
index 12d16e98176a..3c03987c81a1 100644
--- a/drivers/staging/rtl8188eu/include/rtw_xmit.h
+++ b/drivers/staging/rtl8188eu/include/rtw_xmit.h
@@ -193,14 +193,9 @@ struct xmit_buf {
void *priv_data;
u16 ext_tag; /*  0: Normal xmitbuf, 1: extension xmitbuf. */
u16 flags;
-   u32 alloc_sz;
u32  len;
struct submit_ctx *sctx;
-   u32 ff_hwaddr;
struct urb *pxmit_urb[8];
-   dma_addr_t dma_transfer_addr;   /* (in) dma addr for transfer_buffer */
-   u8 bpending[8];
-   int last[8];
 };
 
 struct xmit_frame {
diff --git a/drivers/staging/rtl8188eu/os_dep/xmit_linux.c 
b/drivers/staging/rtl8188eu/os_dep/xmit_linux.c
index 017e1d628461..61ced1160951 100644
--- a/drivers/staging/rtl8188eu/os_dep/xmit_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/xmit_linux.c
@@ -24,7 +24,6 @@ int rtw_os_xmit_resource_alloc(struct adapter *padapter,
return _FAIL;
 
pxmitbuf->pbuf = PTR_ALIGN(pxmitbuf->pallocated_buf, XMITBUF_ALIGN_SZ);
-   pxmitbuf->dma_transfer_addr = 0;
 
for (i = 0; i < 8; i++) {
pxmitbuf->pxmit_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
-- 
2.26.2



Re: Linux kernel in-tree Rust support

2020-07-12 Thread Adrian Bunk
On Thu, Jul 09, 2020 at 11:41:47AM -0700, Nick Desaulniers wrote:
>...
> but also a larger question of "should we do
> this?" or "how might we place limits on where this can be used?"
>...

I won't attend, but I do have a topic that should be covered:

Firefox always depends on recent Rust, which forces distributions to 
update Rust in stable releases.

As an example:
Ubuntu LTS releases upgrade to a new Rust version every 1-2 months.
Ubuntu 16.04 started with Rust 1.7.0 and is now at Rust 1.41.0.

It would not sound good to me if security updates of distribution
kernels might additionally end up using a different version of the
Rust compiler - the toolchain for the kernel should be stable.

Would Rust usage in the kernel require distributions to ship
a "Rust for Firefox" and a "Rust for the kernel"?

> Thanks,
> ~Nick Desaulniers

cu
Adrian


[PATCH] decompress_bunzip2: fix sizeof type in start_bunzip

2020-07-12 Thread trix
From: Tom Rix 

clang static analysis flags this error

lib/decompress_bunzip2.c:671:13: warning: Result of 'malloc' is converted
  to a pointer of type 'unsigned int', which is incompatible with sizeof
  operand type 'int' [unix.MallocSizeof]
bd->dbuf = large_malloc(bd->dbufSize * sizeof(int));
   ^~~~

Reviewing the bunzip_data structure, the element dbuf is type

/* Intermediate buffer and its size (in bytes) */
unsigned int *dbuf, dbufSize;

So change the type in sizeof to 'unsigned int'

Fixes: bc22c17e12c1 ("bzip2/lzma: library support for gzip, bzip2 and lzma 
decompression")

Signed-off-by: Tom Rix 
---
 lib/decompress_bunzip2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/decompress_bunzip2.c b/lib/decompress_bunzip2.c
index 7c4932eed748..59ab76bda7a7 100644
--- a/lib/decompress_bunzip2.c
+++ b/lib/decompress_bunzip2.c
@@ -668,7 +668,7 @@ static int INIT start_bunzip(struct bunzip_data **bdp, void 
*inbuf, long len,
   uncompressed data.  Allocate intermediate buffer for block. */
bd->dbufSize = 10*(i-BZh0);
 
-   bd->dbuf = large_malloc(bd->dbufSize * sizeof(int));
+   bd->dbuf = large_malloc(bd->dbufSize * sizeof(unsigned int));
if (!bd->dbuf)
return RETVAL_OUT_OF_MEMORY;
return RETVAL_OK;
-- 
2.18.1



Re: [PATCH] decompress_bunzip2: fix sizeof type in start_bunzip

2020-07-12 Thread H. Peter Anvin
On 2020-07-12 05:59, t...@redhat.com wrote:
> From: Tom Rix 
> 
> clang static analysis flags this error
> 
> lib/decompress_bunzip2.c:671:13: warning: Result of 'malloc' is converted
>   to a pointer of type 'unsigned int', which is incompatible with sizeof
>   operand type 'int' [unix.MallocSizeof]
> bd->dbuf = large_malloc(bd->dbufSize * sizeof(int));
>^~~~
> 
> Reviewing the bunzip_data structure, the element dbuf is type
> 
>   /* Intermediate buffer and its size (in bytes) */
>   unsigned int *dbuf, dbufSize;
> 
> So change the type in sizeof to 'unsigned int'
> 

You must be kidding.

If you want to change it, change it to sizeof(bd->dbuf) instead, but this flag
is at least in my opinion a total joke. For sizeof(int) != sizeof(unsigned
int) is beyond bizarre, no matter how stupid the platform.

-hpa



[PATCH 2/2] kvm: mmu: page_track: Fix RCU list API usage

2020-07-12 Thread madhuparnabhowmik10
From: Madhuparna Bhowmik 

Use hlist_for_each_entry_srcu() instead of hlist_for_each_entry_rcu()
as it also checkes if the right lock is held.
Using hlist_for_each_entry_rcu() with a condition argument will not
report the cases where a SRCU protected list is traversed using
rcu_read_lock(). Hence, use hlist_for_each_entry_srcu().

Signed-off-by: Madhuparna Bhowmik 
---
 arch/x86/kvm/mmu/page_track.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/mmu/page_track.c b/arch/x86/kvm/mmu/page_track.c
index a7bcde34d1f2..a9cd17625950 100644
--- a/arch/x86/kvm/mmu/page_track.c
+++ b/arch/x86/kvm/mmu/page_track.c
@@ -229,7 +229,8 @@ void kvm_page_track_write(struct kvm_vcpu *vcpu, gpa_t gpa, 
const u8 *new,
return;
 
idx = srcu_read_lock(&head->track_srcu);
-   hlist_for_each_entry_rcu(n, &head->track_notifier_list, node)
+   hlist_for_each_entry_srcu(n, &head->track_notifier_list, node,
+   srcu_read_lock_held(&head->track_srcu))
if (n->track_write)
n->track_write(vcpu, gpa, new, bytes, n);
srcu_read_unlock(&head->track_srcu, idx);
@@ -254,7 +255,8 @@ void kvm_page_track_flush_slot(struct kvm *kvm, struct 
kvm_memory_slot *slot)
return;
 
idx = srcu_read_lock(&head->track_srcu);
-   hlist_for_each_entry_rcu(n, &head->track_notifier_list, node)
+   hlist_for_each_entry_srcu(n, &head->track_notifier_list, node,
+   srcu_read_lock_held(&head->track_srcu))
if (n->track_flush_slot)
n->track_flush_slot(kvm, slot, n);
srcu_read_unlock(&head->track_srcu, idx);
-- 
2.17.1



[PATCH 1/2] rculist : Introduce list/hlist_for_each_entry_srcu() macros

2020-07-12 Thread madhuparnabhowmik10
From: Madhuparna Bhowmik 

list/hlist_for_each_entry_rcu() provides an optional cond argument
to specify the lock held in the updater side.
However for SRCU read side, not providing the cond argument results
into false positive as whether srcu_read_lock is held or not is not
checked implicitly. Therefore, on read side the lockdep expression
srcu_read_lock_held(srcu struct) can solve this issue.

However, the function still fails to check the cases where srcu
protected list is traversed with rcu_read_lock() instead of
srcu_read_lock(). Therefore, to remove the false negative,
this patch introduces two new list traversal primitives :
list_for_each_entry_srcu() and hlist_for_each_entry_srcu().

Both of the functions have non-optional cond argument
as it is required for both read and update side, and simply checks
if the cond is true. For regular read side the lockdep expression
srcu_read_lock_head() can be passed as the cond argument to
list/hlist_for_each_entry_srcu().

Suggested-by: Paolo Bonzini 
Signed-off-by: Madhuparna Bhowmik 
---
 include/linux/rculist.h | 48 +
 1 file changed, 48 insertions(+)

diff --git a/include/linux/rculist.h b/include/linux/rculist.h
index df587d181844..516b4feb2682 100644
--- a/include/linux/rculist.h
+++ b/include/linux/rculist.h
@@ -63,9 +63,17 @@ static inline void INIT_LIST_HEAD_RCU(struct list_head *list)
RCU_LOCKDEP_WARN(!(cond) && !rcu_read_lock_any_held(),  \
 "RCU-list traversed in non-reader section!");  \
})
+
+#define __list_check_srcu(cond) \
+   ({   \
+   RCU_LOCKDEP_WARN(!(cond),\
+   "RCU-list traversed without holding the required lock!");\
+   })
 #else
 #define __list_check_rcu(dummy, cond, extra...)
\
({ check_arg_count_one(extra); })
+
+#define __list_check_srcu(cond)
 #endif
 
 /*
@@ -383,6 +391,25 @@ static inline void list_splice_tail_init_rcu(struct 
list_head *list,
&pos->member != (head); \
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
 
+/**
+ * list_for_each_entry_srcu-   iterate over rcu list of given type
+ * @pos:   the type * to use as a loop cursor.
+ * @head:  the head for your list.
+ * @member:the name of the list_head within the struct.
+ * @cond:  lockdep expression for the lock required to traverse the list.
+ *
+ * This list-traversal primitive may safely run concurrently with
+ * the _rcu list-mutation primitives such as list_add_rcu()
+ * as long as the traversal is guarded by srcu_read_lock().
+ * The lockdep expression srcu_read_lock_held() can be passed as the
+ * cond argument from read side.
+ */
+#define list_for_each_entry_srcu(pos, head, member, cond)  \
+   for (__list_check_srcu(cond),   \
+pos = list_entry_rcu((head)->next, typeof(*pos), member);  \
+   &pos->member != (head); \
+   pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
+
 /**
  * list_entry_lockless - get the struct for this entry
  * @ptr:the &struct list_head pointer.
@@ -681,6 +708,27 @@ static inline void hlist_add_behind_rcu(struct hlist_node 
*n,
pos = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu(\
&(pos)->member)), typeof(*(pos)), member))
 
+/**
+ * hlist_for_each_entry_srcu - iterate over rcu list of given type
+ * @pos:   the type * to use as a loop cursor.
+ * @head:  the head for your list.
+ * @member:the name of the hlist_node within the struct.
+ * @cond:  lockdep expression for the lock required to traverse the list.
+ *
+ * This list-traversal primitive may safely run concurrently with
+ * the _rcu list-mutation primitives such as hlist_add_head_rcu()
+ * as long as the traversal is guarded by srcu_read_lock().
+ * The lockdep expression srcu_read_lock_held() can be passed as the
+ * cond argument from read side.
+ */
+#define hlist_for_each_entry_srcu(pos, head, member, cond) \
+   for (__list_check_srcu(cond),   \
+pos = hlist_entry_safe(rcu_dereference_raw(hlist_first_rcu(head)),\
+   typeof(*(pos)), member);\
+   pos;\
+   pos = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu(\
+   &(pos)->member)), typeof(*(pos)), member))
+
 /**
  * hlist_for_each_entry_rcu_notrace - iterate over rcu list of given type (for 
tracing)
  * @pos:   the type * to use as a loop cursor.
-- 
2.17.1



Re: splat and freeze (2 instances)

2020-07-12 Thread Ilkka Prusi

Hi,

Here's a second splat with some additional tracing enabled.

Again this is gathered with phonecamera from frozen machine (dmesg -w) 
and full logs could not be saved.


Linux version 5.8.0-rc4+ (gcc (Debian 9.3.0-14) 9.3.0, GNU ld (GNU 
Binutils for Debian) 2.34.90.20200706) #95 SMP PREEMPT Sun Jul 12 
12:29:16 EEST 2020


schedule_timeout+0x162/0x1a0
? trace_hardirqs_on+0x1c/0xf0
wait_for_completion+0x84/0xe0
virt_efi_query_variable_info+0x163/0x170
efi_query_variable_store+0x53/0x190
? _raw_spin_unlock_irqrestore+0x41/0x70
efivar_entry_set_safe+0xbf/0x210
efi_pstore_write+0x116/0x160/ [efi_pstore]
pstore_dump+0x10c/0x2e0
? kmsg_dump+0xd5/0x1c0
kmsg_dump+0x7b/0x1c0
oops_end+0x6f/0xc0
do_trap+0x8c/0x100
? do_futex+0x15e/0x560
do_error_trap+0x86/0x100
? do_futex+0x15e/0x560
? do_futex+0x15e/0x560
exc_invalid_op+0x4c/0x60
? do_futex+0x15e/0x560
asm_exc_invalid_op+0xf/0x20
RIP: 0010:do_futex+0x15e/0x560
Code: 85 c0 75 4b c7 84 24 a8 00 00 00 ff ff ff ff 41 b8 ff ff ff ff 4c 
89 e9 44 89 f2 44 89 e6 48 89 ef e8 d6 e0 ff ff 48 98 e9 62  ff ff 
83 f8 08 74 61 83 f8 09 75 18 44 8b 84 24 a8 00 00 00 eb

RSP: 0018:c9000128fe08 EFLAGS: 00010282
RAX: ff92 RBX:  RCX: 00ae8b8c
RDX: 8887fe8dde80 RSI: 8887fa562720 RDI: c9000128fd10
RBP: 57b01018 R08:  R09: 
R10: 0001 R11:  R12: 
R13: c9000128fed0 R14:  R15: 
? do_futex+0x15e/0x560
? lockdep_hardirqs_on_prepare+0xcf/0x170
? _raw_spin_unlock_irq+0x24/0x50
? trace_hardirqs_on+0x1c/0xf0
? _raw_spin_unlock_irq+0x35/0x50
? finish_task_switch+0x9e/0x280
? finish_task_switch+0x70/0x280
? __switch_to+0x361/0x480
? __switch_to_asm+0x36/0x70
__ia32_sys_futex_time32+0x13a/0x168
do_syscall_32_irqs_on+0x45/0x60
do_fast_syscall_32+0x6b/0xf0
entry_SYSCALL_compat_after_hwframe+0x45/0x4d
RIP: 0023:0xf7f06579
Code: Bad RIP value.
RSP: 002b:be3faec0 EFLAGS: 00200282 ORIG_RAX: 00f0
RAX: ffda RBX: 57b01018 RCX: 0089
RDX:  RSI: be3faf90 RDI: 
RBP:  R08:  R09: 
R10:  R11:  R12: 
R13:  R14:  R15: 
irq event stamp: 455331
hardirqs last  enabled at (455331): [] 
do_error_trap+0xbe/0x100
hardirqs last disabled at (455330): [] 
idtentry_enter_cond_rcu+0x1d/0x50
softirqs last  enabled at (454086): [] 
__do_softirq+0x3aa/0x4af
softirqs last disabled at (454075): [] 
asm_call_on_stack+0x12/0x20

---[ end trace 87cc90f8d863ccc2 ]---

decode stacktrace:
$ cat ~/crashdata/580rc4/irq | ./scripts/decode_stacktrace.sh vmlinux . 
/lib/modules/5.8.0-rc4+/

schedule_timeout (/usr/src/linux/kernel/time/timer.c:1874)
? trace_hardirqs_on (/usr/src/linux/kernel/trace/trace_preemptirq.c:50 
(discriminator 42))
wait_for_completion (/usr/src/linux/kernel/sched/completion.c:86 
/usr/src/linux/kernel/sched/completion.c:106 
/usr/src/linux/kernel/sched/completion.c:117 
/usr/src/linux/kernel/sched/completion.c:138)
virt_efi_query_variable_info 
(/usr/src/linux/drivers/firmware/efi/runtime-wrappers.c:374 
(discriminator 7))
efi_query_variable_store 
(/usr/src/linux/arch/x86/platform/efi/quirks.c:165 
/usr/src/linux/arch/x86/platform/efi/quirks.c:151)
? _raw_spin_unlock_irqrestore 
(/usr/src/linux/./arch/x86/include/asm/preempt.h:102 
/usr/src/linux/./include/linux/spinlock_api_smp.h:161 
/usr/src/linux/kernel/locking/spinlock.c:191)

efivar_entry_set_safe (/usr/src/linux/drivers/firmware/efi/vars.c:784)
efi_pstore_write (/usr/src/linux/drivers/firmware/efi/efi-pstore.c:243) 
efi_pstore

pstore_dump (/usr/src/linux/fs/pstore/platform.c:456)
? kmsg_dump (/usr/src/linux/kernel/printk/printk.c:3221)
kmsg_dump (/usr/src/linux/kernel/printk/printk.c:3231 (discriminator 4))
oops_end (/usr/src/linux/arch/x86/kernel/dumpstack.c:348)
do_trap (/usr/src/linux/arch/x86/kernel/traps.c:119 
/usr/src/linux/arch/x86/kernel/traps.c:157)

? do_futex (/usr/src/linux/kernel/futex.c:3811)
do_error_trap (/usr/src/linux/arch/x86/kernel/traps.c:83 
/usr/src/linux/arch/x86/kernel/traps.c:178)

? do_futex (/usr/src/linux/kernel/futex.c:3811)
? do_futex (/usr/src/linux/kernel/futex.c:3811)
exc_invalid_op (/usr/src/linux/arch/x86/kernel/traps.c:262)
? do_futex (/usr/src/linux/kernel/futex.c:3811)
asm_exc_invalid_op (/usr/src/linux/./arch/x86/include/asm/idtentry.h:542)
RIP: 0010:do_futex (/usr/src/linux/kernel/futex.c:3811)
Code: 85 c0 75 4b c7 84 24 a8 00 00 00 ff ff ff ff 41 b8 ff ff ff ff 4c 
89 e9 44 89 f2 44 89 e6 48 89 ef e8 d6 e0 ff ff 48 98 e9 62  ff ff 
83 f8 08 74 61 83 f8 09 75 18 44 8b 84 24 a8 00 00 00 eb

All code

   0:    85 c0        test   %eax,%eax
   2:    75 4b        jne    0x4f
   4:    c7 84 24 a8 00 00 00     movl   $0x,0xa8(%rsp)
   b:    ff ff ff ff
   f:    41 b8 ff ff ff ff   

Re: [PATCH v8 6/6] IIO: Ingenic JZ47xx: Add touchscreen mode.

2020-07-12 Thread Jonathan Cameron
On Thu,  9 Jul 2020 17:22:00 +0200
Artur Rojek  wrote:

> The SADC component in JZ47xx SoCs provides support for touchscreen
> operations (pen position and pen down pressure) in single-ended and
> differential modes.
> 
> The touchscreen component of SADC takes a significant time to stabilize
> after first receiving the clock and a delay of 50ms has been empirically
> proven to be a safe value before data sampling can begin.
> 
> Of the known hardware to use this controller, GCW Zero and Anbernic RG-350
> utilize the touchscreen mode by having their joystick(s) attached to the
> X/Y positive/negative input pins.
> 
> JZ4770 and later SoCs introduce a low-level command feature. With it, up
> to 32 commands can be programmed, each one corresponding to a sampling
> job. It allows to change the low-voltage reference, the high-voltage
> reference, have them connected to VCC, GND, or one of the X-/X+ or Y-/Y+
> pins.
> 
> This patch introduces support for 6 stream-capable channels:
> - channel #0 samples X+/GND
> - channel #1 samples Y+/GND
> - channel #2 samples X-/GND
> - channel #3 samples Y-/GND
> - channel #4 samples X+/X-
> - channel #5 samples Y+/Y-

The one thing I noticed on this read was that we are slightly stretching
the normal IIO channel definitions.  The claim is that each of these channels
is a POSITIONREALTIVE channel, whereas that isn't really true.  They are
related to the position, but as I understand it not directly measuring it
(particularly X+ - X-) which is pretty much a reference voltage (I think!)

We might be better off just describing these as voltage channels, with
4 and 5 described as differential voltage channels.  The problem there
being that it doesn't describe the fact that the measurements are with
particular voltages also being applied to the touch screen.

Perhaps we are best off just leaving it as you have it and being a bit
'odd'.  What do you think?  Having written this down I think perhaps leaving
it alone is the best plan :(

Otherwise this all looks fine to me.

Thanks,

Jonathan

> 
> Being able to sample X-/GND and Y-/GND is useful on some devices, where
> one joystick is connected to the X+/Y+ pins, and a second joystick is
> connected to the X-/Y- pins.
> 
> All the boards which probe this driver have the interrupt provided from
> Device Tree, with no need to handle a case where the IRQ was not provided.
> 
> Co-developed-by: Paul Cercueil 
> Signed-off-by: Paul Cercueil 
> Signed-off-by: Artur Rojek 
> ---
> 
>  Changes:
> 
>  v2: - improve description of the touchscreen mode,
>  - get rid of the unneeded kfifo,
>  - drop IIO_BUFFER_CB from Kconfig,
>  - remove extended names from the touchscreen channels
> 
>  v3: remove unneeded `linux/iio/kfifo_buf.h` include
> 
>  v4: clarify irq provider source in the patch description
> 
>  v5: no change
> 
>  v6: - correct the spelling of Device Tree and IRQ in commit message
>  - don't omit trailing commas from initializer lists
>  - error check `clk_enable`
>  - remove redundant `dev_err` from `platform_get_irq` error check
> 
>  v7: no change
> 
>  v8: add support for ADCMD low-level command feature
> 
>  drivers/iio/adc/Kconfig   |   1 +
>  drivers/iio/adc/ingenic-adc.c | 250 +-
>  2 files changed, 249 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index ff3569635ce0..5b57437cef75 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -500,6 +500,7 @@ config INA2XX_ADC
>  config INGENIC_ADC
>   tristate "Ingenic JZ47xx SoCs ADC driver"
>   depends on MIPS || COMPILE_TEST
> + select IIO_BUFFER
>   help
> Say yes here to build support for the Ingenic JZ47xx SoCs ADC unit.
>  
> diff --git a/drivers/iio/adc/ingenic-adc.c b/drivers/iio/adc/ingenic-adc.c
> index 0233a9055c86..976aea46fede 100644
> --- a/drivers/iio/adc/ingenic-adc.c
> +++ b/drivers/iio/adc/ingenic-adc.c
> @@ -8,7 +8,9 @@
>  
>  #include 
>  #include 
> +#include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -20,19 +22,46 @@
>  #define JZ_ADC_REG_CFG   0x04
>  #define JZ_ADC_REG_CTRL  0x08
>  #define JZ_ADC_REG_STATUS0x0c
> +#define JZ_ADC_REG_ADSAME0x10
> +#define JZ_ADC_REG_ADWAIT0x14
>  #define JZ_ADC_REG_ADTCH 0x18
>  #define JZ_ADC_REG_ADBDAT0x1c
>  #define JZ_ADC_REG_ADSDAT0x20
> +#define JZ_ADC_REG_ADCMD 0x24
>  #define JZ_ADC_REG_ADCLK 0x28
>  
>  #define JZ_ADC_REG_ENABLE_PD BIT(7)
>  #define JZ_ADC_REG_CFG_AUX_MD(BIT(0) | BIT(1))
>  #define JZ_ADC_REG_CFG_BAT_MDBIT(4)
> +#define JZ_ADC_REG_CFG_SAMPLE_NUM(n) ((n) << 10)
> +#define JZ_ADC_REG_CFG_PULL_UP(n)((n) << 16)
> +#define JZ_ADC_REG_CFG_CMD_SEL   BIT(22)
> +#define JZ_ADC_REG_CFG_TOUCH_OPS_MASK(BIT(31) | GENMASK(23, 10)

Re: [PATCH v2] Replace HTTP links with HTTPS ones: Documentation/devicetree/bindings/iio

2020-07-12 Thread Jonathan Cameron
On Sat, 4 Jul 2020 16:05:01 -0700
Matt Ranostay  wrote:

> On Sat, Jul 4, 2020 at 12:34 PM Alexander A. Klimov
>  wrote:
> >
> > Rationale:
> > Reduces attack surface on kernel devs opening the links for MITM
> > as HTTPS traffic is much harder to manipulate.
> >  
> 
> With regards to the drivers that I've authored the changes look good to me.
> 
> Reviewed-by: Matt Ranostay 
Applied. Thanks
> 
> 
> > Deterministic algorithm:
> > For each file:
> >   If not .svg:
> > For each line:
> >   If doesn't contain `\bxmlns\b`:
> > For each link, `\bhttp://[^# \t\r\n]*(?:\w|/)`:
> >   If both the HTTP and HTTPS versions
> >   return 200 OK and serve the same content:
> > Replace HTTP with HTTPS.
> >
> > Signed-off-by: Alexander A. Klimov 
> > ---
> >  Changes in v2:
> >  Addressed 
> > https://lore.kernel.org/linux-iio/20200704173459.78ceec60@archlinux/
> >
> >  Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml  | 4 ++--
> >  Documentation/devicetree/bindings/iio/dac/ti,dac7612.txt  | 2 +-
> >  Documentation/devicetree/bindings/iio/iio-bindings.txt| 2 +-
> >  Documentation/devicetree/bindings/iio/light/apds9300.txt  | 2 +-
> >  Documentation/devicetree/bindings/iio/light/apds9960.txt  | 2 +-
> >  Documentation/devicetree/bindings/iio/light/opt3001.txt   | 2 +-
> >  Documentation/devicetree/bindings/iio/light/vl6180.txt| 2 +-
> >  .../devicetree/bindings/iio/potentiometer/mcp41010.txt| 2 +-
> >  .../devicetree/bindings/iio/potentiostat/lmp91000.txt | 4 ++--
> >  .../devicetree/bindings/iio/pressure/asc,dlhl60d.yaml | 2 +-
> >  .../devicetree/bindings/iio/proximity/devantech-srf04.yaml| 4 ++--
> >  11 files changed, 14 insertions(+), 14 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml 
> > b/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml
> > index d124eba1ce54..fd4eaa3d0ab4 100644
> > --- a/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml
> > +++ b/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml
> > @@ -12,8 +12,8 @@ maintainers:
> >  description: |
> >Analog Devices ADXL345/ADXL375 3-Axis Digital Accelerometers that 
> > supports
> >both I2C & SPI interfaces.
> > -http://www.analog.com/en/products/mems/accelerometers/adxl345.html
> > -
> > http://www.analog.com/en/products/sensors-mems/accelerometers/adxl375.html
> > +https://www.analog.com/en/products/mems/accelerometers/adxl345.html
> > +
> > https://www.analog.com/en/products/sensors-mems/accelerometers/adxl375.html
> >
> >  properties:
> >compatible:
> > diff --git a/Documentation/devicetree/bindings/iio/dac/ti,dac7612.txt 
> > b/Documentation/devicetree/bindings/iio/dac/ti,dac7612.txt
> > index 639c94ed83e9..17af395b99d9 100644
> > --- a/Documentation/devicetree/bindings/iio/dac/ti,dac7612.txt
> > +++ b/Documentation/devicetree/bindings/iio/dac/ti,dac7612.txt
> > @@ -6,7 +6,7 @@ Is is programmable through an SPI interface.
> >
> >  The internal DACs are loaded when the LOADDACS pin is pulled down.
> >
> > -http://www.ti.com/lit/ds/sbas106/sbas106.pdf
> > +https://www.ti.com/lit/ds/sbas106/sbas106.pdf
> >
> >  Required Properties:
> >  - compatible: Should be one of:
> > diff --git a/Documentation/devicetree/bindings/iio/iio-bindings.txt 
> > b/Documentation/devicetree/bindings/iio/iio-bindings.txt
> > index af33267727f4..aa63cac7323e 100644
> > --- a/Documentation/devicetree/bindings/iio/iio-bindings.txt
> > +++ b/Documentation/devicetree/bindings/iio/iio-bindings.txt
> > @@ -9,7 +9,7 @@ specifier is an array of one or more cells identifying the 
> > IIO
> >  output on a device. The length of an IIO specifier is defined by the
> >  value of a #io-channel-cells property in the IIO provider node.
> >
> > -[1] http://marc.info/?l=linux-iio&m=135902119507483&w=2
> > +[1] https://marc.info/?l=linux-iio&m=135902119507483&w=2
> >
> >  ==IIO providers==
> >
> > diff --git a/Documentation/devicetree/bindings/iio/light/apds9300.txt 
> > b/Documentation/devicetree/bindings/iio/light/apds9300.txt
> > index aa199e09a493..3aa6db3ee99d 100644
> > --- a/Documentation/devicetree/bindings/iio/light/apds9300.txt
> > +++ b/Documentation/devicetree/bindings/iio/light/apds9300.txt
> > @@ -1,6 +1,6 @@
> >  * Avago APDS9300 ambient light sensor
> >
> > -http://www.avagotech.com/docs/AV02-1077EN
> > +https://www.avagotech.com/docs/AV02-1077EN
> >
> >  Required properties:
> >
> > diff --git a/Documentation/devicetree/bindings/iio/light/apds9960.txt 
> > b/Documentation/devicetree/bindings/iio/light/apds9960.txt
> > index 3af325ad194b..c53ddb81c4aa 100644
> > --- a/Documentation/devicetree/bindings/iio/light/apds9960.txt
> > +++ b/Documentation/devicetree/bindings/iio/light/apds9960.txt
> > @@ -1,6 +1,6 @@
> >  * Avago APDS9960 gesture/RGB/ALS/proximity sensor
> >
> > -http://www.avagotech.com/docs/AV02-4191EN
> > +https://www.avagotech.com/docs/AV02-4191EN
> >

Re: [PATCH v2] Replace HTTP links with HTTPS ones: drivers/iio

2020-07-12 Thread Jonathan Cameron
On Sat,  4 Jul 2020 21:27:43 +0200
"Alexander A. Klimov"  wrote:

> Rationale:
> Reduces attack surface on kernel devs opening the links for MITM
> as HTTPS traffic is much harder to manipulate.
> 
> Deterministic algorithm:
> For each file:
>   If not .svg:
> For each line:
>   If doesn't contain `\bxmlns\b`:
> For each link, `\bhttp://[^# \t\r\n]*(?:\w|/)`:
>   If both the HTTP and HTTPS versions
>   return 200 OK and serve the same content:
> Replace HTTP with HTTPS.
> 
> Signed-off-by: Alexander A. Klimov 
Applied to the togreg branch of iio.git and pushed out as testing for this
particular patch to be ignored by the autobuilders alongside ones where they
might do something more interesting :)

thanks

Jonathan

> ---
>  Changes in v2:
>  Addressed 
> https://lore.kernel.org/linux-iio/20200704172513.03815356@archlinux/
> 
>  drivers/iio/accel/adxl345_core.c |  2 +-
>  drivers/iio/adc/ad7949.c |  2 +-
>  drivers/iio/adc/ina2xx-adc.c |  2 +-
>  drivers/iio/adc/mcp320x.c|  8 
>  drivers/iio/adc/mcp3422.c|  4 ++--
>  drivers/iio/adc/ti-adc081c.c |  6 +++---
>  drivers/iio/adc/ti-adc0832.c |  2 +-
>  drivers/iio/adc/ti-adc084s021.c  |  2 +-
>  drivers/iio/adc/ti-adc128s052.c  |  6 +++---
>  drivers/iio/adc/ti-ads124s08.c   |  2 +-
>  drivers/iio/adc/ti-ads7950.c |  2 +-
>  drivers/iio/adc/ti-ads8344.c |  2 +-
>  drivers/iio/adc/ti-tlc4541.c |  4 ++--
>  drivers/iio/adc/ti_am335x_adc.c  |  2 +-
>  drivers/iio/adc/twl4030-madc.c   |  2 +-
>  drivers/iio/dac/ti-dac082s085.c  | 12 ++--
>  drivers/iio/dac/ti-dac5571.c | 18 +-
>  drivers/iio/dac/ti-dac7311.c |  2 +-
>  drivers/iio/health/afe4403.c |  2 +-
>  drivers/iio/health/afe4404.c |  2 +-
>  drivers/iio/health/afe440x.h |  2 +-
>  drivers/iio/humidity/hdc100x.c   | 10 +-
>  drivers/iio/light/lv0104cs.c |  2 +-
>  drivers/iio/light/opt3001.c  |  2 +-
>  drivers/iio/potentiometer/ad5272.c   |  2 +-
>  drivers/iio/potentiometer/max5481.c  |  2 +-
>  drivers/iio/potentiometer/mcp41010.c |  2 +-
>  drivers/iio/potentiometer/mcp4131.c  |  2 +-
>  drivers/iio/pressure/dlhl60d.c   |  2 +-
>  drivers/iio/proximity/srf04.c|  2 +-
>  drivers/iio/proximity/srf08.c|  6 +++---
>  31 files changed, 59 insertions(+), 59 deletions(-)
> 
> diff --git a/drivers/iio/accel/adxl345_core.c 
> b/drivers/iio/accel/adxl345_core.c
> index 9c269799e6c1..71d36bde9727 100644
> --- a/drivers/iio/accel/adxl345_core.c
> +++ b/drivers/iio/accel/adxl345_core.c
> @@ -4,7 +4,7 @@
>   *
>   * Copyright (c) 2017 Eva Rachel Retuya 
>   *
> - * Datasheet: 
> http://www.analog.com/media/en/technical-documentation/data-sheets/ADXL345.pdf
> + * Datasheet: 
> https://www.analog.com/media/en/technical-documentation/data-sheets/ADXL345.pdf
>   */
>  
>  #include 
> diff --git a/drivers/iio/adc/ad7949.c b/drivers/iio/adc/ad7949.c
> index 2c6f60edb7ce..3aba75b23bab 100644
> --- a/drivers/iio/adc/ad7949.c
> +++ b/drivers/iio/adc/ad7949.c
> @@ -3,7 +3,7 @@
>   *
>   * Copyright (C) 2018 CMC NV
>   *
> - * 
> http://www.analog.com/media/en/technical-documentation/data-sheets/AD7949.pdf
> + * 
> https://www.analog.com/media/en/technical-documentation/data-sheets/AD7949.pdf
>   */
>  
>  #include 
> diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c
> index bdd7cba6f6b0..de9924df437c 100644
> --- a/drivers/iio/adc/ina2xx-adc.c
> +++ b/drivers/iio/adc/ina2xx-adc.c
> @@ -273,7 +273,7 @@ static int ina2xx_read_raw(struct iio_dev *indio_dev,
>   * Available averaging rates for ina226. The indices correspond with
>   * the bit values expected by the chip (according to the ina226 datasheet,
>   * table 3 AVG bit settings, found at
> - * http://www.ti.com/lit/ds/symlink/ina226.pdf.
> + * https://www.ti.com/lit/ds/symlink/ina226.pdf.
>   */
>  static const int ina226_avg_tab[] = { 1, 4, 16, 64, 128, 256, 512, 1024 };
>  
> diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c
> index 2c0eb5de110c..6a31ee970678 100644
> --- a/drivers/iio/adc/mcp320x.c
> +++ b/drivers/iio/adc/mcp320x.c
> @@ -27,13 +27,13 @@
>   * MCP3553
>   *
>   * Datasheet can be found here:
> - * http://ww1.microchip.com/downloads/en/DeviceDoc/21293C.pdf  mcp3001
> - * http://ww1.microchip.com/downloads/en/DeviceDoc/21294E.pdf  mcp3002
> - * http://ww1.microchip.com/downloads/en/DeviceDoc/21295d.pdf  mcp3004/08
> + * https://ww1.microchip.com/downloads/en/DeviceDoc/21293C.pdf  mcp3001
> + * https://ww1.microchip.com/downloads/en/DeviceDoc/21294E.pdf  mcp3002
> + * https://ww1.microchip.com/downloads/en/DeviceDoc/21295d.pdf  mcp3004/08
>   * http://ww1.microchip.com/downloads/en/DeviceDoc/21290D.pdf  mcp3201
>   * http://ww1.microchip.com/downloads/en/DeviceDoc/21034D.pdf  mcp3202
>   * http://ww1.microchip.com/downloads/en/DeviceDoc/21298c.pdf 

[PATCH 00/18] perf metric: Add support to reuse metric

2020-07-12 Thread Jiri Olsa
hi,
this patchset is adding the support to reused metric in another 
metric. The metric needs to be referenced by 'metric:' prefix.

For example, to define IPC by using CPI with change like:

 "BriefDescription": "Instructions Per Cycle (per Logical Processor)",
 -   "MetricExpr": "INST_RETIRED.ANY / CPU_CLK_UNHALTED.THREAD",
 +   "MetricExpr": "1/metric:CPI",
 "MetricGroup": "TopDownL1",
 "MetricName": "IPC"

I won't be able to find all the possible places we could
use this at, so I wonder you guys (who was asking for this)
would try it and come up with comments if there's something
missing or we could already use it at some places.

It's based on Arnaldo's tmp.perf/core.

v2 changes:
  - collected Ian's acks for few patches [Ian]
  - renamed expr__add_id to expr__add_id_val [Ian]
  - renamed expr_parse_data to expr_id_data [Ian]
  - added recursion check [Ian]
  - added metric test for DCache_L2 metric [Ian]
  - added some renames as discussed in review [Ian]

Also available in here:
  git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
  perf/metric

thanks,
jirka


---
Jiri Olsa (18):
  perf metric: Rename expr__add_id to expr__add_val
  perf metric: Add struct expr_id_data to keep expr value
  perf metric: Add expr__add_id function
  perf metric: Change expr__get_id to return struct expr_id_data
  perf metric: Add expr__del_id function
  perf metric: Add find_metric function
  perf metric: Add add_metric function
  perf metric: Rename __metricgroup__add_metric to __add_metric
  perf metric: Collect referenced metrics in struct metric_ref_node
  perf metric: Collect referenced metrics in struct metric_expr
  perf metric: Add referenced metrics to hash data
  perf metric: Compute referenced metrics
  perf metric: Add events for the current group
  perf metric: Add cache_miss_cycles to metric parse test
  perf metric: Add DCache_L2 to metric parse test
  perf metric: Add recursion check when processing nested metrics
  perf metric: Rename struct egroup to metric
  perf metric: Rename group_list to list

 tools/perf/tests/expr.c |   7 +-
 tools/perf/tests/parse-metric.c | 131 +++-
 tools/perf/tests/pmu-events.c   |   4 +-
 tools/perf/util/expr.c  | 130 ++--
 tools/perf/util/expr.h  |  34 +-
 tools/perf/util/expr.y  |  16 +++--
 tools/perf/util/metricgroup.c   | 435 
---
 tools/perf/util/metricgroup.h   |   6 ++
 tools/perf/util/stat-shadow.c   |  24 ---
 9 files changed, 644 insertions(+), 143 deletions(-)



[PATCH 06/18] perf metric: Add find_metric function

2020-07-12 Thread Jiri Olsa
Decouple lookup metric logic into find_metric function,
so it can be used from other places in following changes.

Signed-off-by: Jiri Olsa 
---
 tools/perf/util/metricgroup.c | 89 +++
 1 file changed, 48 insertions(+), 41 deletions(-)

diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
index df0356ec120d..72552608ff7d 100644
--- a/tools/perf/util/metricgroup.c
+++ b/tools/perf/util/metricgroup.c
@@ -614,57 +614,64 @@ static int __metricgroup__add_metric(struct list_head 
*group_list,
return 0;
 }
 
-static int metricgroup__add_metric(const char *metric, bool metric_no_group,
-  struct strbuf *events,
-  struct list_head *group_list,
-  struct pmu_events_map *map)
+static struct pmu_event *find_metric(const char *metric, struct pmu_events_map 
*map)
 {
struct pmu_event *pe;
-   struct egroup *eg;
-   int i, ret;
-   bool has_match = false;
+   int i;
 
for (i = 0; ; i++) {
pe = &map->table[i];
-
-   if (!pe->name && !pe->metric_group && !pe->metric_name) {
-   /* End of pmu events. */
-   if (!has_match)
-   return -EINVAL;
+   /* End of pmu events. */
+   if (!pe->name && !pe->metric_group && !pe->metric_name)
break;
-   }
if (!pe->metric_expr)
continue;
if (match_metric(pe->metric_group, metric) ||
-   match_metric(pe->metric_name, metric)) {
-   has_match = true;
-   pr_debug("metric expr %s for %s\n", pe->metric_expr, 
pe->metric_name);
-
-   if (!strstr(pe->metric_expr, "?")) {
-   ret = __metricgroup__add_metric(group_list,
-   pe,
-   metric_no_group,
-   1);
-   if (ret)
-   return ret;
-   } else {
-   int j, count;
-
-   count = arch_get_runtimeparam();
-
-   /* This loop is added to create multiple
-* events depend on count value and add
-* those events to group_list.
-*/
+   match_metric(pe->metric_name, metric))
+   return pe;
+   }
 
-   for (j = 0; j < count; j++) {
-   ret = __metricgroup__add_metric(
-   group_list, pe,
-   metric_no_group, j);
-   if (ret)
-   return ret;
-   }
-   }
+   return NULL;
+}
+
+static int metricgroup__add_metric(const char *metric, bool metric_no_group,
+  struct strbuf *events,
+  struct list_head *group_list,
+  struct pmu_events_map *map)
+{
+   struct pmu_event *pe;
+   struct egroup *eg;
+   int ret;
+
+   pe = find_metric(metric, map);
+   if (!pe)
+   return -EINVAL;
+
+   pr_debug("metric expr %s for %s\n", pe->metric_expr, pe->metric_name);
+
+   if (!strstr(pe->metric_expr, "?")) {
+   ret = __metricgroup__add_metric(group_list,
+   pe,
+   metric_no_group,
+   1);
+   if (ret)
+   return ret;
+   } else {
+   int j, count;
+
+   count = arch_get_runtimeparam();
+
+   /* This loop is added to create multiple
+* events depend on count value and add
+* those events to group_list.
+*/
+
+   for (j = 0; j < count; j++) {
+   ret = __metricgroup__add_metric(
+   group_list, pe,
+   metric_no_group, j);
+   if (ret)
+   return ret;
}
}
list_for_each_entry(eg, group_list, nd) {
-- 
2.25.4



[PATCH 01/18] perf metric: Rename expr__add_id to expr__add_val

2020-07-12 Thread Jiri Olsa
Renaming expr__add_id to expr__add_val so we can use
expr__add_id to actually add just id without any value
in following changes.

There's no functional change.

Signed-off-by: Jiri Olsa 
---
 tools/perf/tests/expr.c   | 4 ++--
 tools/perf/tests/pmu-events.c | 4 ++--
 tools/perf/util/expr.c| 2 +-
 tools/perf/util/expr.h| 2 +-
 tools/perf/util/expr.y| 2 +-
 tools/perf/util/stat-shadow.c | 4 ++--
 6 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c
index b7e5ef3007fc..d13fc1dfd5ef 100644
--- a/tools/perf/tests/expr.c
+++ b/tools/perf/tests/expr.c
@@ -24,8 +24,8 @@ int test__expr(struct test *t __maybe_unused, int subtest 
__maybe_unused)
struct expr_parse_ctx ctx;
 
expr__ctx_init(&ctx);
-   expr__add_id(&ctx, strdup("FOO"), 1);
-   expr__add_id(&ctx, strdup("BAR"), 2);
+   expr__add_id_val(&ctx, strdup("FOO"), 1);
+   expr__add_id_val(&ctx, strdup("BAR"), 2);
 
ret = test(&ctx, "1+1", 2);
ret |= test(&ctx, "FOO+BAR", 3);
diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c
index b66b021476ec..eb19f9a0bc15 100644
--- a/tools/perf/tests/pmu-events.c
+++ b/tools/perf/tests/pmu-events.c
@@ -492,7 +492,7 @@ static int test_parsing(void)
 */
k = 1;
hashmap__for_each_entry((&ctx.ids), cur, bkt)
-   expr__add_id(&ctx, strdup(cur->key), k++);
+   expr__add_id_val(&ctx, strdup(cur->key), k++);
 
hashmap__for_each_entry((&ctx.ids), cur, bkt) {
if (check_parse_cpu(cur->key, map == cpus_map,
@@ -547,7 +547,7 @@ static int metric_parse_fake(const char *str)
 */
i = 1;
hashmap__for_each_entry((&ctx.ids), cur, bkt)
-   expr__add_id(&ctx, strdup(cur->key), i++);
+   expr__add_id_val(&ctx, strdup(cur->key), i++);
 
hashmap__for_each_entry((&ctx.ids), cur, bkt) {
if (check_parse_fake(cur->key)) {
diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
index e8f777830a23..9116a3a01eea 100644
--- a/tools/perf/util/expr.c
+++ b/tools/perf/util/expr.c
@@ -33,7 +33,7 @@ static bool key_equal(const void *key1, const void *key2,
 }
 
 /* Caller must make sure id is allocated */
-int expr__add_id(struct expr_parse_ctx *ctx, const char *name, double val)
+int expr__add_id_val(struct expr_parse_ctx *ctx, const char *name, double val)
 {
double *val_ptr = NULL, *old_val = NULL;
char *old_key = NULL;
diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h
index 8a2c1074f90f..bb6bac836b48 100644
--- a/tools/perf/util/expr.h
+++ b/tools/perf/util/expr.h
@@ -22,7 +22,7 @@ struct expr_scanner_ctx {
 
 void expr__ctx_init(struct expr_parse_ctx *ctx);
 void expr__ctx_clear(struct expr_parse_ctx *ctx);
-int expr__add_id(struct expr_parse_ctx *ctx, const char *id, double val);
+int expr__add_id_val(struct expr_parse_ctx *ctx, const char *id, double val);
 int expr__get_id(struct expr_parse_ctx *ctx, const char *id, double *val_ptr);
 int expr__parse(double *final_val, struct expr_parse_ctx *ctx,
const char *expr, int runtime);
diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y
index 5fcb98800f9c..b2b3420ea6ec 100644
--- a/tools/perf/util/expr.y
+++ b/tools/perf/util/expr.y
@@ -69,7 +69,7 @@ all_other: all_other other
 
 other: ID
 {
-   expr__add_id(ctx, $1, 0.0);
+   expr__add_id_val(ctx, $1, 0.0);
 }
 |
 MIN | MAX | IF | ELSE | SMT_ON | NUMBER | '|' | '^' | '&' | '-' | '+' | '*' | 
'/' | '%' | '(' | ')' | ','
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index 8fdef47005e6..fc9ac4b4218e 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -773,9 +773,9 @@ static int prepare_metric(struct evsel **metric_events,
*pn = 0;
 
if (metric_total)
-   expr__add_id(pctx, n, metric_total);
+   expr__add_id_val(pctx, n, metric_total);
else
-   expr__add_id(pctx, n, avg_stats(stats)*scale);
+   expr__add_id_val(pctx, n, avg_stats(stats)*scale);
}
 
return i;
-- 
2.25.4



[PATCH 05/18] perf metric: Add expr__del_id function

2020-07-12 Thread Jiri Olsa
Adding expr__del_id function to remove ID from hashmap.
It will save us few lines in following changes.

Signed-off-by: Jiri Olsa 
---
 tools/perf/util/expr.c | 21 +
 tools/perf/util/expr.h |  1 +
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
index 7d02d29286bc..91142d4c3419 100644
--- a/tools/perf/util/expr.c
+++ b/tools/perf/util/expr.c
@@ -75,6 +75,17 @@ int expr__get_id(struct expr_parse_ctx *ctx, const char *id,
return hashmap__find(&ctx->ids, id, (void **)data) ? 0 : -1;
 }
 
+void expr__del_id(struct expr_parse_ctx *ctx, const char *id)
+{
+   struct expr_id_data *old_val = NULL;
+   char *old_key = NULL;
+
+   hashmap__delete(&ctx->ids, id,
+   (const void **)&old_key, (void **)&old_val);
+   free(old_key);
+   free(old_val);
+}
+
 void expr__ctx_init(struct expr_parse_ctx *ctx)
 {
hashmap__init(&ctx->ids, key_hash, key_equal, NULL);
@@ -132,16 +143,10 @@ int expr__parse(double *final_val, struct expr_parse_ctx 
*ctx,
 int expr__find_other(const char *expr, const char *one,
 struct expr_parse_ctx *ctx, int runtime)
 {
-   struct expr_id_data *old_val = NULL;
-   char *old_key = NULL;
int ret = __expr__parse(NULL, ctx, expr, EXPR_OTHER, runtime);
 
-   if (one) {
-   hashmap__delete(&ctx->ids, one,
-   (const void **)&old_key, (void **)&old_val);
-   free(old_key);
-   free(old_val);
-   }
+   if (one)
+   expr__del_id(ctx, one);
 
return ret;
 }
diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h
index f38292fdab19..2462abd0ac65 100644
--- a/tools/perf/util/expr.h
+++ b/tools/perf/util/expr.h
@@ -26,6 +26,7 @@ struct expr_scanner_ctx {
 
 void expr__ctx_init(struct expr_parse_ctx *ctx);
 void expr__ctx_clear(struct expr_parse_ctx *ctx);
+void expr__del_id(struct expr_parse_ctx *ctx, const char *id);
 int expr__add_id(struct expr_parse_ctx *ctx, const char *id);
 int expr__add_id_val(struct expr_parse_ctx *ctx, const char *id, double val);
 int expr__get_id(struct expr_parse_ctx *ctx, const char *id,
-- 
2.25.4



[PATCH 02/18] perf metric: Add struct expr_id_data to keep expr value

2020-07-12 Thread Jiri Olsa
Adding struct expr_id_data to keep expr value
instead of just simple double pointer, so we can
store more data for ID in following changes.

Signed-off-by: Jiri Olsa 
---
 tools/perf/tests/expr.c   |  3 ++-
 tools/perf/util/expr.c| 22 +++---
 tools/perf/util/expr.h|  4 
 tools/perf/util/metricgroup.c |  2 +-
 4 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c
index d13fc1dfd5ef..4d01051951cd 100644
--- a/tools/perf/tests/expr.c
+++ b/tools/perf/tests/expr.c
@@ -18,8 +18,9 @@ static int test(struct expr_parse_ctx *ctx, const char *e, 
double val2)
 
 int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused)
 {
+   struct expr_id_data *val_ptr;
const char *p;
-   double val, *val_ptr;
+   double val;
int ret;
struct expr_parse_ctx ctx;
 
diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
index 9116a3a01eea..5d05f9765ed8 100644
--- a/tools/perf/util/expr.c
+++ b/tools/perf/util/expr.c
@@ -33,32 +33,32 @@ static bool key_equal(const void *key1, const void *key2,
 }
 
 /* Caller must make sure id is allocated */
-int expr__add_id_val(struct expr_parse_ctx *ctx, const char *name, double val)
+int expr__add_id_val(struct expr_parse_ctx *ctx, const char *id, double val)
 {
-   double *val_ptr = NULL, *old_val = NULL;
+   struct expr_id_data *data_ptr = NULL, *old_data = NULL;
char *old_key = NULL;
int ret;
 
if (val != 0.0) {
-   val_ptr = malloc(sizeof(double));
-   if (!val_ptr)
+   data_ptr = malloc(sizeof(*data_ptr));
+   if (!data_ptr)
return -ENOMEM;
-   *val_ptr = val;
+   data_ptr->val = val;
}
-   ret = hashmap__set(&ctx->ids, name, val_ptr,
-  (const void **)&old_key, (void **)&old_val);
+   ret = hashmap__set(&ctx->ids, id, data_ptr,
+  (const void **)&old_key, (void **)&old_data);
free(old_key);
-   free(old_val);
+   free(old_data);
return ret;
 }
 
 int expr__get_id(struct expr_parse_ctx *ctx, const char *id, double *val_ptr)
 {
-   double *data;
+   struct expr_id_data *data;
 
if (!hashmap__find(&ctx->ids, id, (void **)&data))
return -1;
-   *val_ptr = (data == NULL) ?  0.0 : *data;
+   *val_ptr = (data == NULL) ?  0.0 : data->val;
return 0;
 }
 
@@ -119,7 +119,7 @@ int expr__parse(double *final_val, struct expr_parse_ctx 
*ctx,
 int expr__find_other(const char *expr, const char *one,
 struct expr_parse_ctx *ctx, int runtime)
 {
-   double *old_val = NULL;
+   struct expr_id_data *old_val = NULL;
char *old_key = NULL;
int ret = __expr__parse(NULL, ctx, expr, EXPR_OTHER, runtime);
 
diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h
index bb6bac836b48..21fe5bd85718 100644
--- a/tools/perf/util/expr.h
+++ b/tools/perf/util/expr.h
@@ -15,6 +15,10 @@ struct expr_parse_ctx {
struct hashmap ids;
 };
 
+struct expr_id_data {
+   double  val;
+};
+
 struct expr_scanner_ctx {
int start_token;
int runtime;
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
index 82fecb5a302d..df0356ec120d 100644
--- a/tools/perf/util/metricgroup.c
+++ b/tools/perf/util/metricgroup.c
@@ -138,7 +138,7 @@ static struct evsel *find_evsel_group(struct evlist 
*perf_evlist,
  unsigned long *evlist_used)
 {
struct evsel *ev, *current_leader = NULL;
-   double *val_ptr;
+   struct expr_id_data *val_ptr;
int i = 0, matched_events = 0, events_to_match;
const int idnum = (int)hashmap__size(&pctx->ids);
 
-- 
2.25.4



[PATCH 03/18] perf metric: Add expr__add_id function

2020-07-12 Thread Jiri Olsa
Adding expr__add_id function to data for ID
with zero value, which is used when scanning
the expression for IDs.

Acked-by: Ian Rogers 
Signed-off-by: Jiri Olsa 
---
 tools/perf/util/expr.c | 29 +++--
 tools/perf/util/expr.h |  1 +
 tools/perf/util/expr.y |  2 +-
 3 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
index 5d05f9765ed8..4b8953605aed 100644
--- a/tools/perf/util/expr.c
+++ b/tools/perf/util/expr.c
@@ -32,6 +32,24 @@ static bool key_equal(const void *key1, const void *key2,
return !strcmp((const char *)key1, (const char *)key2);
 }
 
+/* Caller must make sure id is allocated */
+int expr__add_id(struct expr_parse_ctx *ctx, const char *id)
+{
+   struct expr_id_data *data_ptr = NULL, *old_data = NULL;
+   char *old_key = NULL;
+   int ret;
+
+   data_ptr = malloc(sizeof(*data_ptr));
+   if (!data_ptr)
+   return -ENOMEM;
+
+   ret = hashmap__set(&ctx->ids, id, data_ptr,
+  (const void **)&old_key, (void **)&old_data);
+   free(old_key);
+   free(old_data);
+   return ret;
+}
+
 /* Caller must make sure id is allocated */
 int expr__add_id_val(struct expr_parse_ctx *ctx, const char *id, double val)
 {
@@ -39,12 +57,11 @@ int expr__add_id_val(struct expr_parse_ctx *ctx, const char 
*id, double val)
char *old_key = NULL;
int ret;
 
-   if (val != 0.0) {
-   data_ptr = malloc(sizeof(*data_ptr));
-   if (!data_ptr)
-   return -ENOMEM;
-   data_ptr->val = val;
-   }
+   data_ptr = malloc(sizeof(*data_ptr));
+   if (!data_ptr)
+   return -ENOMEM;
+   data_ptr->val = val;
+
ret = hashmap__set(&ctx->ids, id, data_ptr,
   (const void **)&old_key, (void **)&old_data);
free(old_key);
diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h
index 21fe5bd85718..ac32cda42006 100644
--- a/tools/perf/util/expr.h
+++ b/tools/perf/util/expr.h
@@ -26,6 +26,7 @@ struct expr_scanner_ctx {
 
 void expr__ctx_init(struct expr_parse_ctx *ctx);
 void expr__ctx_clear(struct expr_parse_ctx *ctx);
+int expr__add_id(struct expr_parse_ctx *ctx, const char *id);
 int expr__add_id_val(struct expr_parse_ctx *ctx, const char *id, double val);
 int expr__get_id(struct expr_parse_ctx *ctx, const char *id, double *val_ptr);
 int expr__parse(double *final_val, struct expr_parse_ctx *ctx,
diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y
index b2b3420ea6ec..8befe4a46f87 100644
--- a/tools/perf/util/expr.y
+++ b/tools/perf/util/expr.y
@@ -69,7 +69,7 @@ all_other: all_other other
 
 other: ID
 {
-   expr__add_id_val(ctx, $1, 0.0);
+   expr__add_id(ctx, $1);
 }
 |
 MIN | MAX | IF | ELSE | SMT_ON | NUMBER | '|' | '^' | '&' | '-' | '+' | '*' | 
'/' | '%' | '(' | ')' | ','
-- 
2.25.4



[PATCH 14/18] perf metric: Add cache_miss_cycles to metric parse test

2020-07-12 Thread Jiri Olsa
Adding test that compute metric with other metrics in it.

  cache_miss_cycles = metric:dcache_miss_cpi + metric:icache_miss_cycles

Signed-off-by: Jiri Olsa 
---
 tools/perf/tests/parse-metric.c | 33 +
 1 file changed, 33 insertions(+)

diff --git a/tools/perf/tests/parse-metric.c b/tools/perf/tests/parse-metric.c
index 8c48251425e1..28f33893338b 100644
--- a/tools/perf/tests/parse-metric.c
+++ b/tools/perf/tests/parse-metric.c
@@ -11,6 +11,8 @@
 #include "debug.h"
 #include "expr.h"
 #include "stat.h"
+#include 
+#include 
 
 static struct pmu_event pme_test[] = {
 {
@@ -22,6 +24,18 @@ static struct pmu_event pme_test[] = {
  "( 1 + cpu_clk_unhalted.one_thread_active / 
cpu_clk_unhalted.ref_xclk ) )))",
.metric_name= "Frontend_Bound_SMT",
 },
+{
+   .metric_expr= "l1d\\-loads\\-misses / inst_retired.any",
+   .metric_name= "dcache_miss_cpi",
+},
+{
+   .metric_expr= "l1i\\-loads\\-misses / inst_retired.any",
+   .metric_name= "icache_miss_cycles",
+},
+{
+   .metric_expr= "(dcache_miss_cpi + icache_miss_cycles)",
+   .metric_name= "cache_miss_cycles",
+},
 };
 
 static struct pmu_events_map map = {
@@ -162,9 +176,28 @@ static int test_frontend(void)
return 0;
 }
 
+static int test_cache_miss_cycles(void)
+{
+   double ratio;
+   struct value vals[] = {
+   { .event = "l1d-loads-misses",  .val = 300 },
+   { .event = "l1i-loads-misses",  .val = 200 },
+   { .event = "inst_retired.any",  .val = 400 },
+   { 0 },
+   };
+
+   TEST_ASSERT_VAL("failed to compute metric",
+   compute_metric("cache_miss_cycles", vals, &ratio) == 0);
+
+   TEST_ASSERT_VAL("cache_miss_cycles failed, wrong ratio",
+   ratio == 1.25);
+   return 0;
+}
+
 int test__parse_metric(struct test *test __maybe_unused, int subtest 
__maybe_unused)
 {
TEST_ASSERT_VAL("IPC failed", test_ipc() == 0);
TEST_ASSERT_VAL("frontend failed", test_frontend() == 0);
+   TEST_ASSERT_VAL("cache_miss_cycles failed", test_cache_miss_cycles() == 
0);
return 0;
 }
-- 
2.25.4



[PATCH 08/18] perf metric: Rename __metricgroup__add_metric to __add_metric

2020-07-12 Thread Jiri Olsa
Renaming __metricgroup__add_metric to __add_metric
to fit in the current function names.

Signed-off-by: Jiri Olsa 
---
 tools/perf/util/metricgroup.c | 17 ++---
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
index 9a168f3df7a4..f0b0a053bfd2 100644
--- a/tools/perf/util/metricgroup.c
+++ b/tools/perf/util/metricgroup.c
@@ -571,10 +571,10 @@ int __weak arch_get_runtimeparam(void)
return 1;
 }
 
-static int __metricgroup__add_metric(struct list_head *group_list,
-struct pmu_event *pe,
-bool metric_no_group,
-int runtime)
+static int __add_metric(struct list_head *group_list,
+   struct pmu_event *pe,
+   bool metric_no_group,
+   int runtime)
 {
struct egroup *eg;
 
@@ -643,10 +643,7 @@ static int add_metric(struct list_head *group_list,
pr_debug("metric expr %s for %s\n", pe->metric_expr, pe->metric_name);
 
if (!strstr(pe->metric_expr, "?")) {
-   ret = __metricgroup__add_metric(group_list,
-   pe,
-   metric_no_group,
-   1);
+   ret = __add_metric(group_list, pe, metric_no_group, 1);
} else {
int j, count;
 
@@ -658,9 +655,7 @@ static int add_metric(struct list_head *group_list,
 */
 
for (j = 0; j < count && !ret; j++) {
-   ret = __metricgroup__add_metric(
-   group_list, pe,
-   metric_no_group, j);
+   ret = __add_metric(group_list, pe, metric_no_group, j);
}
}
 
-- 
2.25.4



[PATCH 11/18] perf metric: Add referenced metrics to hash data

2020-07-12 Thread Jiri Olsa
Adding referenced metrics to the parsing context so they
can be resolved during the metric processing.

Adding expr__add_ref function to store referenced metrics
into parse context.

Signed-off-by: Jiri Olsa 
---
 tools/perf/util/expr.c| 35 +++
 tools/perf/util/expr.h| 13 -
 tools/perf/util/stat-shadow.c | 20 ++--
 3 files changed, 61 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
index 91142d4c3419..6bf8a21f5c53 100644
--- a/tools/perf/util/expr.c
+++ b/tools/perf/util/expr.c
@@ -4,6 +4,8 @@
 #include 
 #include 
 #include 
+#include "metricgroup.h"
+#include "debug.h"
 #include "expr.h"
 #include "expr-bison.h"
 #include "expr-flex.h"
@@ -61,6 +63,7 @@ int expr__add_id_val(struct expr_parse_ctx *ctx, const char 
*id, double val)
if (!data_ptr)
return -ENOMEM;
data_ptr->val = val;
+   data_ptr->is_ref = false;
 
ret = hashmap__set(&ctx->ids, id, data_ptr,
   (const void **)&old_key, (void **)&old_data);
@@ -69,6 +72,38 @@ int expr__add_id_val(struct expr_parse_ctx *ctx, const char 
*id, double val)
return ret;
 }
 
+int expr__add_ref(struct expr_parse_ctx *ctx, struct metric_ref *ref)
+{
+   struct expr_id_data *data_ptr = NULL, *old_data = NULL;
+   char *old_key = NULL;
+   char *name;
+   int ret;
+
+   data_ptr = zalloc(sizeof(*data_ptr));
+   if (!data_ptr)
+   return -ENOMEM;
+
+   name = strdup(ref->metric_name);
+   if (!name) {
+   free(data_ptr);
+   return -ENOMEM;
+   }
+
+   data_ptr->ref.metric_name = ref->metric_name;
+   data_ptr->ref.metric_expr = ref->metric_expr;
+   data_ptr->is_ref = true;
+
+   ret = hashmap__set(&ctx->ids, name, data_ptr,
+  (const void **)&old_key, (void **)&old_data);
+
+   pr_debug2("adding ref metric %s: %s\n",
+ ref->metric_name, ref->metric_expr);
+
+   free(old_key);
+   free(old_data);
+   return ret;
+}
+
 int expr__get_id(struct expr_parse_ctx *ctx, const char *id,
 struct expr_id_data **data)
 {
diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h
index 2462abd0ac65..d19e66915228 100644
--- a/tools/perf/util/expr.h
+++ b/tools/perf/util/expr.h
@@ -11,12 +11,22 @@
 #include "util/hashmap.h"
 //#endif
 
+struct metric_ref;
+
 struct expr_parse_ctx {
struct hashmap ids;
 };
 
 struct expr_id_data {
-   double  val;
+   boolis_ref;
+
+   union {
+   double  val;
+   struct {
+   const char *metric_name;
+   const char *metric_expr;
+   } ref;
+   };
 };
 
 struct expr_scanner_ctx {
@@ -29,6 +39,7 @@ void expr__ctx_clear(struct expr_parse_ctx *ctx);
 void expr__del_id(struct expr_parse_ctx *ctx, const char *id);
 int expr__add_id(struct expr_parse_ctx *ctx, const char *id);
 int expr__add_id_val(struct expr_parse_ctx *ctx, const char *id, double val);
+int expr__add_ref(struct expr_parse_ctx *ctx, struct metric_ref *ref);
 int expr__get_id(struct expr_parse_ctx *ctx, const char *id,
 struct expr_id_data **data);
 int expr__parse(double *final_val, struct expr_parse_ctx *ctx,
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index fc9ac4b4218e..e1ba6c1b916a 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -731,13 +731,14 @@ static void print_smi_cost(struct perf_stat_config 
*config,
 }
 
 static int prepare_metric(struct evsel **metric_events,
+ struct metric_ref *metric_refs,
  struct expr_parse_ctx *pctx,
  int cpu,
  struct runtime_stat *st)
 {
double scale;
char *n, *pn;
-   int i;
+   int i, j, ret;
 
expr__ctx_init(pctx);
for (i = 0; metric_events[i]; i++) {
@@ -778,12 +779,19 @@ static int prepare_metric(struct evsel **metric_events,
expr__add_id_val(pctx, n, avg_stats(stats)*scale);
}
 
+   for (j = 0; metric_refs && metric_refs[j].metric_name; j++) {
+   ret = expr__add_ref(pctx, &metric_refs[j]);
+   if (ret)
+   return ret;
+   }
+
return i;
 }
 
 static void generic_metric(struct perf_stat_config *config,
   const char *metric_expr,
   struct evsel **metric_events,
+  struct metric_ref *metric_refs,
   char *name,
   const char *metric_name,
   const char *metric_unit,
@@ -798,7 +806,7 @@ static void generic_metric(struct perf_stat_config *config,
int i;
void *ctxp = out->ctx;
 
-   i = prepare_metric(metric_events, &pctx, cpu, st)

[PATCH 10/18] perf metric: Collect referenced metrics in struct metric_expr

2020-07-12 Thread Jiri Olsa
Add referenced metrics into struct metric_expr object,
so they are accessible when computing the metric.

Storing just name and expression itself, so the metric
can be resolved and computed.

Signed-off-by: Jiri Olsa 
---
 tools/perf/util/metricgroup.c | 26 ++
 tools/perf/util/metricgroup.h |  6 ++
 2 files changed, 32 insertions(+)

diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
index 9923eef1e2d4..8cbcc5e05fef 100644
--- a/tools/perf/util/metricgroup.c
+++ b/tools/perf/util/metricgroup.c
@@ -83,6 +83,7 @@ static void metric_event_delete(struct rblist *rblist 
__maybe_unused,
struct metric_expr *expr, *tmp;
 
list_for_each_entry_safe(expr, tmp, &me->head, nd) {
+   free(expr->metric_refs);
free(expr);
}
 
@@ -243,6 +244,7 @@ static int metricgroup__setup_events(struct list_head 
*groups,
 
list_for_each_entry (eg, groups, nd) {
struct evsel **metric_events;
+   struct metric_ref *metric_refs = NULL;
 
metric_events = calloc(sizeof(void *),
hashmap__size(&eg->pctx.ids) + 1);
@@ -274,6 +276,30 @@ static int metricgroup__setup_events(struct list_head 
*groups,
free(metric_events);
break;
}
+
+   /*
+* Collect and store collected nested expressions
+* for metric processing.
+*/
+   if (eg->refs_cnt) {
+   struct metric_ref_node *ref;
+
+   metric_refs = zalloc(sizeof(struct metric_ref) * 
(eg->refs_cnt + 1));
+   if (!metric_refs) {
+   ret = -ENOMEM;
+   free(metric_events);
+   break;
+   }
+
+   i = 0;
+   list_for_each_entry(ref, &eg->refs, list) {
+   metric_refs[i].metric_name = ref->metric_name;
+   metric_refs[i].metric_expr = ref->metric_expr;
+   i++;
+   }
+   };
+
+   expr->metric_refs = metric_refs;
expr->metric_expr = eg->metric_expr;
expr->metric_name = eg->metric_name;
expr->metric_unit = eg->metric_unit;
diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h
index 8315bd1a7da4..62623a39cbec 100644
--- a/tools/perf/util/metricgroup.h
+++ b/tools/perf/util/metricgroup.h
@@ -18,12 +18,18 @@ struct metric_event {
struct list_head head; /* list of metric_expr */
 };
 
+struct metric_ref {
+   const char *metric_name;
+   const char *metric_expr;
+};
+
 struct metric_expr {
struct list_head nd;
const char *metric_expr;
const char *metric_name;
const char *metric_unit;
struct evsel **metric_events;
+   struct metric_ref *metric_refs;
int runtime;
 };
 
-- 
2.25.4



[PATCH 17/18] perf metric: Rename struct egroup to metric

2020-07-12 Thread Jiri Olsa
Renaming struct egroup to metric, because it seems
to make more sense. Plus renaming all the variables
that hold egroup to appropriate names.

Signed-off-by: Jiri Olsa 
---
 tools/perf/util/metricgroup.c | 158 +-
 1 file changed, 79 insertions(+), 79 deletions(-)

diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
index 69ec20dd737b..9b880a5fb52b 100644
--- a/tools/perf/util/metricgroup.c
+++ b/tools/perf/util/metricgroup.c
@@ -112,7 +112,7 @@ struct metric_ref_node {
 
 #define RECURSION_ID_MAX 100
 
-struct egroup {
+struct metric {
struct list_head nd;
struct expr_parse_ctx pctx;
const char *metric_name;
@@ -242,7 +242,7 @@ static int metricgroup__setup_events(struct list_head 
*groups,
struct metric_expr *expr;
int i = 0;
int ret = 0;
-   struct egroup *eg;
+   struct metric *m;
struct evsel *evsel, *tmp;
unsigned long *evlist_used;
 
@@ -250,23 +250,23 @@ static int metricgroup__setup_events(struct list_head 
*groups,
if (!evlist_used)
return -ENOMEM;
 
-   list_for_each_entry (eg, groups, nd) {
+   list_for_each_entry (m, groups, nd) {
struct evsel **metric_events;
struct metric_ref *metric_refs = NULL;
 
metric_events = calloc(sizeof(void *),
-   hashmap__size(&eg->pctx.ids) + 1);
+   hashmap__size(&m->pctx.ids) + 1);
if (!metric_events) {
ret = -ENOMEM;
break;
}
-   evsel = find_evsel_group(perf_evlist, &eg->pctx,
+   evsel = find_evsel_group(perf_evlist, &m->pctx,
 metric_no_merge,
-eg->has_constraint, metric_events,
+m->has_constraint, metric_events,
 evlist_used);
if (!evsel) {
pr_debug("Cannot resolve %s: %s\n",
-   eg->metric_name, eg->metric_expr);
+   m->metric_name, m->metric_expr);
free(metric_events);
continue;
}
@@ -289,10 +289,10 @@ static int metricgroup__setup_events(struct list_head 
*groups,
 * Collect and store collected nested expressions
 * for metric processing.
 */
-   if (eg->refs_cnt) {
+   if (m->refs_cnt) {
struct metric_ref_node *ref;
 
-   metric_refs = zalloc(sizeof(struct metric_ref) * 
(eg->refs_cnt + 1));
+   metric_refs = zalloc(sizeof(struct metric_ref) * 
(m->refs_cnt + 1));
if (!metric_refs) {
ret = -ENOMEM;
free(metric_events);
@@ -300,7 +300,7 @@ static int metricgroup__setup_events(struct list_head 
*groups,
}
 
i = 0;
-   list_for_each_entry(ref, &eg->refs, list) {
+   list_for_each_entry(ref, &m->refs, list) {
metric_refs[i].metric_name = ref->metric_name;
metric_refs[i].metric_expr = ref->metric_expr;
i++;
@@ -308,11 +308,11 @@ static int metricgroup__setup_events(struct list_head 
*groups,
};
 
expr->metric_refs = metric_refs;
-   expr->metric_expr = eg->metric_expr;
-   expr->metric_name = eg->metric_name;
-   expr->metric_unit = eg->metric_unit;
+   expr->metric_expr = m->metric_expr;
+   expr->metric_name = m->metric_name;
+   expr->metric_unit = m->metric_unit;
expr->metric_events = metric_events;
-   expr->runtime = eg->runtime;
+   expr->runtime = m->runtime;
list_add(&expr->nd, &me->head);
}
 
@@ -617,38 +617,38 @@ static int __add_metric(struct list_head *group_list,
struct pmu_event *pe,
bool metric_no_group,
int runtime,
-   struct egroup **egp,
+   struct metric **mp,
struct expr_id *parent)
 {
struct metric_ref_node *ref;
-   struct egroup *eg;
+   struct metric *m;
 
-   if (*egp == NULL) {
+   if (*mp == NULL) {
/*
 * We got in here for the master group,
 * allocate it and put it on the list.
 */
-   eg = zalloc(sizeof(*eg));
-   if (!eg)
+   m = zalloc(sizeof(*m));
+   if (!m)
return -ENOMEM;
 
- 

[PATCH 13/18] perf metric: Add events for the current group

2020-07-12 Thread Jiri Olsa
There's no need to iterate the whole list of groups,
when adding new events. The currently created group
is the one we want to add.

Signed-off-by: Jiri Olsa 
---
 tools/perf/util/metricgroup.c | 22 --
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
index 8cbcc5e05fef..66f25362702d 100644
--- a/tools/perf/util/metricgroup.c
+++ b/tools/perf/util/metricgroup.c
@@ -811,17 +811,19 @@ static int metricgroup__add_metric(const char *metric, 
bool metric_no_group,
if (ret)
return ret;
 
-   list_for_each_entry(eg, group_list, nd) {
-   if (events->len > 0)
-   strbuf_addf(events, ",");
+   if (events->len > 0)
+   strbuf_addf(events, ",");
 
-   if (eg->has_constraint) {
-   metricgroup__add_metric_non_group(events,
- &eg->pctx);
-   } else {
-   metricgroup__add_metric_weak_group(events,
-  &eg->pctx);
-   }
+   /*
+* Even if we add multiple groups through the runtime
+* param, they share same events.
+*/
+   if (eg->has_constraint) {
+   metricgroup__add_metric_non_group(events,
+ &eg->pctx);
+   } else {
+   metricgroup__add_metric_weak_group(events,
+  &eg->pctx);
}
return 0;
 }
-- 
2.25.4



[PATCH 15/18] perf metric: Add DCache_L2 to metric parse test

2020-07-12 Thread Jiri Olsa
Adding test that compute DCache_L2 metrics with other related metrics in it.

Signed-off-by: Jiri Olsa 
---
 tools/perf/tests/parse-metric.c | 71 +
 1 file changed, 71 insertions(+)

diff --git a/tools/perf/tests/parse-metric.c b/tools/perf/tests/parse-metric.c
index 28f33893338b..b50e2a3f3b73 100644
--- a/tools/perf/tests/parse-metric.c
+++ b/tools/perf/tests/parse-metric.c
@@ -36,6 +36,27 @@ static struct pmu_event pme_test[] = {
.metric_expr= "(dcache_miss_cpi + icache_miss_cycles)",
.metric_name= "cache_miss_cycles",
 },
+{
+   .metric_expr= "L2_RQSTS.DEMAND_DATA_RD_HIT + L2_RQSTS.PF_HIT + 
L2_RQSTS.RFO_HIT",
+   .metric_name= "DCache_L2_All_Hits",
+},
+{
+   .metric_expr= "max(L2_RQSTS.ALL_DEMAND_DATA_RD - 
L2_RQSTS.DEMAND_DATA_RD_HIT, 0) + "
+ "L2_RQSTS.PF_MISS + L2_RQSTS.RFO_MISS",
+   .metric_name= "DCache_L2_All_Miss",
+},
+{
+   .metric_expr= "DCache_L2_All_Hits + DCache_L2_All_Miss",
+   .metric_name= "DCache_L2_All",
+},
+{
+   .metric_expr= "d_ratio(DCache_L2_All_Hits, DCache_L2_All)",
+   .metric_name= "DCache_L2_Hits",
+},
+{
+   .metric_expr= "d_ratio(DCache_L2_All_Miss, DCache_L2_All)",
+   .metric_name= "DCache_L2_Misses",
+},
 };
 
 static struct pmu_events_map map = {
@@ -194,10 +215,60 @@ static int test_cache_miss_cycles(void)
return 0;
 }
 
+
+/*
+ * DCache_L2_All_Hits = L2_RQSTS.DEMAND_DATA_RD_HIT + L2_RQSTS.PF_HIT + 
L2_RQSTS.RFO_HI
+ * DCache_L2_All_Miss = MAX(L2_RQSTS.ALL_DEMAND_DATA_RD - 
L2_RQSTS.DEMAND_DATA_RD_HIT, 0) +
+ *  L2_RQSTS.PF_MISS + L2_RQSTS.RFO_MISS
+ * DCache_L2_All  = DCache_L2_All_Hits + DCache_L2_All_Miss
+ * DCache_L2_Hits = d_ratio(DCache_L2_All_Hits, DCache_L2_All)
+ * DCache_L2_Misses   = d_ratio(DCache_L2_All_Miss, DCache_L2_All)
+ *
+ * L2_RQSTS.DEMAND_DATA_RD_HIT = 100
+ * L2_RQSTS.PF_HIT = 200
+ * L2_RQSTS.RFO_HI = 300
+ * L2_RQSTS.ALL_DEMAND_DATA_RD = 400
+ * L2_RQSTS.PF_MISS= 500
+ * L2_RQSTS.RFO_MISS   = 600
+ *
+ * DCache_L2_All_Hits = 600
+ * DCache_L2_All_Miss = MAX(400 - 100, 0) + 500 + 600 = 1400
+ * DCache_L2_All  = 600 + 1400  = 2000
+ * DCache_L2_Hits = 600 / 2000  = 0.3
+ * DCache_L2_Misses   = 1400 / 2000 = 0.7
+ */
+static int test_dcache_l2(void)
+{
+   double ratio;
+   struct value vals[] = {
+   { .event = "L2_RQSTS.DEMAND_DATA_RD_HIT", .val = 100 },
+   { .event = "L2_RQSTS.PF_HIT", .val = 200 },
+   { .event = "L2_RQSTS.RFO_HIT",.val = 300 },
+   { .event = "L2_RQSTS.ALL_DEMAND_DATA_RD", .val = 400 },
+   { .event = "L2_RQSTS.PF_MISS",.val = 500 },
+   { .event = "L2_RQSTS.RFO_MISS",   .val = 600 },
+   { 0 },
+   };
+
+   TEST_ASSERT_VAL("failed to compute metric",
+   compute_metric("DCache_L2_Hits", vals, &ratio) == 0);
+
+   TEST_ASSERT_VAL("DCache_L2_Hits failed, wrong ratio",
+   ratio == 0.3);
+
+   TEST_ASSERT_VAL("failed to compute metric",
+   compute_metric("DCache_L2_Misses", vals, &ratio) == 0);
+
+   TEST_ASSERT_VAL("DCache_L2_Misses failed, wrong ratio",
+   ratio == 0.7);
+   return 0;
+}
+
 int test__parse_metric(struct test *test __maybe_unused, int subtest 
__maybe_unused)
 {
TEST_ASSERT_VAL("IPC failed", test_ipc() == 0);
TEST_ASSERT_VAL("frontend failed", test_frontend() == 0);
TEST_ASSERT_VAL("cache_miss_cycles failed", test_cache_miss_cycles() == 
0);
+   TEST_ASSERT_VAL("DCache_L2 failed", test_dcache_l2() == 0);
return 0;
 }
-- 
2.25.4



[PATCH 16/18] perf metric: Add recursion check when processing nested metrics

2020-07-12 Thread Jiri Olsa
Keeping the stack of nested metrics via 'struct expr_id' objecs
and checking if we are in recursion via already processed metric.

The stack is implemented as static array within the struct egroup
with 100 entries, which should be enough nesting depth for any
metric we have or plan to have at the moment.

Adding test that simulates the recursion and checks we can
detect it.

Signed-off-by: Jiri Olsa 
---
 tools/perf/tests/parse-metric.c |  27 -
 tools/perf/util/expr.c  |   2 +
 tools/perf/util/expr.h  |   9 ++-
 tools/perf/util/metricgroup.c   | 101 +---
 4 files changed, 128 insertions(+), 11 deletions(-)

diff --git a/tools/perf/tests/parse-metric.c b/tools/perf/tests/parse-metric.c
index b50e2a3f3b73..238a805edd55 100644
--- a/tools/perf/tests/parse-metric.c
+++ b/tools/perf/tests/parse-metric.c
@@ -57,6 +57,14 @@ static struct pmu_event pme_test[] = {
.metric_expr= "d_ratio(DCache_L2_All_Miss, DCache_L2_All)",
.metric_name= "DCache_L2_Misses",
 },
+{
+   .metric_expr= "IPC + M2",
+   .metric_name= "M1",
+},
+{
+   .metric_expr= "IPC + M1",
+   .metric_name= "M2",
+},
 };
 
 static struct pmu_events_map map = {
@@ -139,8 +147,8 @@ static int compute_metric(const char *name, struct value 
*vals, double *ratio)
err = metricgroup__parse_groups_test(evlist, &map, name,
 false, false,
 &metric_events);
-
-   TEST_ASSERT_VAL("failed to parse metric", err == 0);
+   if (err)
+   return err;
 
if (perf_evlist__alloc_stats(evlist, false))
return -1;
@@ -264,11 +272,26 @@ static int test_dcache_l2(void)
return 0;
 }
 
+static int test_recursion_fail(void)
+{
+   double ratio;
+   struct value vals[] = {
+   { .event = "inst_retired.any",.val = 300 },
+   { .event = "cpu_clk_unhalted.thread", .val = 200 },
+   { 0 },
+   };
+
+   TEST_ASSERT_VAL("failed to find recursion",
+   compute_metric("M1", vals, &ratio) == -1);
+   return 0;
+}
+
 int test__parse_metric(struct test *test __maybe_unused, int subtest 
__maybe_unused)
 {
TEST_ASSERT_VAL("IPC failed", test_ipc() == 0);
TEST_ASSERT_VAL("frontend failed", test_frontend() == 0);
TEST_ASSERT_VAL("cache_miss_cycles failed", test_cache_miss_cycles() == 
0);
TEST_ASSERT_VAL("DCache_L2 failed", test_dcache_l2() == 0);
+   TEST_ASSERT_VAL("recursion fail failed", test_recursion_fail() == 0);
return 0;
 }
diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
index 2784df38f8c2..d23d8897bc61 100644
--- a/tools/perf/util/expr.c
+++ b/tools/perf/util/expr.c
@@ -45,6 +45,8 @@ int expr__add_id(struct expr_parse_ctx *ctx, const char *id)
if (!data_ptr)
return -ENOMEM;
 
+   data_ptr->parent = ctx->parent;
+
ret = hashmap__set(&ctx->ids, id, data_ptr,
   (const void **)&old_key, (void **)&old_data);
free(old_key);
diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h
index b6d1fba64eaa..e5fdeab928c7 100644
--- a/tools/perf/util/expr.h
+++ b/tools/perf/util/expr.h
@@ -13,8 +13,14 @@
 
 struct metric_ref;
 
+struct expr_id {
+   char*id;
+   struct expr_id  *parent;
+};
+
 struct expr_parse_ctx {
-   struct hashmap ids;
+   struct hashmap   ids;
+   struct expr_id  *parent;
 };
 
 struct expr_id_data {
@@ -27,6 +33,7 @@ struct expr_id_data {
const char *metric_expr;
bool counted;
} ref;
+   struct expr_id  *parent;
};
 };
 
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
index 66f25362702d..69ec20dd737b 100644
--- a/tools/perf/util/metricgroup.c
+++ b/tools/perf/util/metricgroup.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include "util.h"
+#include 
 
 struct metric_event *metricgroup__lookup(struct rblist *metric_events,
 struct evsel *evsel,
@@ -109,6 +110,8 @@ struct metric_ref_node {
struct list_head list;
 };
 
+#define RECURSION_ID_MAX 100
+
 struct egroup {
struct list_head nd;
struct expr_parse_ctx pctx;
@@ -119,6 +122,11 @@ struct egroup {
int refs_cnt;
int runtime;
bool has_constraint;
+
+   struct {
+   struct expr_id  id[RECURSION_ID_MAX];
+   int cnt;
+   } recursion;
 };
 
 /**
@@ -609,7 +617,8 @@ static int __add_metric(struct list_head *group_list,
struct pmu_event *pe,
bool metric_no_group,
int runtime,
-   struct egroup **egp)
+   struct egroup **egp,
+   struct expr_id *parent)
 {
struct metric_r

[PATCH 04/18] perf metric: Change expr__get_id to return struct expr_id_data

2020-07-12 Thread Jiri Olsa
Changing expr__get_id to use and return struct expr_id_data
pointer as value for the ID. This way we can access data other
than value for given ID in following changes.

Acked-by: Ian Rogers 
Signed-off-by: Jiri Olsa 
---
 tools/perf/util/expr.c | 10 +++---
 tools/perf/util/expr.h |  3 ++-
 tools/perf/util/expr.y | 14 +-
 3 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
index 4b8953605aed..7d02d29286bc 100644
--- a/tools/perf/util/expr.c
+++ b/tools/perf/util/expr.c
@@ -69,14 +69,10 @@ int expr__add_id_val(struct expr_parse_ctx *ctx, const char 
*id, double val)
return ret;
 }
 
-int expr__get_id(struct expr_parse_ctx *ctx, const char *id, double *val_ptr)
+int expr__get_id(struct expr_parse_ctx *ctx, const char *id,
+struct expr_id_data **data)
 {
-   struct expr_id_data *data;
-
-   if (!hashmap__find(&ctx->ids, id, (void **)&data))
-   return -1;
-   *val_ptr = (data == NULL) ?  0.0 : data->val;
-   return 0;
+   return hashmap__find(&ctx->ids, id, (void **)data) ? 0 : -1;
 }
 
 void expr__ctx_init(struct expr_parse_ctx *ctx)
diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h
index ac32cda42006..f38292fdab19 100644
--- a/tools/perf/util/expr.h
+++ b/tools/perf/util/expr.h
@@ -28,7 +28,8 @@ void expr__ctx_init(struct expr_parse_ctx *ctx);
 void expr__ctx_clear(struct expr_parse_ctx *ctx);
 int expr__add_id(struct expr_parse_ctx *ctx, const char *id);
 int expr__add_id_val(struct expr_parse_ctx *ctx, const char *id, double val);
-int expr__get_id(struct expr_parse_ctx *ctx, const char *id, double *val_ptr);
+int expr__get_id(struct expr_parse_ctx *ctx, const char *id,
+struct expr_id_data **data);
 int expr__parse(double *final_val, struct expr_parse_ctx *ctx,
const char *expr, int runtime);
 int expr__find_other(const char *expr, const char *one,
diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y
index 8befe4a46f87..0d4f5d324be7 100644
--- a/tools/perf/util/expr.y
+++ b/tools/perf/util/expr.y
@@ -85,12 +85,16 @@ if_expr:
;
 
 expr:NUMBER
-   | ID{ if (expr__get_id(ctx, $1, &$$)) {
-   pr_debug("%s not found\n", $1);
+   | ID{
+   struct expr_id_data *data;
+
+   if (expr__get_id(ctx, $1, &data) || 
!data) {
+   pr_debug("%s not found\n", $1);
+   free($1);
+   YYABORT;
+   }
+   $$ = data->val;
free($1);
-   YYABORT;
- }
- free($1);
}
| expr '|' expr { $$ = (long)$1 | (long)$3; }
| expr '&' expr { $$ = (long)$1 & (long)$3; }
-- 
2.25.4



[PATCH 07/18] perf metric: Add add_metric function

2020-07-12 Thread Jiri Olsa
Decouple metric adding login into add_metric function,
so it can be used from other places in following changes.

Signed-off-by: Jiri Olsa 
---
 tools/perf/util/metricgroup.c | 42 ++-
 1 file changed, 26 insertions(+), 16 deletions(-)

diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
index 72552608ff7d..9a168f3df7a4 100644
--- a/tools/perf/util/metricgroup.c
+++ b/tools/perf/util/metricgroup.c
@@ -634,18 +634,11 @@ static struct pmu_event *find_metric(const char *metric, 
struct pmu_events_map *
return NULL;
 }
 
-static int metricgroup__add_metric(const char *metric, bool metric_no_group,
-  struct strbuf *events,
-  struct list_head *group_list,
-  struct pmu_events_map *map)
+static int add_metric(struct list_head *group_list,
+ struct pmu_event *pe,
+ bool metric_no_group)
 {
-   struct pmu_event *pe;
-   struct egroup *eg;
-   int ret;
-
-   pe = find_metric(metric, map);
-   if (!pe)
-   return -EINVAL;
+   int ret = 0;
 
pr_debug("metric expr %s for %s\n", pe->metric_expr, pe->metric_name);
 
@@ -654,8 +647,6 @@ static int metricgroup__add_metric(const char *metric, bool 
metric_no_group,
pe,
metric_no_group,
1);
-   if (ret)
-   return ret;
} else {
int j, count;
 
@@ -666,14 +657,33 @@ static int metricgroup__add_metric(const char *metric, 
bool metric_no_group,
 * those events to group_list.
 */
 
-   for (j = 0; j < count; j++) {
+   for (j = 0; j < count && !ret; j++) {
ret = __metricgroup__add_metric(
group_list, pe,
metric_no_group, j);
-   if (ret)
-   return ret;
}
}
+
+   return ret;
+}
+
+static int metricgroup__add_metric(const char *metric, bool metric_no_group,
+  struct strbuf *events,
+  struct list_head *group_list,
+  struct pmu_events_map *map)
+{
+   struct pmu_event *pe;
+   struct egroup *eg;
+   int ret;
+
+   pe = find_metric(metric, map);
+   if (!pe)
+   return -EINVAL;
+
+   ret = add_metric(group_list, pe, metric_no_group);
+   if (ret)
+   return ret;
+
list_for_each_entry(eg, group_list, nd) {
if (events->len > 0)
strbuf_addf(events, ",");
-- 
2.25.4



[PATCH 12/18] perf metric: Compute referenced metrics

2020-07-12 Thread Jiri Olsa
Adding computation (expr__parse call) of referenced metric at
the point when it needs to be resolved during the 'master'
metric computation.

Once the inner metric is computed, the result is stored and
used if there's another usage of that metric.

Signed-off-by: Jiri Olsa 
---
 tools/perf/util/expr.c | 31 +++
 tools/perf/util/expr.h |  3 +++
 tools/perf/util/expr.y |  4 ++--
 3 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
index 6bf8a21f5c53..2784df38f8c2 100644
--- a/tools/perf/util/expr.c
+++ b/tools/perf/util/expr.c
@@ -91,6 +91,7 @@ int expr__add_ref(struct expr_parse_ctx *ctx, struct 
metric_ref *ref)
 
data_ptr->ref.metric_name = ref->metric_name;
data_ptr->ref.metric_expr = ref->metric_expr;
+   data_ptr->ref.counted = false;
data_ptr->is_ref = true;
 
ret = hashmap__set(&ctx->ids, name, data_ptr,
@@ -110,6 +111,34 @@ int expr__get_id(struct expr_parse_ctx *ctx, const char 
*id,
return hashmap__find(&ctx->ids, id, (void **)data) ? 0 : -1;
 }
 
+int expr__resolve_id(struct expr_parse_ctx *ctx, const char *id,
+struct expr_id_data **datap)
+{
+   struct expr_id_data *data;
+
+   if (expr__get_id(ctx, id, datap) || !*datap) {
+   pr_debug("%s not found\n", id);
+   return -1;
+   }
+
+   data = *datap;
+
+   pr_debug2("lookup: is_ref %d, counted %d, val %f: %s\n",
+ data->is_ref, data->ref.counted, data->val, id);
+
+   if (data->is_ref && !data->ref.counted) {
+   data->ref.counted = true;
+   pr_debug("processing metric: %s ENTRY\n", id);
+   if (expr__parse(&data->val, ctx, data->ref.metric_expr, 1)) {
+   pr_debug("%s failed to count\n", id);
+   return -1;
+   }
+   pr_debug("processing metric: %s EXIT: %f\n", id, data->val);
+   }
+
+   return 0;
+}
+
 void expr__del_id(struct expr_parse_ctx *ctx, const char *id)
 {
struct expr_id_data *old_val = NULL;
@@ -150,6 +179,8 @@ __expr__parse(double *val, struct expr_parse_ctx *ctx, 
const char *expr,
void *scanner;
int ret;
 
+   pr_debug2("parsing metric: %s\n", expr);
+
ret = expr_lex_init_extra(&scanner_ctx, &scanner);
if (ret)
return ret;
diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h
index d19e66915228..b6d1fba64eaa 100644
--- a/tools/perf/util/expr.h
+++ b/tools/perf/util/expr.h
@@ -25,6 +25,7 @@ struct expr_id_data {
struct {
const char *metric_name;
const char *metric_expr;
+   bool counted;
} ref;
};
 };
@@ -42,6 +43,8 @@ int expr__add_id_val(struct expr_parse_ctx *ctx, const char 
*id, double val);
 int expr__add_ref(struct expr_parse_ctx *ctx, struct metric_ref *ref);
 int expr__get_id(struct expr_parse_ctx *ctx, const char *id,
 struct expr_id_data **data);
+int expr__resolve_id(struct expr_parse_ctx *ctx, const char *id,
+struct expr_id_data **datap);
 int expr__parse(double *final_val, struct expr_parse_ctx *ctx,
const char *expr, int runtime);
 int expr__find_other(const char *expr, const char *one,
diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y
index 0d4f5d324be7..d34b370391c6 100644
--- a/tools/perf/util/expr.y
+++ b/tools/perf/util/expr.y
@@ -88,11 +88,11 @@ expr: NUMBER
| ID{
struct expr_id_data *data;
 
-   if (expr__get_id(ctx, $1, &data) || 
!data) {
-   pr_debug("%s not found\n", $1);
+   if (expr__resolve_id(ctx, $1, &data)) {
free($1);
YYABORT;
}
+
$$ = data->val;
free($1);
}
-- 
2.25.4



[PATCH 09/18] perf metric: Collect referenced metrics in struct metric_ref_node

2020-07-12 Thread Jiri Olsa
Collecting referenced metrics in struct metric_ref_node object,
so we can process them later on.

The change will parse nested metric names out of expression and
'resolve' them.

All referenced metrics are dissolved into one context, meaning all
nested metrics events and added to the parent context.

Signed-off-by: Jiri Olsa 
---
 tools/perf/util/metricgroup.c | 147 ++
 1 file changed, 132 insertions(+), 15 deletions(-)

diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
index f0b0a053bfd2..9923eef1e2d4 100644
--- a/tools/perf/util/metricgroup.c
+++ b/tools/perf/util/metricgroup.c
@@ -102,12 +102,20 @@ void metricgroup__rblist_exit(struct rblist 
*metric_events)
rblist__exit(metric_events);
 }
 
+struct metric_ref_node {
+   const char *metric_name;
+   const char *metric_expr;
+   struct list_head list;
+};
+
 struct egroup {
struct list_head nd;
struct expr_parse_ctx pctx;
const char *metric_name;
const char *metric_expr;
const char *metric_unit;
+   struct list_head refs;
+   int refs_cnt;
int runtime;
bool has_constraint;
 };
@@ -574,27 +582,66 @@ int __weak arch_get_runtimeparam(void)
 static int __add_metric(struct list_head *group_list,
struct pmu_event *pe,
bool metric_no_group,
-   int runtime)
+   int runtime,
+   struct egroup **egp)
 {
+   struct metric_ref_node *ref;
struct egroup *eg;
 
-   eg = malloc(sizeof(*eg));
-   if (!eg)
-   return -ENOMEM;
+   if (*egp == NULL) {
+   /*
+* We got in here for the master group,
+* allocate it and put it on the list.
+*/
+   eg = malloc(sizeof(*eg));
+   if (!eg)
+   return -ENOMEM;
+
+   expr__ctx_init(&eg->pctx);
+   eg->metric_name = pe->metric_name;
+   eg->metric_expr = pe->metric_expr;
+   eg->metric_unit = pe->unit;
+   eg->runtime = runtime;
+   eg->has_constraint = metric_no_group || 
metricgroup__has_constraint(pe);
+   INIT_LIST_HEAD(&eg->refs);
+   eg->refs_cnt = 0;
+   *egp = eg;
+   } else {
+   /*
+* We got here for the referenced metric, via the
+* recursive metricgroup__add_metric call, add
+* it to the master group.
+*/
+   eg = *egp;
+
+   ref = malloc(sizeof(*ref));
+   if (!ref)
+   return -ENOMEM;
 
-   expr__ctx_init(&eg->pctx);
-   eg->metric_name = pe->metric_name;
-   eg->metric_expr = pe->metric_expr;
-   eg->metric_unit = pe->unit;
-   eg->runtime = runtime;
-   eg->has_constraint = metric_no_group || metricgroup__has_constraint(pe);
+   ref->metric_name = pe->metric_name;
+   ref->metric_expr = pe->metric_expr;
+   list_add(&ref->list, &eg->refs);
+   eg->refs_cnt++;
+   eg->has_constraint |= metricgroup__has_constraint(pe);
+   }
 
+   /*
+* For both the master and referenced metrics, we parse
+* all the metric's IDs and add it to the parent context.
+*/
if (expr__find_other(pe->metric_expr, NULL, &eg->pctx, runtime) < 0) {
expr__ctx_clear(&eg->pctx);
free(eg);
return -EINVAL;
}
 
+   /*
+* We add new group only in the 'master' call,
+* so bail out for referenced metric case.
+*/
+   if (eg->refs_cnt)
+   return 0;
+
if (list_empty(group_list))
list_add(&eg->nd, group_list);
else {
@@ -636,14 +683,63 @@ static struct pmu_event *find_metric(const char *metric, 
struct pmu_events_map *
 
 static int add_metric(struct list_head *group_list,
  struct pmu_event *pe,
- bool metric_no_group)
+ bool metric_no_group,
+ struct egroup **egp);
+
+static int resolve_metric(struct egroup *eg,
+ bool metric_no_group,
+ struct list_head *group_list,
+ struct pmu_events_map *map)
+{
+   struct hashmap_entry *cur;
+   size_t bkt;
+   bool all;
+   int ret;
+
+   /*
+* Iterate all the parsed IDs and if there's metric,
+* add it to the context.
+*/
+   do {
+   all = true;
+   hashmap__for_each_entry((&eg->pctx.ids), cur, bkt) {
+   struct pmu_event *pe;
+
+   pe = find_metric(cur->key, map);
+   if (!pe)
+   continue;
+
+   all = false;
+

[PATCH 18/18] perf metric: Rename group_list to list

2020-07-12 Thread Jiri Olsa
Following the previous change that rename egroup
to metric, there's no reason to call the list
'group_list' anymore, renaming it to list.

Signed-off-by: Jiri Olsa 
---
 tools/perf/util/metricgroup.c | 45 +--
 1 file changed, 22 insertions(+), 23 deletions(-)

diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
index 9b880a5fb52b..0645ac1031fe 100644
--- a/tools/perf/util/metricgroup.c
+++ b/tools/perf/util/metricgroup.c
@@ -613,7 +613,7 @@ int __weak arch_get_runtimeparam(void)
return 1;
 }
 
-static int __add_metric(struct list_head *group_list,
+static int __add_metric(struct list_head *list,
struct pmu_event *pe,
bool metric_no_group,
int runtime,
@@ -691,13 +691,13 @@ static int __add_metric(struct list_head *group_list,
if (m->refs_cnt)
return 0;
 
-   if (list_empty(group_list))
-   list_add(&m->nd, group_list);
+   if (list_empty(list))
+   list_add(&m->nd, list);
else {
struct list_head *pos;
 
/* Place the largest groups at the front. */
-   list_for_each_prev(pos, group_list) {
+   list_for_each_prev(pos, list) {
struct metric *old = list_entry(pos, struct metric, nd);
 
if (hashmap__size(&m->pctx.ids) <=
@@ -775,7 +775,7 @@ static int recursion_check(struct metric *m, const char 
*id, struct expr_id **pa
return p->id ? 0 : -ENOMEM;
 }
 
-static int add_metric(struct list_head *group_list,
+static int add_metric(struct list_head *list,
  struct pmu_event *pe,
  bool metric_no_group,
  struct metric **mp,
@@ -783,7 +783,7 @@ static int add_metric(struct list_head *group_list,
 
 static int resolve_metric(struct metric *m,
  bool metric_no_group,
- struct list_head *group_list,
+ struct list_head *list,
  struct pmu_events_map *map)
 {
struct hashmap_entry *cur;
@@ -814,7 +814,7 @@ static int resolve_metric(struct metric *m,
expr__del_id(&m->pctx, cur->key);
 
/* ... and it gets resolved to the parent context. */
-   ret = add_metric(group_list, pe, metric_no_group, &m, 
parent);
+   ret = add_metric(list, pe, metric_no_group, &m, parent);
if (ret)
return ret;
 
@@ -829,7 +829,7 @@ static int resolve_metric(struct metric *m,
return 0;
 }
 
-static int add_metric(struct list_head *group_list,
+static int add_metric(struct list_head *list,
  struct pmu_event *pe,
  bool metric_no_group,
  struct metric **m,
@@ -840,7 +840,7 @@ static int add_metric(struct list_head *group_list,
pr_debug("metric expr %s for %s\n", pe->metric_expr, pe->metric_name);
 
if (!strstr(pe->metric_expr, "?")) {
-   ret = __add_metric(group_list, pe, metric_no_group, 1, m, 
parent);
+   ret = __add_metric(list, pe, metric_no_group, 1, m, parent);
} else {
int j, count;
 
@@ -848,11 +848,11 @@ static int add_metric(struct list_head *group_list,
 
/* This loop is added to create multiple
 * events depend on count value and add
-* those events to group_list.
+* those events to list.
 */
 
for (j = 0; j < count && !ret; j++) {
-   ret = __add_metric(group_list, pe, metric_no_group, j, 
m, parent);
+   ret = __add_metric(list, pe, metric_no_group, j, m, 
parent);
}
}
 
@@ -861,7 +861,7 @@ static int add_metric(struct list_head *group_list,
 
 static int metricgroup__add_metric(const char *metric, bool metric_no_group,
   struct strbuf *events,
-  struct list_head *group_list,
+  struct list_head *list,
   struct pmu_events_map *map)
 
 {
@@ -873,7 +873,7 @@ static int metricgroup__add_metric(const char *metric, bool 
metric_no_group,
if (!pe)
return -EINVAL;
 
-   ret = add_metric(group_list, pe, metric_no_group, &m, NULL);
+   ret = add_metric(list, pe, metric_no_group, &m, NULL);
if (ret)
return ret;
 
@@ -881,8 +881,7 @@ static int metricgroup__add_metric(const char *metric, bool 
metric_no_group,
 * Process any possible referenced metrics
 * included in the expression.
 */
-   ret = resolve_metric(m, metric_no_group,
-group_list, map);
+   ret = resolve_metric(m, metric_no_group, list, map);
  

  1   2   3   4   5   6   >