Re: [PATCH] arch/powerpc: Use dma_zalloc_coherent

2018-11-16 Thread Souptick Joarder
Hi Joe,

On Fri, Nov 16, 2018 at 12:55 AM Joe Perches  wrote:
>
> On Thu, 2018-11-15 at 23:29 +0530, Sabyasachi Gupta wrote:
> > On Mon, Nov 5, 2018 at 8:58 AM Sabyasachi Gupta
> >  wrote:
> > > Replaced dma_alloc_coherent + memset with dma_zalloc_coherent
> > >
> > > Signed-off-by: Sabyasachi Gupta 
> >
> > Any comment on this patch?
>
> It's obviously correct.
>
> You might realign the arguments on the next lines
> to the open parenthesis.
>
> Perhaps there should be new function calls
> added for symmetry to the other alloc functions
> for multiplication overflow protection.
>
> Perhaps:
>
> void *dma_alloc_array_coherent()
> void *dma_calloc_coherent()
>
> Something like
> ---
>  include/linux/dma-mapping.h | 19 +++
>  1 file changed, 19 insertions(+)
>
> diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
> index 15bd41447025..95bebf8883b1 100644
> --- a/include/linux/dma-mapping.h
> +++ b/include/linux/dma-mapping.h
> @@ -565,6 +565,25 @@ static inline void *dma_alloc_coherent(struct device 
> *dev, size_t size,
> (gfp & __GFP_NOWARN) ? DMA_ATTR_NO_WARN : 0);
>  }
>
> +static inline void *dma_alloc_array_coherent(struct device *dev,
> +size_t n, size_t size,
> +dma_addr_t *dma_handle, gfp_t 
> gfp)
> +{
> +   size_t bytes;
> +
> +   if (unlikely(check_mul_overflow(n, size, )))
> +   return NULL;
> +   return dma_alloc_coherent(dev, bytes, dma_handle, gfp);
> +}
> +
> +static inline void *dma_calloc_coherent(struct device *dev,
> +   size_t n, size_t size,
> +   dma_addr_t *dma_handle, gfp_t gfp)
> +{
> +   return dma_alloc_array_coherent(dev, n, size, dma_handle,
> +   gfp | __GFP_ZERO);
> +}
> +

If I understood correctly, you are talking about adding these 2 new inline
functions. We can do that.

Can you please help to understand the consumers of these 2 new inline ?

>  static inline void dma_free_coherent(struct device *dev, size_t size,
> void *cpu_addr, dma_addr_t dma_handle)
>  {
>
> ---
> > > diff --git a/arch/powerpc/platforms/pasemi/dma_lib.c 
> > > b/arch/powerpc/platforms/pasemi/dma_lib.c
> []
> > > @@ -255,15 +255,13 @@ int pasemi_dma_alloc_ring(struct pasemi_dmachan 
> > > *chan, int ring_size)
> > >
> > > chan->ring_size = ring_size;
> > >
> > > -   chan->ring_virt = dma_alloc_coherent(_pdev->dev,
> > > +   chan->ring_virt = dma_zalloc_coherent(_pdev->dev,
> > >  ring_size * sizeof(u64),
> > >  >ring_dma, GFP_KERNEL);
> > >  en
> > > if (!chan->ring_virt)
> > > return -ENOMEM;
> > >
> > > -   memset(chan->ring_virt, 0, ring_size * sizeof(u64));
> > > -
> > > return 0;
> > >  }
> > >  EXPORT_SYMBOL(pasemi_dma_alloc_ring);
>
>


Re: [GIT PULL] Please pull powerpc/linux.git powerpc-4.20-3 tag

2018-11-16 Thread pr-tracker-bot
The pull request you sent on Fri, 16 Nov 2018 23:01:02 +1100:

> https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git 
> tags/powerpc-4.20-3

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

Thank you!

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


Re: [PATCH net-next 0/6] Remove VLAN.CFI overload

2018-11-16 Thread David Miller
From: Alexei Starovoitov 
Date: Fri, 16 Nov 2018 19:51:55 -0800

> Michal, could you please explain the reasoning?

By treating VLAN.CFI specially as "VLAN TAG PRESENT" we prevent
the usage of certain VLAN ID encodings.

So he's trying to get rid of VLAN_TAG_PRESENT completely and this
was the final patch series necessary to accomplish that.


Re: [PATCH net-next 0/6] Remove VLAN.CFI overload

2018-11-16 Thread Alexei Starovoitov
On Sat, Nov 10, 2018 at 1:48 PM David Miller  wrote:
>
> From: Michał Mirosław 
> Date: Sat, 10 Nov 2018 19:58:29 +0100
>
> > Fix BPF code/JITs to allow for separate VLAN_PRESENT flag
> > storage and finally move the flag to separate storage in skbuff.
> >
> > This is final step to make CLAN.CFI transparent to core Linux
> > networking stack.
> >
> > An #ifdef is introduced temporarily to mark fragments masking
> > VLAN_TAG_PRESENT. This is removed altogether in the final patch.
>
> Daniel and Alexei, please review.

It was on my todo list.
All reviews got delayed due to LPC.

I guess too late to comment now.
Anyhow I don't see the value in this patch set.
Seems like code churn.

Michal, could you please explain the reasoning?


Re: [PATCH v2 2/2] dpaa_eth: add ethtool coalesce control

2018-11-16 Thread David Miller
From: Madalin Bucur 
Date: Tue, 13 Nov 2018 18:29:51 +0200

> + for_each_cpu(cpu, cpus) {
> + portal = qman_get_affine_portal(cpu);
> + res = qman_portal_set_iperiod(portal, period);
> + if (res)
> + return res;
> + res = qman_dqrr_set_ithresh(portal, thresh);
> + if (res)
> + return res;

Nope, you can't do it like this.

If any intermediate change fails, you have to unwind all of the
changes made up until that point.

Which means you'll have to store the previous setting somewhere
and reinstall those saved values in the error path.


Re: [PATCH net-next 0/6] Remove VLAN.CFI overload

2018-11-16 Thread David Miller
From: Michał Mirosław 
Date: Sat, 10 Nov 2018 19:58:29 +0100

> Fix BPF code/JITs to allow for separate VLAN_PRESENT flag
> storage and finally move the flag to separate storage in skbuff.
> 
> This is final step to make CLAN.CFI transparent to core Linux
> networking stack.
> 
> An #ifdef is introduced temporarily to mark fragments masking
> VLAN_TAG_PRESENT. This is removed altogether in the final patch.

Series applied, thank you.


Re: Unexpectedly dma_ops is NULL in struct device

2018-11-16 Thread Logan Gunthorpe



On 15/11/18 03:05 AM, Alexander Fomichev wrote:
> This issue makes functions dma_set_mask() and dma_set_coherent_mask() and 
> dma_alloc_coherent() fail in ntb_hw_switchtec. And the driver can't start on 
> powerpc.

I don't know a lot about powerpc in this area, but a quick peek shows
that dma_set_mask() does some platform specific stuff so it would
definitely help if you can let us know more about your hardware.

On one platform I looked at, it seems that dma_set_mask() sets the
dma_ops for the device, so the fact that it is NULL at that point is not
likely the issue. It's probably some platform specific bug that's
causing this.

Logan


[PATCH] ALSA: aoa: Use device_type helpers to access the node type

2018-11-16 Thread Rob Herring
Remove directly accessing device_node.type pointer and use the accessors
instead. This will eventually allow removing the type pointer.

Replace the open coded iterating over child nodes with
for_each_child_of_node() while we're here.

Cc: Johannes Berg 
Cc: Jaroslav Kysela 
Cc: Takashi Iwai 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: alsa-de...@alsa-project.org
Signed-off-by: Rob Herring 
---
 sound/aoa/fabrics/layout.c | 4 ++--
 sound/aoa/soundbus/core.c  | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/sound/aoa/fabrics/layout.c b/sound/aoa/fabrics/layout.c
index 1eddf8fa188f..3a23fd032611 100644
--- a/sound/aoa/fabrics/layout.c
+++ b/sound/aoa/fabrics/layout.c
@@ -1008,8 +1008,8 @@ static int aoa_fabric_layout_probe(struct soundbus_dev 
*sdev)
return -ENODEV;
 
/* by breaking out we keep a reference */
-   while ((sound = of_get_next_child(sdev->ofdev.dev.of_node, sound))) {
-   if (sound->type && strcasecmp(sound->type, "soundchip") == 0)
+   for_each_child_of_node(sdev->ofdev.dev.of_node, sound) {
+   if (of_node_is_type(sound, "soundchip"))
break;
}
if (!sound)
diff --git a/sound/aoa/soundbus/core.c b/sound/aoa/soundbus/core.c
index 70bcaa7f93dd..f3076a3f7f2f 100644
--- a/sound/aoa/soundbus/core.c
+++ b/sound/aoa/soundbus/core.c
@@ -78,7 +78,7 @@ static int soundbus_uevent(struct device *dev, struct 
kobj_uevent_env *env)
if (retval)
return retval;
 
-   retval = add_uevent_var(env, "OF_TYPE=%s", of->dev.of_node->type);
+   retval = add_uevent_var(env, "OF_TYPE=%s", 
of_node_get_device_type(of->dev.of_node));
if (retval)
return retval;
 
-- 
2.19.1



[PATCH] misc: cxl: Use device_type helpers to access the node type

2018-11-16 Thread Rob Herring
Remove directly accessing device_node.type pointer and use the accessors
instead. This will eventually allow removing the type pointer.

Cc: Frederic Barrat 
Cc: Andrew Donnellan 
Cc: Arnd Bergmann 
Cc: Greg Kroah-Hartman 
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Rob Herring 
---
 drivers/misc/cxl/pci.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index b66d832d3233..c79ba1c699ad 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -1718,7 +1718,6 @@ int cxl_slot_is_switched(struct pci_dev *dev)
 {
struct device_node *np;
int depth = 0;
-   const __be32 *prop;
 
if (!(np = pci_device_to_OF_node(dev))) {
pr_err("cxl: np = NULL\n");
@@ -1727,8 +1726,7 @@ int cxl_slot_is_switched(struct pci_dev *dev)
of_node_get(np);
while (np) {
np = of_get_next_parent(np);
-   prop = of_get_property(np, "device_type", NULL);
-   if (!prop || strcmp((char *)prop, "pciex"))
+   if (!of_node_is_type(np, "pciex"))
break;
depth++;
}
-- 
2.19.1



[PATCH] macintosh: Use device_type helpers to access the node type

2018-11-16 Thread Rob Herring
Remove directly accessing device_node.type pointer and use the accessors
instead. This will eventually allow removing the type pointer.

Cc: Benjamin Herrenschmidt 
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Rob Herring 
---
 drivers/macintosh/macio_asic.c|  4 ++--
 drivers/macintosh/macio_sysfs.c   | 18 ++
 drivers/macintosh/windfarm_fcu_controls.c |  8 
 drivers/macintosh/windfarm_smu_sat.c  |  9 -
 drivers/macintosh/windfarm_smu_sensors.c  | 13 ++---
 5 files changed, 22 insertions(+), 30 deletions(-)

diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index 17d3bc917562..bc8418801224 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -220,8 +220,8 @@ static int macio_resource_quirks(struct device_node *np, 
struct resource *res,
return 1;
 
/* Some older IDE resources have bogus sizes */
-   if (!(strcmp(np->name, "IDE") && strcmp(np->name, "ATA") &&
- strcmp(np->type, "ide") && strcmp(np->type, "ata"))) {
+   if (!strcmp(np->name, "IDE") || !strcmp(np->name, "ATA") ||
+   of_node_is_type(np, "ide") || of_node_is_type(np, "ata")) {
if (index == 0 && (res->end - res->start) > 0xfff)
res->end = res->start + 0xfff;
if (index == 1 && (res->end - res->start) > 0xff)
diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c
index d2451e58acb9..27f5eefc508f 100644
--- a/drivers/macintosh/macio_sysfs.c
+++ b/drivers/macintosh/macio_sysfs.c
@@ -3,17 +3,6 @@
 #include 
 #include 
 
-
-#define macio_config_of_attr(field, format_string) \
-static ssize_t \
-field##_show (struct device *dev, struct device_attribute *attr,   \
-  char *buf)   \
-{  \
-   struct macio_dev *mdev = to_macio_device (dev); \
-   return sprintf (buf, format_string, mdev->ofdev.dev.of_node->field); \
-}  \
-static DEVICE_ATTR_RO(field);
-
 static ssize_t
 compatible_show (struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -65,7 +54,12 @@ static ssize_t name_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(name);
 
-macio_config_of_attr (type, "%s\n");
+static ssize_t type_show(struct device *dev,
+struct device_attribute *attr, char *buf)
+{
+   return sprintf(buf, "%s\n", of_node_get_device_type(dev->of_node));
+}
+static DEVICE_ATTR_RO(type);
 
 static struct attribute *macio_dev_attrs[] = {
_attr_name.attr,
diff --git a/drivers/macintosh/windfarm_fcu_controls.c 
b/drivers/macintosh/windfarm_fcu_controls.c
index 2b3ca628a650..629f19875d7f 100644
--- a/drivers/macintosh/windfarm_fcu_controls.c
+++ b/drivers/macintosh/windfarm_fcu_controls.c
@@ -439,11 +439,11 @@ static void wf_fcu_lookup_fans(struct wf_fcu_priv *pv)
DBG(" control: %pOFn, type: %s\n", np, 
of_node_get_device_type(np));
 
/* Detect control type */
-   if (!strcmp(np->type, "fan-rpm-control") ||
-   !strcmp(np->type, "fan-rpm"))
+   if (of_node_is_type(np, "fan-rpm-control") ||
+   of_node_is_type(np, "fan-rpm"))
type = FCU_FAN_RPM;
-   if (!strcmp(np->type, "fan-pwm-control") ||
-   !strcmp(np->type, "fan-pwm"))
+   if (of_node_is_type(np, "fan-pwm-control") ||
+   of_node_is_type(np, "fan-pwm"))
type = FCU_FAN_PWM;
/* Only care about fans for now */
if (type == -1)
diff --git a/drivers/macintosh/windfarm_smu_sat.c 
b/drivers/macintosh/windfarm_smu_sat.c
index a0f61eb853c5..b4be718beba8 100644
--- a/drivers/macintosh/windfarm_smu_sat.c
+++ b/drivers/macintosh/windfarm_smu_sat.c
@@ -197,7 +197,7 @@ static int wf_sat_probe(struct i2c_client *client,
struct wf_sat *sat;
struct wf_sat_sensor *sens;
const u32 *reg;
-   const char *loc, *type;
+   const char *loc;
u8 chip, core;
struct device_node *child;
int shift, cpu, index;
@@ -220,7 +220,6 @@ static int wf_sat_probe(struct i2c_client *client,
child = NULL;
while ((child = of_get_next_child(dev, child)) != NULL) {
reg = of_get_property(child, "reg", NULL);
-   type = of_get_property(child, "device_type", NULL);
loc = of_get_property(child, "location", NULL);
if (reg == NULL || loc == NULL)
continue;
@@ -249,15 +248,15 @@ static int wf_sat_probe(struct i2c_client *client,
continue;
}
 
-   if 

[PATCH] powerpc: Use device_type helpers to access the node type

2018-11-16 Thread Rob Herring
Remove directly accessing device_node.type pointer and use the accessors
instead. This will eventually allow removing the type pointer.

Replace the open coded iterating over child nodes with
for_each_child_of_node() while we're here.

Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: Michael Ellerman 
Cc: Arnd Bergmann 
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Rob Herring 
---
 arch/powerpc/kernel/cacheinfo.c   |  2 +-
 arch/powerpc/kernel/isa-bridge.c  |  3 +--
 arch/powerpc/kernel/legacy_serial.c   |  5 ++--
 arch/powerpc/kernel/pci_of_scan.c | 11 +++-
 arch/powerpc/kernel/setup-common.c|  2 +-
 arch/powerpc/mm/numa.c|  2 +-
 arch/powerpc/platforms/4xx/pci.c  |  6 ++---
 arch/powerpc/platforms/cell/cbe_regs.c|  6 ++---
 arch/powerpc/platforms/cell/setup.c   |  3 +--
 arch/powerpc/platforms/chrp/pci.c |  6 ++---
 arch/powerpc/platforms/chrp/setup.c   |  5 +---
 arch/powerpc/platforms/maple/pci.c|  6 ++---
 arch/powerpc/platforms/powermac/low_i2c.c |  7 +++--
 arch/powerpc/platforms/powermac/pic.c |  2 +-
 arch/powerpc/platforms/powermac/udbg_adb.c|  2 +-
 .../platforms/pseries/hotplug-memory.c|  8 ++
 arch/powerpc/platforms/pseries/setup.c| 10 +++
 arch/powerpc/platforms/pseries/vio.c  | 27 +--
 18 files changed, 45 insertions(+), 68 deletions(-)

diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c
index be57bd07596d..53102764fd2f 100644
--- a/arch/powerpc/kernel/cacheinfo.c
+++ b/arch/powerpc/kernel/cacheinfo.c
@@ -428,7 +428,7 @@ static void link_cache_lists(struct cache *smaller, struct 
cache *bigger)
 static void do_subsidiary_caches_debugcheck(struct cache *cache)
 {
WARN_ON_ONCE(cache->level != 1);
-   WARN_ON_ONCE(strcmp(cache->ofnode->type, "cpu"));
+   WARN_ON_ONCE(!of_node_is_type(cache->ofnode, "cpu"));
 }
 
 static void do_subsidiary_caches(struct cache *cache)
diff --git a/arch/powerpc/kernel/isa-bridge.c b/arch/powerpc/kernel/isa-bridge.c
index fda3ae48480c..0e7099da4f25 100644
--- a/arch/powerpc/kernel/isa-bridge.c
+++ b/arch/powerpc/kernel/isa-bridge.c
@@ -327,8 +327,7 @@ static int isa_bridge_notify(struct notifier_block *nb, 
unsigned long action,
/* Check if we have no ISA device, and this happens to be one,
 * register it as such if it has an OF device
 */
-   if (!isa_bridge_devnode && devnode && devnode->type &&
-   !strcmp(devnode->type, "isa"))
+   if (!isa_bridge_devnode && of_node_is_type(devnode, "isa"))
isa_bridge_find_late(pdev, devnode);
 
return 0;
diff --git a/arch/powerpc/kernel/legacy_serial.c 
b/arch/powerpc/kernel/legacy_serial.c
index 33b34a58fc62..2a6f339e92cd 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -192,7 +192,7 @@ static int __init add_legacy_soc_port(struct device_node 
*np,
/* Add port, irq will be dealt with later. We passed a translated
 * IO port value. It will be fixed up later along with the irq
 */
-   if (tsi && !strcmp(tsi->type, "tsi-bridge"))
+   if (of_node_is_type(tsi, "tsi-bridge"))
return add_legacy_port(np, -1, UPIO_TSI, addr, addr,
   0, legacy_port_flags, 0);
else
@@ -417,7 +417,8 @@ void __init find_legacy_serial_ports(void)
of_node_put(parent);
continue;
}
-   if (strcmp(np->name, "serial") && strcmp(np->type, "serial")) {
+   if (strcmp(np->name, "serial") &&
+   !of_node_is_type(np, "serial")) {
of_node_put(parent);
continue;
}
diff --git a/arch/powerpc/kernel/pci_of_scan.c 
b/arch/powerpc/kernel/pci_of_scan.c
index 98f04725def7..24191ea2d9a7 100644
--- a/arch/powerpc/kernel/pci_of_scan.c
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -125,16 +125,13 @@ struct pci_dev *of_create_pci_dev(struct device_node 
*node,
 struct pci_bus *bus, int devfn)
 {
struct pci_dev *dev;
-   const char *type;
 
dev = pci_alloc_dev(bus);
if (!dev)
return NULL;
-   type = of_get_property(node, "device_type", NULL);
-   if (type == NULL)
-   type = "";
 
-   pr_debug("create device, devfn: %x, type: %s\n", devfn, type);
+   pr_debug("create device, devfn: %x, type: %s\n", devfn,
+of_node_get_device_type(node));
 
dev->dev.of_node = of_node_get(node);
dev->dev.parent = bus->bridge;
@@ -167,12 +164,12 @@ struct pci_dev *of_create_pci_dev(struct device_node 
*node,
/* Early fixups, before probing the BARs */

[PATCH] powerpc: Rework btext_find_display to use of_stdout and device_type helpers

2018-11-16 Thread Rob Herring
Remove directly accessing device_node.type pointer and use the accessors
instead. This will eventually allow removing the type pointer.

In the process, the of_stdout pointer can be used instead of finding the
stdout node again.

Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: Michael Ellerman 
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Rob Herring 
---
 arch/powerpc/kernel/btext.c | 16 
 1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c
index b4241ed1456e..488b0875ed66 100644
--- a/arch/powerpc/kernel/btext.c
+++ b/arch/powerpc/kernel/btext.c
@@ -232,20 +232,12 @@ static int btext_initialize(struct device_node *np)
 
 int __init btext_find_display(int allow_nonstdout)
 {
-   const char *name;
-   struct device_node *np = NULL; 
+   struct device_node *np = of_stdout; 
int rc = -ENODEV;
 
-   name = of_get_property(of_chosen, "linux,stdout-path", NULL);
-   if (name != NULL) {
-   np = of_find_node_by_path(name);
-   if (np != NULL) {
-   if (strcmp(np->type, "display") != 0) {
-   printk("boot stdout isn't a display !\n");
-   of_node_put(np);
-   np = NULL;
-   }
-   }
+   if (!of_node_is_type(np, "display")) {
+   printk("boot stdout isn't a display !\n");
+   np = NULL;
}
if (np)
rc = btext_initialize(np);
-- 
2.19.1



[PATCH] macintosh: windfarm: Another convert to using %pOFn instead of device_node.name

2018-11-16 Thread Rob Herring
In preparation to remove the node name pointer from struct device_node,
convert printf users to use the %pOFn format specifier.

Convert the open coded iterating thru child nodes to
for_each_child_of_node() while we're here.

Cc: Benjamin Herrenschmidt 
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Rob Herring 
---
 drivers/macintosh/windfarm_fcu_controls.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/macintosh/windfarm_fcu_controls.c 
b/drivers/macintosh/windfarm_fcu_controls.c
index fab7a21e9577..2b3ca628a650 100644
--- a/drivers/macintosh/windfarm_fcu_controls.c
+++ b/drivers/macintosh/windfarm_fcu_controls.c
@@ -425,18 +425,18 @@ static void wf_fcu_lookup_fans(struct wf_fcu_priv *pv)
{ "CPU B 2","cpu-fan-b-1",  },
{ "CPU B 3","cpu-fan-c-1",  },
};
-   struct device_node *np = NULL, *fcu = pv->i2c->dev.of_node;
+   struct device_node *np, *fcu = pv->i2c->dev.of_node;
int i;
 
DBG("Looking up FCU controls in device-tree...\n");
 
-   while ((np = of_get_next_child(fcu, np)) != NULL) {
+   for_each_child_of_node(fcu, np) {
int id, type = -1;
const char *loc;
const char *name;
const u32 *reg;
 
-   DBG(" control: %s, type: %s\n", np->name, np->type);
+   DBG(" control: %pOFn, type: %s\n", np, 
of_node_get_device_type(np));
 
/* Detect control type */
if (!strcmp(np->type, "fan-rpm-control") ||
-- 
2.19.1



[PATCH v8 14/14] ima: Store the measurement again when appraising a modsig

2018-11-16 Thread Thiago Jung Bauermann
If the IMA template contains the 'sig' field, then the modsig should be
added to the measurement list when the file is appraised, and that is what
normally happens.

But If a measurement rule caused a file containing a modsig to be measured
before a different rule causes it to be appraised, the resulting
measurement entry will not contain the modsig because it is only fetched
during appraisal. When the appraisal rule triggers, it won't store a new
measurement containing the modsig because the file was already measured.

We need to detect that situation and store an additional measurement with
the modsig. This is done by defining the appraise subaction flag
IMA_READ_MEASURE and testing for it in process_measurement().

Suggested-by: Mimi Zohar 
Signed-off-by: Thiago Jung Bauermann 
---
 security/integrity/ima/ima.h  |  1 +
 security/integrity/ima/ima_api.c  |  8 +++-
 security/integrity/ima/ima_main.c | 16 +++-
 security/integrity/ima/ima_policy.c   | 59 ---
 security/integrity/ima/ima_template.c | 27 
 security/integrity/integrity.h|  9 ++--
 6 files changed, 110 insertions(+), 10 deletions(-)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 8e1b1ddbe14f..c39bed55f6d2 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -147,6 +147,7 @@ int ima_init_crypto(void);
 void ima_putc(struct seq_file *m, void *data, int datalen);
 void ima_print_digest(struct seq_file *m, u8 *digest, u32 size);
 struct ima_template_desc *ima_template_desc_current(void);
+bool ima_current_template_has_sig(void);
 int ima_restore_measurement_entry(struct ima_template_entry *entry);
 int ima_restore_measurement_list(loff_t bufsize, void *buf);
 int ima_measurements_show(struct seq_file *m, void *v);
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 99dd1d53fc35..a7af114bc6b4 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -289,7 +289,13 @@ void ima_store_measurement(struct integrity_iint_cache 
*iint,
xattr_len, NULL};
int violation = 0;
 
-   if (iint->measured_pcrs & (0x1 << pcr))
+   /*
+* We still need to store the measurement in the case of MODSIG because
+* we only have its contents to put in the list at the time of
+* appraisal. See comment in store_measurement_again() for more details.
+*/
+   if (iint->measured_pcrs & (0x1 << pcr) &&
+   (!xattr_value || xattr_value->type != IMA_MODSIG))
return;
 
result = ima_alloc_init_template(_data, );
diff --git a/security/integrity/ima/ima_main.c 
b/security/integrity/ima/ima_main.c
index d5abd22d502a..807b9b77b813 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -166,6 +166,20 @@ void ima_file_free(struct file *file)
ima_check_last_writer(iint, inode, file);
 }
 
+/*
+ * A file measurement might already exist in the measurement list. Based on
+ * policy, include an additional file measurement containing the appended
+ * signature and file hash, without the appended signature (i.e., the 'd-sig'
+ * field).
+ */
+static bool store_measurement_again(struct integrity_iint_cache *iint,
+   struct evm_ima_xattr_data *xattr_value)
+{
+   return iint->flags & IMA_READ_MEASURE && xattr_value &&
+   xattr_value->type == IMA_MODSIG &&
+   ima_current_template_has_sig();
+}
+
 static int process_measurement(struct file *file, const struct cred *cred,
   u32 secid, char *buf, loff_t size, int mask,
   enum ima_hooks func)
@@ -299,7 +313,7 @@ static int process_measurement(struct file *file, const 
struct cred *cred,
if (!pathbuf)   /* ima_rdwr_violation possibly pre-fetched */
pathname = ima_d_path(>f_path, , filename);
 
-   if (action & IMA_MEASURE)
+   if (action & IMA_MEASURE || store_measurement_again(iint, xattr_value))
ima_store_measurement(iint, file, pathname,
  xattr_value, xattr_len, pcr);
if (rc == 0 && (action & IMA_APPRAISE_SUBMASK)) {
diff --git a/security/integrity/ima/ima_policy.c 
b/security/integrity/ima/ima_policy.c
index 3e5a64053aa8..c0b39802e988 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -10,6 +10,9 @@
  * - initialize default measure policy rules
  *
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include 
 #include 
 #include 
@@ -367,7 +370,8 @@ static bool ima_match_rules(struct ima_rule_entry *rule, 
struct inode *inode,
  * In addition to knowing that we need to appraise the file in general,
  * we need to differentiate between calling hooks, for hook specific rules.
  */
-static int get_subaction(struct ima_rule_entry *rule, enum 

[PATCH v8 13/14] ima: Write modsig to the measurement list

2018-11-16 Thread Thiago Jung Bauermann
Add modsig support to the "sig" template field, allowing the the contents
of the modsig to be included in the measurement list.

Suggested-by: Mimi Zohar 
Signed-off-by: Thiago Jung Bauermann 
---
 security/integrity/ima/ima.h  |  7 +++
 security/integrity/ima/ima_modsig.c   | 13 +
 security/integrity/ima/ima_template_lib.c | 15 ++-
 3 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 7f88e4b86156..8e1b1ddbe14f 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -315,6 +315,7 @@ int ima_read_modsig(enum ima_hooks func, const void *buf, 
loff_t buf_len,
int *xattr_len);
 int ima_get_modsig_hash(struct evm_ima_xattr_data *hdr, enum hash_algo *algo,
const u8 **hash, u8 *len);
+int ima_modsig_serialize_data(struct evm_ima_xattr_data **data, int *data_len);
 int ima_modsig_verify(const unsigned int keyring_id,
  struct evm_ima_xattr_data *hdr);
 void ima_free_xattr_data(struct evm_ima_xattr_data *hdr);
@@ -339,6 +340,12 @@ static inline int ima_get_modsig_hash(struct 
evm_ima_xattr_data *hdr,
return -EOPNOTSUPP;
 }
 
+static inline int ima_modsig_serialize_data(struct evm_ima_xattr_data **data,
+   int *data_len)
+{
+   return -EOPNOTSUPP;
+}
+
 static inline int ima_modsig_verify(const unsigned int keyring_id,
struct evm_ima_xattr_data *hdr)
 {
diff --git a/security/integrity/ima/ima_modsig.c 
b/security/integrity/ima/ima_modsig.c
index 584d9d77b2c4..e31ab7dc11db 100644
--- a/security/integrity/ima/ima_modsig.c
+++ b/security/integrity/ima/ima_modsig.c
@@ -167,6 +167,19 @@ int ima_get_modsig_hash(struct evm_ima_xattr_data *hdr, 
enum hash_algo *algo,
return pkcs7_get_digest(modsig->pkcs7_msg, hash, len);
 }
 
+int ima_modsig_serialize_data(struct evm_ima_xattr_data **data, int *data_len)
+{
+   struct modsig_hdr *modsig = (struct modsig_hdr *) *data;
+
+   if (!*data || (*data)->type != IMA_MODSIG)
+   return -EINVAL;
+
+   *data = >raw_pkcs7;
+   *data_len = modsig->raw_pkcs7_len;
+
+   return 0;
+}
+
 int ima_modsig_verify(const unsigned int keyring_id,
  struct evm_ima_xattr_data *hdr)
 {
diff --git a/security/integrity/ima/ima_template_lib.c 
b/security/integrity/ima/ima_template_lib.c
index 36d175816894..417cd153ba60 100644
--- a/security/integrity/ima/ima_template_lib.c
+++ b/security/integrity/ima/ima_template_lib.c
@@ -411,10 +411,23 @@ int ima_eventsig_init(struct ima_event_data *event_data,
  struct ima_field_data *field_data)
 {
struct evm_ima_xattr_data *xattr_value = event_data->xattr_value;
+   int xattr_len = event_data->xattr_len;
 
if (!is_signed(xattr_value))
return 0;
 
-   return ima_write_template_field_data(xattr_value, event_data->xattr_len,
+   /*
+* The xattr_value for IMA_MODSIG is a runtime structure containing
+* pointers. Get its raw data instead.
+*/
+   if (xattr_value->type == IMA_MODSIG) {
+   int rc;
+
+   rc = ima_modsig_serialize_data(_value, _len);
+   if (rc)
+   return rc;
+   }
+
+   return ima_write_template_field_data(xattr_value, xattr_len,
 DATA_FMT_HEX, field_data);
 }



[PATCH v8 12/14] ima: Add new "d-sig" template field

2018-11-16 Thread Thiago Jung Bauermann
Define new "d-sig" template field which holds the digest that is expected
to match the one contained in the modsig.

Suggested-by: Mimi Zohar 
Signed-off-by: Thiago Jung Bauermann 
---
 Documentation/security/IMA-templates.rst  |  5 
 security/integrity/ima/ima.h  |  9 +++
 security/integrity/ima/ima_modsig.c   | 23 
 security/integrity/ima/ima_template.c |  4 ++-
 security/integrity/ima/ima_template_lib.c | 32 ++-
 security/integrity/ima/ima_template_lib.h |  2 ++
 6 files changed, 73 insertions(+), 2 deletions(-)

diff --git a/Documentation/security/IMA-templates.rst 
b/Documentation/security/IMA-templates.rst
index 2cd0e273cc9a..f2a0f4225857 100644
--- a/Documentation/security/IMA-templates.rst
+++ b/Documentation/security/IMA-templates.rst
@@ -68,6 +68,11 @@ descriptors by adding their identifier to the format string
  - 'd-ng': the digest of the event, calculated with an arbitrary hash
algorithm (field format: [:]digest, where the digest
prefix is shown only if the hash algorithm is not SHA1 or MD5);
+ - 'd-sig': the digest of the event for files that have an appended modsig. 
This
+   field is calculated without including the modsig and thus will differ from
+   the total digest of the file, but it is what should match the digest
+   contained in the modsig (if it doesn't, the signature is invalid). It is
+   shown in the same format as 'd-ng';
  - 'n-ng': the name of the event, without size limitations;
  - 'sig': the file signature.
 
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 312d60cee702..7f88e4b86156 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -313,6 +313,8 @@ bool ima_hook_supports_modsig(enum ima_hooks func);
 int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len,
struct evm_ima_xattr_data **xattr_value,
int *xattr_len);
+int ima_get_modsig_hash(struct evm_ima_xattr_data *hdr, enum hash_algo *algo,
+   const u8 **hash, u8 *len);
 int ima_modsig_verify(const unsigned int keyring_id,
  struct evm_ima_xattr_data *hdr);
 void ima_free_xattr_data(struct evm_ima_xattr_data *hdr);
@@ -330,6 +332,13 @@ static inline int ima_read_modsig(enum ima_hooks func, 
const void *buf,
return -EOPNOTSUPP;
 }
 
+static inline int ima_get_modsig_hash(struct evm_ima_xattr_data *hdr,
+ enum hash_algo *algo, const u8 **hash,
+ u8 *len)
+{
+   return -EOPNOTSUPP;
+}
+
 static inline int ima_modsig_verify(const unsigned int keyring_id,
struct evm_ima_xattr_data *hdr)
 {
diff --git a/security/integrity/ima/ima_modsig.c 
b/security/integrity/ima/ima_modsig.c
index e095d35d804d..584d9d77b2c4 100644
--- a/security/integrity/ima/ima_modsig.c
+++ b/security/integrity/ima/ima_modsig.c
@@ -144,6 +144,29 @@ int ima_read_modsig(enum ima_hooks func, const void *buf, 
loff_t buf_len,
return rc;
 }
 
+int ima_get_modsig_hash(struct evm_ima_xattr_data *hdr, enum hash_algo *algo,
+   const u8 **hash, u8 *len)
+{
+   struct modsig_hdr *modsig = (typeof(modsig)) hdr;
+   const struct public_key_signature *pks;
+   int i;
+
+   if (!hdr || hdr->type != IMA_MODSIG)
+   return -EINVAL;
+
+   pks = pkcs7_get_message_sig(modsig->pkcs7_msg);
+   if (!pks)
+   return -EBADMSG;
+
+   for (i = 0; i < HASH_ALGO__LAST; i++)
+   if (!strcmp(hash_algo_name[i], pks->hash_algo))
+   break;
+
+   *algo = i;
+
+   return pkcs7_get_digest(modsig->pkcs7_msg, hash, len);
+}
+
 int ima_modsig_verify(const unsigned int keyring_id,
  struct evm_ima_xattr_data *hdr)
 {
diff --git a/security/integrity/ima/ima_template.c 
b/security/integrity/ima/ima_template.c
index b631b8bc7624..045ad508cbb8 100644
--- a/security/integrity/ima/ima_template.c
+++ b/security/integrity/ima/ima_template.c
@@ -43,8 +43,10 @@ static const struct ima_template_field supported_fields[] = {
 .field_show = ima_show_template_string},
{.field_id = "sig", .field_init = ima_eventsig_init,
 .field_show = ima_show_template_sig},
+   {.field_id = "d-sig", .field_init = ima_eventdigest_sig_init,
+.field_show = ima_show_template_digest_ng},
 };
-#define MAX_TEMPLATE_NAME_LEN 15
+#define MAX_TEMPLATE_NAME_LEN 24
 
 static struct ima_template_desc *ima_template;
 static struct ima_template_desc *lookup_template_desc(const char *name);
diff --git a/security/integrity/ima/ima_template_lib.c 
b/security/integrity/ima/ima_template_lib.c
index 300912914b17..36d175816894 100644
--- a/security/integrity/ima/ima_template_lib.c
+++ b/security/integrity/ima/ima_template_lib.c
@@ -222,7 +222,8 @@ int ima_parse_buf(void *bufstartp, void *bufendp, void 
**bufcurp,
return 0;

[PATCH v8 11/14] ima: Implement support for module-style appended signatures

2018-11-16 Thread Thiago Jung Bauermann
Implement the appraise_type=imasig|modsig option, allowing IMA to read and
verify modsig signatures.

In case a file has both an xattr signature and an appended modsig, IMA will
only use the appended signature if the key used by the xattr signature
isn't present in the IMA keyring.

Signed-off-by: Thiago Jung Bauermann 
---
 security/integrity/ima/Kconfig|   3 +
 security/integrity/ima/ima.h  |  36 ++-
 security/integrity/ima/ima_appraise.c |  65 ++--
 security/integrity/ima/ima_main.c |  17 ++-
 security/integrity/ima/ima_modsig.c   | 145 ++
 security/integrity/integrity.h|   1 +
 6 files changed, 256 insertions(+), 11 deletions(-)

diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index bba19f9ea184..0fb542455698 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -234,6 +234,9 @@ config IMA_APPRAISE_BOOTPARAM
 config IMA_APPRAISE_MODSIG
bool "Support module-style signatures for appraisal"
depends on IMA_APPRAISE
+   depends on INTEGRITY_ASYMMETRIC_KEYS
+   select PKCS7_MESSAGE_PARSER
+   select MODULE_SIG_FORMAT
default n
help
   Adds support for signatures appended to files. The format of the
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 69c06e2d7bd6..312d60cee702 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -156,7 +156,8 @@ void ima_init_template_list(void);
 
 static inline bool is_signed(const struct evm_ima_xattr_data *xattr_value)
 {
-   return xattr_value && xattr_value->type == EVM_IMA_XATTR_DIGSIG;
+   return xattr_value && (xattr_value->type == EVM_IMA_XATTR_DIGSIG ||
+  xattr_value->type == IMA_MODSIG);
 }
 
 /*
@@ -253,6 +254,8 @@ enum integrity_status ima_get_cache_status(struct 
integrity_iint_cache *iint,
   enum ima_hooks func);
 enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
 int xattr_len);
+bool ima_xattr_sig_known_key(const struct evm_ima_xattr_data *xattr_value,
+int xattr_len);
 int ima_read_xattr(struct dentry *dentry,
   struct evm_ima_xattr_data **xattr_value);
 
@@ -291,6 +294,12 @@ ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, 
int xattr_len)
return ima_hash_algo;
 }
 
+static inline bool ima_xattr_sig_known_key(const struct evm_ima_xattr_data
+  *xattr_value, int xattr_len)
+{
+   return false;
+}
+
 static inline int ima_read_xattr(struct dentry *dentry,
 struct evm_ima_xattr_data **xattr_value)
 {
@@ -301,11 +310,36 @@ static inline int ima_read_xattr(struct dentry *dentry,
 
 #ifdef CONFIG_IMA_APPRAISE_MODSIG
 bool ima_hook_supports_modsig(enum ima_hooks func);
+int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len,
+   struct evm_ima_xattr_data **xattr_value,
+   int *xattr_len);
+int ima_modsig_verify(const unsigned int keyring_id,
+ struct evm_ima_xattr_data *hdr);
+void ima_free_xattr_data(struct evm_ima_xattr_data *hdr);
 #else
 static inline bool ima_hook_supports_modsig(enum ima_hooks func)
 {
return false;
 }
+
+static inline int ima_read_modsig(enum ima_hooks func, const void *buf,
+ loff_t buf_len,
+ struct evm_ima_xattr_data **xattr_value,
+ int *xattr_len)
+{
+   return -EOPNOTSUPP;
+}
+
+static inline int ima_modsig_verify(const unsigned int keyring_id,
+   struct evm_ima_xattr_data *hdr)
+{
+   return -EOPNOTSUPP;
+}
+
+static inline void ima_free_xattr_data(struct evm_ima_xattr_data *hdr)
+{
+   kfree(hdr);
+}
 #endif /* CONFIG_IMA_APPRAISE_MODSIG */
 
 /* LSM based policy rules require audit */
diff --git a/security/integrity/ima/ima_appraise.c 
b/security/integrity/ima/ima_appraise.c
index c6459408e6b2..27a1dbb52544 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -189,6 +189,22 @@ enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data 
*xattr_value,
return ima_hash_algo;
 }
 
+bool ima_xattr_sig_known_key(const struct evm_ima_xattr_data *xattr_value,
+int xattr_len)
+{
+   struct key *keyring;
+
+   if (xattr_value->type != EVM_IMA_XATTR_DIGSIG)
+   return false;
+
+   keyring = integrity_keyring_from_id(INTEGRITY_KEYRING_IMA);
+   if (IS_ERR(keyring))
+   return false;
+
+   return asymmetric_sig_has_known_key(keyring, (const char *) xattr_value,
+   xattr_len);
+}
+
 int ima_read_xattr(struct dentry *dentry,
   struct evm_ima_xattr_data 

[PATCH v8 10/14] ima: Add modsig appraise_type option for module-style appended signatures

2018-11-16 Thread Thiago Jung Bauermann
Introduce the modsig keyword to the IMA policy syntax to specify that
a given hook should expect the file to have the IMA signature appended
to it. Here is how it can be used in a rule:

appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig|modsig

With this rule, IMA will accept either a signature stored in the extended
attribute or an appended signature.

For now, the rule above will behave exactly the same as if
appraise_type=imasig was specified. The actual modsig implementation
will be introduced separately.

Suggested-by: Mimi Zohar 
Signed-off-by: Thiago Jung Bauermann 
---
 Documentation/ABI/testing/ima_policy |  6 +-
 security/integrity/ima/Kconfig   | 10 +
 security/integrity/ima/Makefile  |  1 +
 security/integrity/ima/ima.h |  9 
 security/integrity/ima/ima_modsig.c  | 31 
 security/integrity/ima/ima_policy.c  | 12 +--
 security/integrity/integrity.h   |  1 +
 7 files changed, 67 insertions(+), 3 deletions(-)

diff --git a/Documentation/ABI/testing/ima_policy 
b/Documentation/ABI/testing/ima_policy
index 74c6702de74e..9d1dfd0a8891 100644
--- a/Documentation/ABI/testing/ima_policy
+++ b/Documentation/ABI/testing/ima_policy
@@ -37,7 +37,7 @@ Description:
euid:= decimal value
fowner:= decimal value
lsm:are LSM specific
-   option: appraise_type:= [imasig]
+   option: appraise_type:= [imasig] [imasig|modsig]
pcr:= decimal value
 
default policy:
@@ -103,3 +103,7 @@ Description:
 
measure func=KEXEC_KERNEL_CHECK pcr=4
measure func=KEXEC_INITRAMFS_CHECK pcr=5
+
+   Example of appraise rule allowing modsig appended signatures:
+
+   appraise func=KEXEC_KERNEL_CHECK 
appraise_type=imasig|modsig
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index a18f8c6d13b5..bba19f9ea184 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -231,6 +231,16 @@ config IMA_APPRAISE_BOOTPARAM
  This option enables the different "ima_appraise=" modes
  (eg. fix, log) from the boot command line.
 
+config IMA_APPRAISE_MODSIG
+   bool "Support module-style signatures for appraisal"
+   depends on IMA_APPRAISE
+   default n
+   help
+  Adds support for signatures appended to files. The format of the
+  appended signature is the same used for signed kernel modules.
+  The modsig keyword can be used in the IMA policy to allow a hook
+  to accept such signatures.
+
 config IMA_TRUSTED_KEYRING
bool "Require all keys on the .ima keyring be signed (deprecated)"
depends on IMA_APPRAISE && SYSTEM_TRUSTED_KEYRING
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
index d921dc4f9eb0..31d57cdf2421 100644
--- a/security/integrity/ima/Makefile
+++ b/security/integrity/ima/Makefile
@@ -9,5 +9,6 @@ obj-$(CONFIG_IMA) += ima.o
 ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
 ima_policy.o ima_template.o ima_template_lib.o
 ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o
+ima-$(CONFIG_IMA_APPRAISE_MODSIG) += ima_modsig.o
 ima-$(CONFIG_HAVE_IMA_KEXEC) += ima_kexec.o
 obj-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index f0bc2a182cbf..69c06e2d7bd6 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -299,6 +299,15 @@ static inline int ima_read_xattr(struct dentry *dentry,
 
 #endif /* CONFIG_IMA_APPRAISE */
 
+#ifdef CONFIG_IMA_APPRAISE_MODSIG
+bool ima_hook_supports_modsig(enum ima_hooks func);
+#else
+static inline bool ima_hook_supports_modsig(enum ima_hooks func)
+{
+   return false;
+}
+#endif /* CONFIG_IMA_APPRAISE_MODSIG */
+
 /* LSM based policy rules require audit */
 #ifdef CONFIG_IMA_LSM_RULES
 
diff --git a/security/integrity/ima/ima_modsig.c 
b/security/integrity/ima/ima_modsig.c
new file mode 100644
index ..84d428cbbca8
--- /dev/null
+++ b/security/integrity/ima/ima_modsig.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * IMA support for appraising module-style appended signatures.
+ *
+ * Copyright (C) 2018  IBM Corporation
+ *
+ * Author:
+ * Thiago Jung Bauermann 
+ */
+
+#include "ima.h"
+
+/**
+ * ima_hook_supports_modsig - can the policy allow modsig for this hook?
+ *
+ * modsig is only supported by hooks using ima_post_read_file, because only 
they
+ * preload the contents of the file in a buffer. FILE_CHECK does that in some
+ * cases, but not when reached from vfs_open. POLICY_CHECK can support it, but
+ * it's not useful in practice because it's a text file so deny.
+ */
+bool ima_hook_supports_modsig(enum ima_hooks func)
+{
+   switch (func) {
+   case FIRMWARE_CHECK:
+   case KEXEC_KERNEL_CHECK:

[PATCH v8 09/14] ima: Export func_tokens

2018-11-16 Thread Thiago Jung Bauermann
ima_read_modsig() will need it so that it can show an error message.

Signed-off-by: Thiago Jung Bauermann 
---
 security/integrity/ima/ima.h|  2 ++
 security/integrity/ima/ima_policy.c | 12 ++--
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index e4f72b30cb28..f0bc2a182cbf 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -195,6 +195,8 @@ enum ima_hooks {
__ima_hooks(__ima_hook_enumify)
 };
 
+extern const char *const func_tokens[];
+
 /* LIM API function definitions */
 int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid,
   int mask, enum ima_hooks func, int *pcr);
diff --git a/security/integrity/ima/ima_policy.c 
b/security/integrity/ima/ima_policy.c
index b20770704b6c..fd31e42c2bad 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -1136,6 +1136,12 @@ void ima_delete_rules(void)
}
 }
 
+#define __ima_hook_stringify(str)  (#str),
+
+const char *const func_tokens[] = {
+   __ima_hooks(__ima_hook_stringify)
+};
+
 #ifdef CONFIG_IMA_READ_POLICY
 enum {
mask_exec = 0, mask_write, mask_read, mask_append
@@ -1148,12 +1154,6 @@ static const char *const mask_tokens[] = {
"MAY_APPEND"
 };
 
-#define __ima_hook_stringify(str)  (#str),
-
-static const char *const func_tokens[] = {
-   __ima_hooks(__ima_hook_stringify)
-};
-
 void *ima_policy_start(struct seq_file *m, loff_t *pos)
 {
loff_t l = *pos;



[PATCH v8 08/14] ima: Introduce is_signed()

2018-11-16 Thread Thiago Jung Bauermann
With the introduction of another IMA signature type (modsig), some places
will need to check for both of them. It is cleaner to do that if there's a
helper function to tell whether an xattr_value represents an IMA
signature.

Suggested-by: Mimi Zohar 
Signed-off-by: Thiago Jung Bauermann 
---
 security/integrity/ima/ima.h  | 5 +
 security/integrity/ima/ima_appraise.c | 7 +++
 security/integrity/ima/ima_template_lib.c | 2 +-
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index cc12f3449a72..e4f72b30cb28 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -154,6 +154,11 @@ unsigned long ima_get_binary_runtime_size(void);
 int ima_init_template(void);
 void ima_init_template_list(void);
 
+static inline bool is_signed(const struct evm_ima_xattr_data *xattr_value)
+{
+   return xattr_value && xattr_value->type == EVM_IMA_XATTR_DIGSIG;
+}
+
 /*
  * used to protect h_table and sha_table
  */
diff --git a/security/integrity/ima/ima_appraise.c 
b/security/integrity/ima/ima_appraise.c
index 8bcef90939f8..c6459408e6b2 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -325,15 +325,14 @@ int ima_appraise_measurement(enum ima_hooks func,
} else if (status != INTEGRITY_PASS) {
/* Fix mode, but don't replace file signatures. */
if ((ima_appraise & IMA_APPRAISE_FIX) &&
-   (!xattr_value ||
-xattr_value->type != EVM_IMA_XATTR_DIGSIG)) {
+   !is_signed(xattr_value)) {
if (!ima_fix_xattr(dentry, iint))
status = INTEGRITY_PASS;
}
 
/* Permit new files with file signatures, but without data. */
if (inode->i_size == 0 && iint->flags & IMA_NEW_FILE &&
-   xattr_value && xattr_value->type == EVM_IMA_XATTR_DIGSIG) {
+   is_signed(xattr_value)) {
status = INTEGRITY_PASS;
}
 
@@ -448,7 +447,7 @@ int ima_inode_setxattr(struct dentry *dentry, const char 
*xattr_name,
if (!xattr_value_len || (xvalue->type >= IMA_XATTR_LAST))
return -EINVAL;
ima_reset_appraise_flags(d_backing_inode(dentry),
-   xvalue->type == EVM_IMA_XATTR_DIGSIG);
+is_signed(xvalue));
result = 0;
}
return result;
diff --git a/security/integrity/ima/ima_template_lib.c 
b/security/integrity/ima/ima_template_lib.c
index 43752002c222..300912914b17 100644
--- a/security/integrity/ima/ima_template_lib.c
+++ b/security/integrity/ima/ima_template_lib.c
@@ -382,7 +382,7 @@ int ima_eventsig_init(struct ima_event_data *event_data,
 {
struct evm_ima_xattr_data *xattr_value = event_data->xattr_value;
 
-   if ((!xattr_value) || (xattr_value->type != EVM_IMA_XATTR_DIGSIG))
+   if (!is_signed(xattr_value))
return 0;
 
return ima_write_template_field_data(xattr_value, event_data->xattr_len,



[PATCH v8 07/14] integrity: Select CONFIG_KEYS instead of depending on it

2018-11-16 Thread Thiago Jung Bauermann
This avoids a dependency cycle in soon-to-be-introduced
CONFIG_IMA_APPRAISE_MODSIG: it will select CONFIG_MODULE_SIG_FORMAT
which in turn selects CONFIG_KEYS. Kconfig then complains that
CONFIG_INTEGRITY_SIGNATURE depends on CONFIG_KEYS.

Signed-off-by: Thiago Jung Bauermann 
Signed-off-by: Mimi Zohar 
---
 security/integrity/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
index da9565891738..0d642e0317c7 100644
--- a/security/integrity/Kconfig
+++ b/security/integrity/Kconfig
@@ -17,8 +17,8 @@ if INTEGRITY
 
 config INTEGRITY_SIGNATURE
bool "Digital signature verification using multiple keyrings"
-   depends on KEYS
default n
+   select KEYS
select SIGNATURE
help
  This option enables digital signature verification support



[PATCH v8 06/14] integrity: Introduce asymmetric_sig_has_known_key()

2018-11-16 Thread Thiago Jung Bauermann
IMA will only look for a modsig if the xattr sig references a key which is
not in the expected kernel keyring. To that end, introduce
asymmetric_sig_has_known_key().

The logic of extracting the key used in the xattr sig is factored out from
asymmetric_verify() so that it can be used by the new function.

Signed-off-by: Thiago Jung Bauermann 
Signed-off-by: Mimi Zohar 
---
 security/integrity/digsig_asymmetric.c | 44 +++---
 security/integrity/integrity.h |  8 +
 2 files changed, 41 insertions(+), 11 deletions(-)

diff --git a/security/integrity/digsig_asymmetric.c 
b/security/integrity/digsig_asymmetric.c
index d775e03fbbcc..4c3c49f919f5 100644
--- a/security/integrity/digsig_asymmetric.c
+++ b/security/integrity/digsig_asymmetric.c
@@ -79,26 +79,48 @@ static struct key *request_asymmetric_key(struct key 
*keyring, uint32_t keyid)
return key;
 }
 
-int asymmetric_verify(struct key *keyring, const char *sig,
- int siglen, const char *data, int datalen)
+static struct key *asymmetric_key_from_sig(struct key *keyring, const char 
*sig,
+  int siglen)
 {
-   struct public_key_signature pks;
-   struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
-   struct key *key;
-   int ret = -ENOMEM;
+   const struct signature_v2_hdr *hdr = (struct signature_v2_hdr *) sig;
 
if (siglen <= sizeof(*hdr))
-   return -EBADMSG;
+   return ERR_PTR(-EBADMSG);
 
siglen -= sizeof(*hdr);
 
if (siglen != be16_to_cpu(hdr->sig_size))
-   return -EBADMSG;
+   return ERR_PTR(-EBADMSG);
 
if (hdr->hash_algo >= HASH_ALGO__LAST)
-   return -ENOPKG;
+   return ERR_PTR(-ENOPKG);
+
+   return request_asymmetric_key(keyring, be32_to_cpu(hdr->keyid));
+}
+
+bool asymmetric_sig_has_known_key(struct key *keyring, const char *sig,
+ int siglen)
+{
+   struct key *key;
+
+   key = asymmetric_key_from_sig(keyring, sig, siglen);
+   if (IS_ERR_OR_NULL(key))
+   return false;
+
+   key_put(key);
+
+   return true;
+}
+
+int asymmetric_verify(struct key *keyring, const char *sig,
+ int siglen, const char *data, int datalen)
+{
+   struct public_key_signature pks;
+   struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
+   struct key *key;
+   int ret = -ENOMEM;
 
-   key = request_asymmetric_key(keyring, be32_to_cpu(hdr->keyid));
+   key = asymmetric_key_from_sig(keyring, sig, siglen);
if (IS_ERR(key))
return PTR_ERR(key);
 
@@ -110,7 +132,7 @@ int asymmetric_verify(struct key *keyring, const char *sig,
pks.digest = (u8 *)data;
pks.digest_size = datalen;
pks.s = hdr->sig;
-   pks.s_size = siglen;
+   pks.s_size = siglen - sizeof(*hdr);
ret = verify_signature(key, );
key_put(key);
pr_debug("%s() = %d\n", __func__, ret);
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 91c41351e18a..ae3c79c63674 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -182,12 +182,20 @@ static inline int integrity_init_keyring(const unsigned 
int id)
 #ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS
 int asymmetric_verify(struct key *keyring, const char *sig,
  int siglen, const char *data, int datalen);
+bool asymmetric_sig_has_known_key(struct key *keyring, const char *sig,
+ int siglen);
 #else
 static inline int asymmetric_verify(struct key *keyring, const char *sig,
int siglen, const char *data, int datalen)
 {
return -EOPNOTSUPP;
 }
+
+static inline bool asymmetric_sig_has_known_key(struct key *keyring,
+   const char *sig, int siglen)
+{
+   return false;
+}
 #endif
 
 #ifdef CONFIG_IMA_LOAD_X509



[PATCH v8 05/14] integrity: Introduce integrity_keyring_from_id()

2018-11-16 Thread Thiago Jung Bauermann
IMA will need to obtain the keyring used to verify file signatures so that
it can verify the module-style signature appended to files.

Signed-off-by: Thiago Jung Bauermann 
Signed-off-by: Mimi Zohar 
---
 security/integrity/digsig.c| 28 +---
 security/integrity/integrity.h |  6 ++
 2 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index 5eacba858e4b..bfa27f166184 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -43,11 +43,10 @@ static const char * const 
keyring_name[INTEGRITY_KEYRING_MAX] = {
 #define restrict_link_to_ima restrict_link_by_builtin_trusted
 #endif
 
-int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
-   const char *digest, int digestlen)
+struct key *integrity_keyring_from_id(const unsigned int id)
 {
-   if (id >= INTEGRITY_KEYRING_MAX || siglen < 2)
-   return -EINVAL;
+   if (id >= INTEGRITY_KEYRING_MAX)
+   return ERR_PTR(-EINVAL);
 
if (!keyring[id]) {
keyring[id] =
@@ -56,17 +55,32 @@ int integrity_digsig_verify(const unsigned int id, const 
char *sig, int siglen,
int err = PTR_ERR(keyring[id]);
pr_err("no %s keyring: %d\n", keyring_name[id], err);
keyring[id] = NULL;
-   return err;
+   return ERR_PTR(err);
}
}
 
+   return keyring[id];
+}
+
+int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
+   const char *digest, int digestlen)
+{
+   struct key *keyring;
+
+   if (siglen < 2)
+   return -EINVAL;
+
+   keyring = integrity_keyring_from_id(id);
+   if (IS_ERR(keyring))
+   return PTR_ERR(keyring);
+
switch (sig[1]) {
case 1:
/* v1 API expect signature without xattr type */
-   return digsig_verify(keyring[id], sig + 1, siglen - 1,
+   return digsig_verify(keyring, sig + 1, siglen - 1,
 digest, digestlen);
case 2:
-   return asymmetric_verify(keyring[id], sig, siglen,
+   return asymmetric_verify(keyring, sig, siglen,
 digest, digestlen);
}
 
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 20ac02bf1b84..91c41351e18a 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -153,6 +153,7 @@ extern struct dentry *integrity_dir;
 
 #ifdef CONFIG_INTEGRITY_SIGNATURE
 
+struct key *integrity_keyring_from_id(const unsigned int id);
 int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
const char *digest, int digestlen);
 
@@ -160,6 +161,11 @@ int __init integrity_init_keyring(const unsigned int id);
 int __init integrity_load_x509(const unsigned int id, const char *path);
 #else
 
+static inline struct key *integrity_keyring_from_id(const unsigned int id)
+{
+   return ERR_PTR(-EINVAL);
+}
+
 static inline int integrity_digsig_verify(const unsigned int id,
  const char *sig, int siglen,
  const char *digest, int digestlen)



[PATCH v8 04/14] integrity: Introduce struct evm_xattr

2018-11-16 Thread Thiago Jung Bauermann
Even though struct evm_ima_xattr_data includes a fixed-size array to hold a
SHA1 digest, most of the code ignores the array and uses the struct to mean
"type indicator followed by data of unspecified size" and tracks the real
size of what the struct represents in a separate length variable.

The only exception to that is the EVM code, which correctly uses the
definition of struct evm_ima_xattr_data.

So make this explicit in the code by removing the length specification from
the array in struct evm_ima_xattr_data. Also, change the name of the
element from digest to data since in most places the array doesn't hold a
digest.

A separate struct evm_xattr is introduced, with the original definition of
evm_ima_xattr_data to be used in the places that actually expect that
definition.

Signed-off-by: Thiago Jung Bauermann 
---
 security/integrity/evm/evm_main.c | 8 
 security/integrity/ima/ima_appraise.c | 7 ---
 security/integrity/integrity.h| 5 +
 3 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/security/integrity/evm/evm_main.c 
b/security/integrity/evm/evm_main.c
index 7f3f54d89a6e..a1b42d10efc7 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -169,7 +169,7 @@ static enum integrity_status evm_verify_hmac(struct dentry 
*dentry,
/* check value type */
switch (xattr_data->type) {
case EVM_XATTR_HMAC:
-   if (xattr_len != sizeof(struct evm_ima_xattr_data)) {
+   if (xattr_len != sizeof(struct evm_xattr)) {
evm_status = INTEGRITY_FAIL;
goto out;
}
@@ -179,7 +179,7 @@ static enum integrity_status evm_verify_hmac(struct dentry 
*dentry,
   xattr_value_len, );
if (rc)
break;
-   rc = crypto_memneq(xattr_data->digest, digest.digest,
+   rc = crypto_memneq(xattr_data->data, digest.digest,
   SHA1_DIGEST_SIZE);
if (rc)
rc = -EINVAL;
@@ -523,7 +523,7 @@ int evm_inode_init_security(struct inode *inode,
 const struct xattr *lsm_xattr,
 struct xattr *evm_xattr)
 {
-   struct evm_ima_xattr_data *xattr_data;
+   struct evm_xattr *xattr_data;
int rc;
 
if (!evm_key_loaded() || !evm_protected_xattr(lsm_xattr->name))
@@ -533,7 +533,7 @@ int evm_inode_init_security(struct inode *inode,
if (!xattr_data)
return -ENOMEM;
 
-   xattr_data->type = EVM_XATTR_HMAC;
+   xattr_data->data.type = EVM_XATTR_HMAC;
rc = evm_init_hmac(inode, lsm_xattr, xattr_data->digest);
if (rc < 0)
goto out;
diff --git a/security/integrity/ima/ima_appraise.c 
b/security/integrity/ima/ima_appraise.c
index deec1804a00a..8bcef90939f8 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -167,7 +167,8 @@ enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data 
*xattr_value,
return sig->hash_algo;
break;
case IMA_XATTR_DIGEST_NG:
-   ret = xattr_value->digest[0];
+   /* first byte contains algorithm id */
+   ret = xattr_value->data[0];
if (ret < HASH_ALGO__LAST)
return ret;
break;
@@ -175,7 +176,7 @@ enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data 
*xattr_value,
/* this is for backward compatibility */
if (xattr_len == 21) {
unsigned int zero = 0;
-   if (!memcmp(_value->digest[16], , 4))
+   if (!memcmp(_value->data[16], , 4))
return HASH_ALGO_MD5;
else
return HASH_ALGO_SHA1;
@@ -274,7 +275,7 @@ int ima_appraise_measurement(enum ima_hooks func,
/* xattr length may be longer. md5 hash in previous
   version occupied 20 bytes in xattr, instead of 16
 */
-   rc = memcmp(_value->digest[hash_start],
+   rc = memcmp(_value->data[hash_start],
iint->ima_hash->digest,
iint->ima_hash->length);
else
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index e60473b13a8d..20ac02bf1b84 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -79,6 +79,11 @@ enum evm_ima_xattr_type {
 
 struct evm_ima_xattr_data {
u8 type;
+   u8 data[];
+} __packed;
+
+struct evm_xattr {
+   struct evm_ima_xattr_data data;
u8 digest[SHA1_DIGEST_SIZE];
 } __packed;
 



[PATCH v8 03/14] PKCS#7: Introduce pkcs7_get_digest()

2018-11-16 Thread Thiago Jung Bauermann
IMA will need to access the digest of the PKCS7 message (as calculated by
the kernel) before the signature is verified, so introduce
pkcs7_get_digest() for that purpose.

Also, modify pkcs7_digest() to detect when the digest was already
calculated so that it doesn't have to do redundant work. Verifying that
sinfo->sig->digest isn't NULL is sufficient because both places which
allocate sinfo->sig (pkcs7_parse_message() and pkcs7_note_signed_info())
use kzalloc() so sig->digest is always initialized to zero.

Signed-off-by: Thiago Jung Bauermann 
Reviewed-by: Mimi Zohar 
Cc: David Howells 
Cc: Herbert Xu 
Cc: "David S. Miller" 
---
 crypto/asymmetric_keys/pkcs7_verify.c | 25 +
 include/crypto/pkcs7.h|  3 +++
 2 files changed, 28 insertions(+)

diff --git a/crypto/asymmetric_keys/pkcs7_verify.c 
b/crypto/asymmetric_keys/pkcs7_verify.c
index 97c77f66b20d..e61f121bfc87 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -33,6 +33,10 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
 
kenter(",%u,%s", sinfo->index, sinfo->sig->hash_algo);
 
+   /* The digest was calculated already. */
+   if (sig->digest)
+   return 0;
+
if (!sinfo->sig->hash_algo)
return -ENOPKG;
 
@@ -122,6 +126,27 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
return ret;
 }
 
+int pkcs7_get_digest(struct pkcs7_message *pkcs7, const u8 **buf, u8 *len)
+{
+   struct pkcs7_signed_info *sinfo = pkcs7->signed_infos;
+   int ret;
+
+   /*
+* This function doesn't support messages with more than one signature.
+*/
+   if (sinfo == NULL || sinfo->next != NULL)
+   return -EBADMSG;
+
+   ret = pkcs7_digest(pkcs7, sinfo);
+   if (ret)
+   return ret;
+
+   *buf = sinfo->sig->digest;
+   *len = sinfo->sig->digest_size;
+
+   return 0;
+}
+
 /*
  * Find the key (X.509 certificate) to use to verify a PKCS#7 message.  PKCS#7
  * uses the issuer's name and the issuing certificate serial number for
diff --git a/include/crypto/pkcs7.h b/include/crypto/pkcs7.h
index 6f51d0cb6d12..cfaea9c37f4a 100644
--- a/include/crypto/pkcs7.h
+++ b/include/crypto/pkcs7.h
@@ -46,4 +46,7 @@ extern int pkcs7_verify(struct pkcs7_message *pkcs7,
 extern int pkcs7_supply_detached_data(struct pkcs7_message *pkcs7,
  const void *data, size_t datalen);
 
+extern int pkcs7_get_digest(struct pkcs7_message *pkcs7, const u8 **buf,
+   u8 *len);
+
 #endif /* _CRYPTO_PKCS7_H */



[PATCH v8 02/14] PKCS#7: Refactor verify_pkcs7_signature() and add pkcs7_get_message_sig()

2018-11-16 Thread Thiago Jung Bauermann
IMA will need to verify a PKCS#7 which has already been parsed. For this
reason, factor out the code which does that from verify_pkcs7_signature()
into a new function which takes a struct pkcs7_message instead of a data
buffer.

In addition, IMA will need to know the key that signed a given PKCS#7
message, so add pkcs7_get_message_sig().

Signed-off-by: Thiago Jung Bauermann 
Reviewed-by: Mimi Zohar 
Cc: David Howells 
Cc: David Woodhouse 
Cc: Herbert Xu 
Cc: "David S. Miller" 
---
 certs/system_keyring.c| 61 ---
 crypto/asymmetric_keys/pkcs7_parser.c | 16 +++
 include/crypto/pkcs7.h|  2 +
 include/linux/verification.h  | 10 +
 4 files changed, 73 insertions(+), 16 deletions(-)

diff --git a/certs/system_keyring.c b/certs/system_keyring.c
index 81728717523d..dd8c5ef941ce 100644
--- a/certs/system_keyring.c
+++ b/certs/system_keyring.c
@@ -191,33 +191,27 @@ late_initcall(load_system_certificate_list);
 #ifdef CONFIG_SYSTEM_DATA_VERIFICATION
 
 /**
- * verify_pkcs7_signature - Verify a PKCS#7-based signature on system data.
+ * verify_pkcs7_message_sig - Verify a PKCS#7-based signature on system data.
  * @data: The data to be verified (NULL if expecting internal data).
  * @len: Size of @data.
- * @raw_pkcs7: The PKCS#7 message that is the signature.
- * @pkcs7_len: The size of @raw_pkcs7.
+ * @pkcs7: The PKCS#7 message that is the signature.
  * @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only,
  * (void *)1UL for all trusted keys).
  * @usage: The use to which the key is being put.
  * @view_content: Callback to gain access to content.
  * @ctx: Context for callback.
  */
-int verify_pkcs7_signature(const void *data, size_t len,
-  const void *raw_pkcs7, size_t pkcs7_len,
-  struct key *trusted_keys,
-  enum key_being_used_for usage,
-  int (*view_content)(void *ctx,
-  const void *data, size_t len,
-  size_t asn1hdrlen),
-  void *ctx)
+int verify_pkcs7_message_sig(const void *data, size_t len,
+struct pkcs7_message *pkcs7,
+struct key *trusted_keys,
+enum key_being_used_for usage,
+int (*view_content)(void *ctx,
+const void *data, size_t len,
+size_t asn1hdrlen),
+void *ctx)
 {
-   struct pkcs7_message *pkcs7;
int ret;
 
-   pkcs7 = pkcs7_parse_message(raw_pkcs7, pkcs7_len);
-   if (IS_ERR(pkcs7))
-   return PTR_ERR(pkcs7);
-
/* The data should be detached - so we need to supply it. */
if (data && pkcs7_supply_detached_data(pkcs7, data, len) < 0) {
pr_err("PKCS#7 signature with non-detached data\n");
@@ -259,6 +253,41 @@ int verify_pkcs7_signature(const void *data, size_t len,
}
 
 error:
+   pr_devel("<==%s() = %d\n", __func__, ret);
+   return ret;
+}
+
+/**
+ * verify_pkcs7_signature - Verify a PKCS#7-based signature on system data.
+ * @data: The data to be verified (NULL if expecting internal data).
+ * @len: Size of @data.
+ * @raw_pkcs7: The PKCS#7 message that is the signature.
+ * @pkcs7_len: The size of @raw_pkcs7.
+ * @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only,
+ * (void *)1UL for all trusted keys).
+ * @usage: The use to which the key is being put.
+ * @view_content: Callback to gain access to content.
+ * @ctx: Context for callback.
+ */
+int verify_pkcs7_signature(const void *data, size_t len,
+  const void *raw_pkcs7, size_t pkcs7_len,
+  struct key *trusted_keys,
+  enum key_being_used_for usage,
+  int (*view_content)(void *ctx,
+  const void *data, size_t len,
+  size_t asn1hdrlen),
+  void *ctx)
+{
+   struct pkcs7_message *pkcs7;
+   int ret;
+
+   pkcs7 = pkcs7_parse_message(raw_pkcs7, pkcs7_len);
+   if (IS_ERR(pkcs7))
+   return PTR_ERR(pkcs7);
+
+   ret = verify_pkcs7_message_sig(data, len, pkcs7, trusted_keys, usage,
+  view_content, ctx);
+
pkcs7_free_message(pkcs7);
pr_devel("<==%s() = %d\n", __func__, ret);
return ret;
diff --git a/crypto/asymmetric_keys/pkcs7_parser.c 
b/crypto/asymmetric_keys/pkcs7_parser.c
index f0d56e1a8b7e..8df9693f659f 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.c
+++ b/crypto/asymmetric_keys/pkcs7_parser.c
@@ -684,3 +684,19 @@ int 

[PATCH v8 01/14] MODSIGN: Export module signature definitions

2018-11-16 Thread Thiago Jung Bauermann
IMA will use the module_signature format for append signatures, so export
the relevant definitions and factor out the code which verifies that the
appended signature trailer is valid.

Also, create a CONFIG_MODULE_SIG_FORMAT option so that IMA can select it
and be able to use validate_module_sig() without having to depend on
CONFIG_MODULE_SIG.

Signed-off-by: Thiago Jung Bauermann 
Reviewed-by: Mimi Zohar 
Cc: Jessica Yu 
---
 include/linux/module.h   |  3 --
 include/linux/module_signature.h | 47 ++
 init/Kconfig |  6 ++-
 kernel/Makefile  |  2 +-
 kernel/module.c  |  1 +
 kernel/module_signing.c  | 82 ++--
 6 files changed, 91 insertions(+), 50 deletions(-)

diff --git a/include/linux/module.h b/include/linux/module.h
index fce6b4335e36..e49bbc5c66ef 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -25,9 +25,6 @@
 #include 
 #include 
 
-/* In stripped ARM and x86-64 modules, ~ is surprisingly rare. */
-#define MODULE_SIG_STRING "~Module signature appended~\n"
-
 /* Not Yet Implemented */
 #define MODULE_SUPPORTED_DEVICE(name)
 
diff --git a/include/linux/module_signature.h b/include/linux/module_signature.h
new file mode 100644
index ..862ddc25dbd1
--- /dev/null
+++ b/include/linux/module_signature.h
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Module signature handling.
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowe...@redhat.com)
+ */
+
+#ifndef _LINUX_MODULE_SIGNATURE_H
+#define _LINUX_MODULE_SIGNATURE_H
+
+/* In stripped ARM and x86-64 modules, ~ is surprisingly rare. */
+#define MODULE_SIG_STRING "~Module signature appended~\n"
+
+enum pkey_id_type {
+   PKEY_ID_PGP,/* OpenPGP generated key ID */
+   PKEY_ID_X509,   /* X.509 arbitrary subjectKeyIdentifier */
+   PKEY_ID_PKCS7,  /* Signature in PKCS#7 message */
+};
+
+/*
+ * Module signature information block.
+ *
+ * The constituents of the signature section are, in order:
+ *
+ * - Signer's name
+ * - Key identifier
+ * - Signature data
+ * - Information block
+ */
+struct module_signature {
+   u8  algo;   /* Public-key crypto algorithm [0] */
+   u8  hash;   /* Digest algorithm [0] */
+   u8  id_type;/* Key identifier type [PKEY_ID_PKCS7] */
+   u8  signer_len; /* Length of signer's name [0] */
+   u8  key_id_len; /* Length of key identifier [0] */
+   u8  __pad[3];
+   __be32  sig_len;/* Length of signature data */
+};
+
+struct load_info;
+
+int validate_module_sig(const struct module_signature *ms, size_t file_len,
+   const char *name);
+int mod_verify_sig(const void *mod, struct load_info *info);
+
+#endif /* _LINUX_MODULE_SIGNATURE_H */
diff --git a/init/Kconfig b/init/Kconfig
index a4112e95724a..cd31593525ee 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1864,7 +1864,7 @@ config MODULE_SRCVERSION_ALL
 config MODULE_SIG
bool "Module signature verification"
depends on MODULES
-   select SYSTEM_DATA_VERIFICATION
+   select MODULE_SIG_FORMAT
help
  Check modules for valid signatures upon load: the signature
  is simply appended to the module. For more information see
@@ -1879,6 +1879,10 @@ config MODULE_SIG
  debuginfo strip done by some packagers (such as rpmbuild) and
  inclusion into an initramfs that wants the module size reduced.
 
+config MODULE_SIG_FORMAT
+   def_bool n
+   select SYSTEM_DATA_VERIFICATION
+
 config MODULE_SIG_FORCE
bool "Require modules to be validly signed"
depends on MODULE_SIG
diff --git a/kernel/Makefile b/kernel/Makefile
index 7343b3a9bff0..e56842571348 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -59,7 +59,7 @@ obj-y += up.o
 endif
 obj-$(CONFIG_UID16) += uid16.o
 obj-$(CONFIG_MODULES) += module.o
-obj-$(CONFIG_MODULE_SIG) += module_signing.o
+obj-$(CONFIG_MODULE_SIG_FORMAT) += module_signing.o
 obj-$(CONFIG_KALLSYMS) += kallsyms.o
 obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
 obj-$(CONFIG_CRASH_CORE) += crash_core.o
diff --git a/kernel/module.c b/kernel/module.c
index 49a405891587..205c9eefd08d 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
diff --git a/kernel/module_signing.c b/kernel/module_signing.c
index f2075ce8e4b3..2912b7b1e814 100644
--- a/kernel/module_signing.c
+++ b/kernel/module_signing.c
@@ -11,36 +11,44 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include "module-internal.h"
 
-enum pkey_id_type {
-   PKEY_ID_PGP,/* OpenPGP generated key ID */
-   PKEY_ID_X509,   /* X.509 arbitrary subjectKeyIdentifier */
-   PKEY_ID_PKCS7,  /* Signature in PKCS#7 message */
-};

[PATCH v8 00/14] Appended signatures support for IMA appraisal

2018-11-16 Thread Thiago Jung Bauermann
Hello,

v8 is just a rebase on top of today's linux-integrity/next-integrity.
There aren't any noteworthy changes since v7, which is why I'm keeping its
description below:

The main difference in v7 is the addition of the last patch, which ensures
that there will always be a measurement entry containing the appended
modsig if one was used to appraise the file. The patch description and
comments in the code should explain in which circumstances the patch proved
necessary.

Apart from that, there was some small cleaning up of the code, and merging
and splitting of patches. The changelog below has the details.

Original cover letter:

On the OpenPOWER platform, secure boot and trusted boot are being
implemented using IMA for taking measurements and verifying signatures.
Since the kernel image on Power servers is an ELF binary, kernels are
signed using the scripts/sign-file tool and thus use the same signature
format as signed kernel modules.

This patch series adds support in IMA for verifying those signatures.
It adds flexibility to OpenPOWER secure boot, because it allows it to boot
kernels with the signature appended to them as well as kernels where the
signature is stored in the IMA extended attribute.

Changes since v7:
- Patch "MODSIGN: Export module signature definitions"
  - Added module name parameter to validate_module_sig() so that it can be
shown in error messages.

- Patch "integrity: Introduce struct evm_xattr"
  - Dropped use of struct evm_xattr in evm_update_evmxattr() and
evm_verify_hmac(). It's not needed there anymore because of changes
to support portable EVM signatures.

Changes since v6:

- Patch "PKCS#7: Introduce pkcs7_get_message_sig() and 
verify_pkcs7_message_sig()"
  - Retitled to "PKCS#7: Refactor verify_pkcs7_signature() and
add pkcs7_get_message_sig()"
  - Reworded description to clarify why the refactoring is needed.
The code is unchanged. (Suggested by Mimi Zohar)
  - Added Mimi Zohar's Reviewed-by.

- Patch "PKCS#7: Introduce pkcs7_get_digest()"
  - Added Mimi Zohar's Reviewed-by.

- Patch "integrity: Introduce integrity_keyring_from_id"
  - Added Mimi Zohar's Signed-off-by.

- Patch "integrity: Introduce asymmetric_sig_has_known_key()"
  - Added Mimi Zohar's Signed-off-by.

- Patch "integrity: Select CONFIG_KEYS instead of depending on it"
  - Added Mimi Zohar's Signed-off-by.

- Patch "ima: Introduce is_ima_sig()"
  - Renamed function to is_signed() (suggested by Mimi Zohar).

- Patch "ima: Add functions to read and verify a modsig signature"
  - Changed stubs for the !CONFIG_IMA_APPRAISE_MODSIG to return -EOPNOTSUPP
instead of -ENOTSUPP, since the latter isn't defined in uapi headers.
  - Moved functions to the patches which use them and dropped this patch
(suggested by Mimi Zohar).

- Patch "ima: Implement support for module-style appended signatures"
  - Prevent reading and writing of IMA_MODSIG xattr in ima_read_xattr()
and ima_inode_setxattr().
  - Simplify code in process_measurement() which decides whether to try
reading a modsig (suggested by Mimi Zohar).
  - Moved some functions from patch "ima: Add functions to read and verify
a modsig signature" into this patch.

- Patch "ima: Add new "d-sig" template field"
  - New patch containing code from patch "ima: Write modsig to the measurement 
list"
(Suggested by Mimi Zohar).

- Patch "ima: Write modsig to the measurement list"
  - Moved some functions from patch "ima: Add functions to read and verify
a modsig signature" into this patch.
  - Moved code related to d-sig support to new patch.

- Patch "ima: Store the measurement again when appraising a modsig"
  - New patch.

Changes since v5:
- Patch "ima: Remove some superfluous parentheses"
  - Dropped.

- Patch "evm, ima: Remove superfluous parentheses"
  - Dropped.

- Patch "evm, ima: Remove more superfluous parentheses"
  - Dropped.

- Patch "ima: Don't pass xattr value to EVM xattr verification."
  - Dropped.

- Patch "ima: Store measurement after appraisal"
  - Dropped.

- Patch "MODSIGN: Export module signature definitions"
  - Reduced changes to the code that was moved into validate_module_sig()
to the minimum necessary (suggested by Mimi Zohar).
  - Added SPDX license identifier.

- Patch "PKCS#7: Introduce pkcs7_get_message_sig() and 
verify_pkcs7_message_sig()"
  - In the hypothetical case that there's more than one sinfo, changed
pkcs7_get_message_sig() to return NULL instead of the first sinfo's sig.
  - Dropped Mimi's Reviewed-by because of the code change above.

- Patch "PKCS#7: Introduce pkcs7_get_digest()"
  - New patch.

- Patch "integrity: Introduce integrity_keyring_from_id"
  - Add stub in case CONFIG_INTEGRITY_SIGNATURE isn't set.

- Patch "integrity: Introduce asymmetric_sig_has_known_key()"
  - New patch.

- Patch "ima: Introduce is_ima_sig"
  - New patch, with code from "ima: Improvements in ima_appraise_measurement"

- Patch "ima: Add modsig appraise_type option for module-style appended 

[PATCH] powerpc/xmon: fix dump_segments()

2018-11-16 Thread Christophe Leroy
mfsrin() takes segment num from bits 0-3

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/xmon/xmon.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 36b8dc47a3c3..b2fe422c 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -3502,7 +3502,7 @@ void dump_segments(void)
 
printf("sr0-15 =");
for (i = 0; i < 16; ++i)
-   printf(" %x", mfsrin(i));
+   printf(" %x", mfsrin(i << 28));
printf("\n");
 }
 #endif
-- 
2.13.3



[PATCH] powerpc/book3s/32: fix number of bats in p/v_block_mapped()

2018-11-16 Thread Christophe Leroy
This patch fixes the loop in p_block_mapped() and v_block_mapped()
to scan the entire bat_addrs[] array.

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/mm/ppc_mmu_32.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
index cacc43ee5f15..8e1fdea640cd 100644
--- a/arch/powerpc/mm/ppc_mmu_32.c
+++ b/arch/powerpc/mm/ppc_mmu_32.c
@@ -52,7 +52,7 @@ struct batrange { /* stores address ranges mapped 
by BATs */
 phys_addr_t v_block_mapped(unsigned long va)
 {
int b;
-   for (b = 0; b < 4; ++b)
+   for (b = 0; b < ARRAY_SIZE(bat_addrs); ++b)
if (va >= bat_addrs[b].start && va < bat_addrs[b].limit)
return bat_addrs[b].phys + (va - bat_addrs[b].start);
return 0;
@@ -64,7 +64,7 @@ phys_addr_t v_block_mapped(unsigned long va)
 unsigned long p_block_mapped(phys_addr_t pa)
 {
int b;
-   for (b = 0; b < 4; ++b)
+   for (b = 0; b < ARRAY_SIZE(bat_addrs); ++b)
if (pa >= bat_addrs[b].phys
&& pa < (bat_addrs[b].limit-bat_addrs[b].start)
  +bat_addrs[b].phys)
-- 
2.13.3



[PATCH] powerpc/mm: add exec protection on powerpc 603

2018-11-16 Thread Christophe Leroy
The 603 doesn't have a HASH table, TLB misses are handled by
software. It is then possible to generate page fault when
_PAGE_EXEC is not set like in nohash/32.

In order to support it, set_pte_filter() and
set_access_flags_filter() are made common, and the handling
is made dependent on MMU_FTR_HPTE_TABLE

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/book3s/32/hash.h|  1 +
 arch/powerpc/include/asm/book3s/32/pgtable.h | 18 +-
 arch/powerpc/include/asm/cputable.h  |  8 
 arch/powerpc/kernel/head_32.S|  2 ++
 arch/powerpc/mm/pgtable.c| 20 +++-
 5 files changed, 27 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/32/hash.h 
b/arch/powerpc/include/asm/book3s/32/hash.h
index f2892c7ab73e..2a0a467d2985 100644
--- a/arch/powerpc/include/asm/book3s/32/hash.h
+++ b/arch/powerpc/include/asm/book3s/32/hash.h
@@ -26,6 +26,7 @@
 #define _PAGE_WRITETHRU0x040   /* W: cache write-through */
 #define _PAGE_DIRTY0x080   /* C: page changed */
 #define _PAGE_ACCESSED 0x100   /* R: page referenced */
+#define _PAGE_EXEC 0x200   /* software: exec allowed */
 #define _PAGE_RW   0x400   /* software: user write access allowed */
 #define _PAGE_SPECIAL  0x800   /* software: Special page */
 
diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h 
b/arch/powerpc/include/asm/book3s/32/pgtable.h
index c21d33704633..cf844fed4527 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -10,9 +10,9 @@
 /* And here we include common definitions */
 
 #define _PAGE_KERNEL_RO0
-#define _PAGE_KERNEL_ROX   0
+#define _PAGE_KERNEL_ROX   (_PAGE_EXEC)
 #define _PAGE_KERNEL_RW(_PAGE_DIRTY | _PAGE_RW)
-#define _PAGE_KERNEL_RWX   (_PAGE_DIRTY | _PAGE_RW)
+#define _PAGE_KERNEL_RWX   (_PAGE_DIRTY | _PAGE_RW | _PAGE_EXEC)
 
 #define _PAGE_HPTEFLAGS _PAGE_HASHPTE
 
@@ -66,11 +66,11 @@ static inline bool pte_user(pte_t pte)
  */
 #define PAGE_NONE  __pgprot(_PAGE_BASE)
 #define PAGE_SHARED__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
-#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
+#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | 
_PAGE_EXEC)
 #define PAGE_COPY  __pgprot(_PAGE_BASE | _PAGE_USER)
-#define PAGE_COPY_X__pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_COPY_X__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
 #define PAGE_READONLY  __pgprot(_PAGE_BASE | _PAGE_USER)
-#define PAGE_READONLY_X__pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_READONLY_X__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
 
 /* Permission masks used for kernel mappings */
 #define PAGE_KERNEL__pgprot(_PAGE_BASE | _PAGE_KERNEL_RW)
@@ -318,7 +318,7 @@ static inline void __ptep_set_access_flags(struct 
vm_area_struct *vma,
   int psize)
 {
unsigned long set = pte_val(entry) &
-   (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW);
+   (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
 
pte_update(ptep, 0, set);
 
@@ -384,7 +384,7 @@ static inline int pte_dirty(pte_t pte)  { 
return !!(pte_val(pte) & _PAGE_DIRTY);
 static inline int pte_young(pte_t pte) { return !!(pte_val(pte) & 
_PAGE_ACCESSED); }
 static inline int pte_special(pte_t pte)   { return !!(pte_val(pte) & 
_PAGE_SPECIAL); }
 static inline int pte_none(pte_t pte)  { return (pte_val(pte) & 
~_PTE_NONE_MASK) == 0; }
-static inline bool pte_exec(pte_t pte) { return true; }
+static inline bool pte_exec(pte_t pte) { return pte_val(pte) & 
_PAGE_EXEC; }
 
 static inline int pte_present(pte_t pte)
 {
@@ -451,7 +451,7 @@ static inline pte_t pte_wrprotect(pte_t pte)
 
 static inline pte_t pte_exprotect(pte_t pte)
 {
-   return pte;
+   return __pte(pte_val(pte) & ~_PAGE_EXEC);
 }
 
 static inline pte_t pte_mkclean(pte_t pte)
@@ -466,7 +466,7 @@ static inline pte_t pte_mkold(pte_t pte)
 
 static inline pte_t pte_mkexec(pte_t pte)
 {
-   return pte;
+   return __pte(pte_val(pte) | _PAGE_EXEC);
 }
 
 static inline pte_t pte_mkpte(pte_t pte)
diff --git a/arch/powerpc/include/asm/cputable.h 
b/arch/powerpc/include/asm/cputable.h
index 29f49a35d6ee..a0395ccbbe9e 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -296,7 +296,7 @@ static inline void cpu_feature_keys_init(void) { }
 #define CPU_FTRS_PPC601(CPU_FTR_COMMON | CPU_FTR_601 | \
CPU_FTR_COHERENT_ICACHE | CPU_FTR_UNIFIED_ID_CACHE | CPU_FTR_USE_RTC)
 #define CPU_FTRS_603   (CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | \
-   CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_PPC_LE)
+   CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_PPC_LE | CPU_FTR_NOEXECUTE)
 #define CPU_FTRS_604   (CPU_FTR_COMMON | CPU_FTR_PPC_LE)
 #define CPU_FTRS_740_NOTAU (CPU_FTR_COMMON | \
   

[PATCH] powerpc/mm: Eliminate not possible mmu features at compile time

2018-11-16 Thread Christophe Leroy
Depending on the CONFIG selected, many of the MMU features are
not possible. Lets only get the possible ones in MMU_FTRS_POSSIBLE.

This allows gcc to get rid at compile time of code related to
not possible features.

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/mmu.h | 31 ++-
 1 file changed, 26 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index eb20eb3b8fb0..b13d8e571dd9 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -131,16 +131,37 @@ DECLARE_PER_CPU(int, next_tlbcam_idx);
 #endif
 
 enum {
-   MMU_FTRS_POSSIBLE = MMU_FTR_HPTE_TABLE | MMU_FTR_TYPE_8xx |
-   MMU_FTR_TYPE_40x | MMU_FTR_TYPE_44x | MMU_FTR_TYPE_FSL_E |
-   MMU_FTR_TYPE_47x | MMU_FTR_USE_HIGH_BATS | MMU_FTR_BIG_PHYS |
-   MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_USE_TLBILX |
-   MMU_FTR_LOCK_BCAST_INVAL | MMU_FTR_NEED_DTLB_SW_LRU |
+   MMU_FTRS_POSSIBLE =
+#ifdef CONFIG_PPC_BOOK3S
+   MMU_FTR_HPTE_TABLE |
+#endif
+#ifdef CONFIG_PPC_8xx
+   MMU_FTR_TYPE_8xx |
+#endif
+#ifdef CONFIG_40x
+   MMU_FTR_TYPE_40x |
+#endif
+#ifdef CONFIG_44x
+   MMU_FTR_TYPE_44x |
+#endif
+#if defined(CONFIG_E200) || defined(CONFIG_E500)
+   MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS | MMU_FTR_USE_TLBILX |
+#endif
+#ifdef CONFIG_PPC_47x
+   MMU_FTR_TYPE_47x | MMU_FTR_USE_TLBIVAX_BCAST | 
MMU_FTR_LOCK_BCAST_INVAL |
+#endif
+#ifdef CONFIG_PPC_BOOK3S_32
+   MMU_FTR_USE_HIGH_BATS | MMU_FTR_NEED_DTLB_SW_LRU |
+#endif
+#ifdef CONFIG_PPC_BOOK3E_64
MMU_FTR_USE_TLBRSRV | MMU_FTR_USE_PAIRED_MAS |
+#endif
+#ifdef CONFIG_PPC_BOOK3S_64
MMU_FTR_NO_SLBIE_B | MMU_FTR_16M_PAGE | MMU_FTR_TLBIEL |
MMU_FTR_LOCKLESS_TLBIE | MMU_FTR_CI_LARGE_PAGE |
MMU_FTR_1T_SEGMENT | MMU_FTR_TLBIE_CROP_VA |
MMU_FTR_KERNEL_RO | MMU_FTR_68_BIT_VA |
+#endif
 #ifdef CONFIG_PPC_RADIX_MMU
MMU_FTR_TYPE_RADIX |
 #endif
-- 
2.13.3



[PATCH] powerpc/mm: dump segment registers on book3s/32

2018-11-16 Thread Christophe Leroy
This patch creates a debugfs file to see content of
segment registers

~# cat /sys/kernel/debug/segment_registers
---[ User Segments ]---
0x-0x0fff Kern key 1 User key 1 VSID 0xade2b0
0x1000-0x1fff Kern key 1 User key 1 VSID 0xade3c1
0x2000-0x2fff Kern key 1 User key 1 VSID 0xade4d2
0x3000-0x3fff Kern key 1 User key 1 VSID 0xade5e3
0x4000-0x4fff Kern key 1 User key 1 VSID 0xade6f4
0x5000-0x5fff Kern key 1 User key 1 VSID 0xade805
0x6000-0x6fff Kern key 1 User key 1 VSID 0xade916
0x7000-0x7fff Kern key 1 User key 1 VSID 0xadea27
0x8000-0x8fff Kern key 1 User key 1 VSID 0xadeb38
0x9000-0x9fff Kern key 1 User key 1 VSID 0xadec49
0xa000-0xafff Kern key 1 User key 1 VSID 0xaded5a
0xb000-0xbfff Kern key 1 User key 1 VSID 0xadee6b

---[ Kernel Segments ]---
0xc000-0xcfff Kern key 0 User key 1 VSID 0x000ccc
0xd000-0xdfff Kern key 0 User key 1 VSID 0x000ddd
0xe000-0xefff Kern key 0 User key 1 VSID 0x000eee
0xf000-0x Kern key 0 User key 1 VSID 0x000fff

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/mm/Makefile  |  2 +-
 arch/powerpc/mm/dump_sr.c | 64 +++
 2 files changed, 65 insertions(+), 1 deletion(-)
 create mode 100644 arch/powerpc/mm/dump_sr.c

diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index 2adad10b5856..cf3e99ceb420 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -47,7 +47,7 @@ ifdef CONFIG_PPC_PTDUMP
 obj-$(CONFIG_4xx)  += dump_linuxpagetables-generic.o
 obj-$(CONFIG_PPC_8xx)  += dump_linuxpagetables-8xx.o
 obj-$(CONFIG_PPC_BOOK3E_MMU)   += dump_linuxpagetables-generic.o
-obj-$(CONFIG_PPC_BOOK3S_32)+= dump_linuxpagetables-generic.o dump_bats.o
+obj-$(CONFIG_PPC_BOOK3S_32)+= dump_linuxpagetables-generic.o dump_bats.o 
dump_sr.o
 obj-$(CONFIG_PPC_BOOK3S_64)+= dump_linuxpagetables-book3s64.o
 endif
 obj-$(CONFIG_PPC_HTDUMP)   += dump_hashpagetable.o
diff --git a/arch/powerpc/mm/dump_sr.c b/arch/powerpc/mm/dump_sr.c
new file mode 100644
index ..057b60bcb6fc
--- /dev/null
+++ b/arch/powerpc/mm/dump_sr.c
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018, Christophe Leroy CS S.I.
+ * 
+ *
+ * This dumps the content of Segment Registers
+ */
+
+#include 
+
+static void seg_show(struct seq_file *m, int i)
+{
+   u32 val = mfsrin(i << 28);
+
+   seq_printf(m, "0x%01x000-0x%01xfff ", i, i);
+   seq_printf(m, "Kern key %d ", (val >> 30) & 1);
+   seq_printf(m, "User key %d ", (val >> 29) & 1);
+   if (val & 0x8000) {
+   seq_printf(m, "Device 0x%03x", (val >> 20) & 0x1ff);
+   seq_printf(m, "-0x%05x", val & 0xf);
+   } else {
+   if (val & 0x1000)
+   seq_puts(m, "No Exec ");
+   seq_printf(m, "VSID 0x%06x", val & 0xff);
+   }
+   seq_puts(m, "\n");
+}
+
+static int sr_show(struct seq_file *m, void *v)
+{
+   int i;
+
+   seq_puts(m, "---[ User Segments ]---\n");
+   for (i = 0; i < TASK_SIZE >> 28; i++)
+   seg_show(m, i);
+
+   seq_puts(m, "\n---[ Kernel Segments ]---\n");
+   for (; i < 16; i++)
+   seg_show(m, i);
+
+   return 0;
+}
+
+static int sr_open(struct inode *inode, struct file *file)
+{
+   return single_open(file, sr_show, NULL);
+}
+
+static const struct file_operations sr_fops = {
+   .open   = sr_open,
+   .read   = seq_read,
+   .llseek = seq_lseek,
+   .release= single_release,
+};
+
+static int sr_init(void)
+{
+   struct dentry *debugfs_file;
+
+   debugfs_file = debugfs_create_file("segment_registers", 0400,
+  NULL, NULL, _fops);
+   return debugfs_file ? 0 : -ENOMEM;
+}
+device_initcall(sr_init);
-- 
2.13.3



[PATCH v2] powerpc/mm: dump block address translation on book3s/32

2018-11-16 Thread Christophe Leroy
This patch adds a debugfs file to dump block address translation:

~# cat /sys/kernel/debug/block_address_translation
Instruction Block Address Translations:
0: -
1: -
2: 0xc000-0xcfff 0x Kernel EXEC coherent
3: 0xd000-0xdfff 0x1000 Kernel EXEC coherent
4: -
5: -
6: -
7: -

Data Block Address Translations:
0: -
1: -
2: 0xc000-0xcfff 0x Kernel RW coherent
3: 0xd000-0xdfff 0x1000 Kernel RW coherent
4: -
5: -
6: -
7: -

Signed-off-by: Christophe Leroy 
---
 Fixed phys address display for CONFIG_PHYS_64BIT

 arch/powerpc/include/asm/book3s/32/mmu-hash.h |   4 +
 arch/powerpc/mm/Makefile  |   2 +-
 arch/powerpc/mm/dump_bats.c   | 184 ++
 3 files changed, 189 insertions(+), 1 deletion(-)
 create mode 100644 arch/powerpc/mm/dump_bats.c

diff --git a/arch/powerpc/include/asm/book3s/32/mmu-hash.h 
b/arch/powerpc/include/asm/book3s/32/mmu-hash.h
index e38c91388c40..f32fd1b14cf0 100644
--- a/arch/powerpc/include/asm/book3s/32/mmu-hash.h
+++ b/arch/powerpc/include/asm/book3s/32/mmu-hash.h
@@ -34,8 +34,12 @@
 #define BAT_PHYS_ADDR(x) ((u32)((x & 0xfffeULL) | \
((x & 0x000eULL) >> 24) | \
((x & 0x0001ULL) >> 30)))
+#define PHYS_BAT_ADDR(x) (((u64)(x) & 0xfffeULL) | \
+ (((u64)(x) << 24) & 0x000eULL) | \
+ (((u64)(x) << 30) & 0x0001ULL))
 #else
 #define BAT_PHYS_ADDR(x) (x)
+#define PHYS_BAT_ADDR(x) (x)
 #endif
 
 struct ppc_bat {
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index ca96e7be4d0e..2adad10b5856 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -47,7 +47,7 @@ ifdef CONFIG_PPC_PTDUMP
 obj-$(CONFIG_4xx)  += dump_linuxpagetables-generic.o
 obj-$(CONFIG_PPC_8xx)  += dump_linuxpagetables-8xx.o
 obj-$(CONFIG_PPC_BOOK3E_MMU)   += dump_linuxpagetables-generic.o
-obj-$(CONFIG_PPC_BOOK3S_32)+= dump_linuxpagetables-generic.o
+obj-$(CONFIG_PPC_BOOK3S_32)+= dump_linuxpagetables-generic.o dump_bats.o
 obj-$(CONFIG_PPC_BOOK3S_64)+= dump_linuxpagetables-book3s64.o
 endif
 obj-$(CONFIG_PPC_HTDUMP)   += dump_hashpagetable.o
diff --git a/arch/powerpc/mm/dump_bats.c b/arch/powerpc/mm/dump_bats.c
new file mode 100644
index ..4687414e39fc
--- /dev/null
+++ b/arch/powerpc/mm/dump_bats.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018, Christophe Leroy CS S.I.
+ * 
+ *
+ * This dumps the content of BATS
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+static char *pp_601(int k, int pp)
+{
+   if (pp == 0)
+   return k ? "NA" : "RWX";
+   if (pp == 1)
+   return k ? "ROX" : "RWX";
+   if (pp == 2)
+   return k ? "RWX" : "RWX";
+   return k ? "ROX" : "ROX";
+}
+
+static void bat_show_601(struct seq_file *m, int idx, u32 lower, u32 upper)
+{
+   u32 blpi = upper & 0xfffe;
+   u32 k = (upper >> 2) & 3;
+   u32 pp = upper & 3;
+   phys_addr_t pbn = PHYS_BAT_ADDR(lower);
+   u32 bsm = lower & 0x3ff;
+   u32 size = (bsm + 1) << 17;
+
+   seq_printf(m, "%d: ", idx);
+   if (!(lower & 0x40)) {
+   seq_puts(m, "-\n");
+   return;
+   }
+
+   seq_printf(m, "0x%08x-0x%08x ", blpi, blpi + size - 1);
+#ifdef CONFIG_PHYS_64BIT
+   seq_printf(m, "0x%016llx ", pbn);
+#else
+   seq_printf(m, "0x%08x ", pbn);
+#endif
+
+   seq_printf(m, "Kernel %s User %s", pp_601(k & 2, pp), pp_601(k & 1, 
pp));
+
+   if (lower & _PAGE_WRITETHRU)
+   seq_puts(m, "write through ");
+   if (lower & _PAGE_NO_CACHE)
+   seq_puts(m, "no cache ");
+   if (lower & _PAGE_COHERENT)
+   seq_puts(m, "coherent ");
+   seq_puts(m, "\n");
+}
+
+#define BAT_SHOW_601(_m, _n, _l, _u) bat_show_601(_m, _n, mfspr(_l), mfspr(_u))
+
+static int bats_show_601(struct seq_file *m, void *v)
+{
+   seq_puts(m, "Block Address Translation:\n");
+
+   BAT_SHOW_601(m, 0, SPRN_IBAT0L, SPRN_IBAT0U);
+   BAT_SHOW_601(m, 1, SPRN_IBAT1L, SPRN_IBAT1U);
+   BAT_SHOW_601(m, 2, SPRN_IBAT2L, SPRN_IBAT2U);
+   BAT_SHOW_601(m, 3, SPRN_IBAT3L, SPRN_IBAT3U);
+
+   return 0;
+}
+
+static void bat_show_603(struct seq_file *m, int idx, u32 lower, u32 upper, 
bool is_d)
+{
+   u32 bepi = upper & 0xfffe;
+   u32 bl = (upper >> 2) & 0x7ff;
+   u32 k = upper & 3;
+   phys_addr_t brpn = PHYS_BAT_ADDR(lower);
+   u32 size = (bl + 1) << 17;
+
+   seq_printf(m, "%d: ", idx);
+   if (k == 0) {
+   seq_puts(m, "-\n");
+   return;
+   

Re: [PATCH] powerpc/64: Fix kernel stack 16-byte alignment

2018-11-16 Thread Michael Ellerman
Sandipan Das  writes:

> On 15/11/18 8:04 AM, Nicholas Piggin wrote:
>> Commit 4c2de74cc869 ("powerpc/64: Interrupts save PPR on stack rather
>> than thread_struct") changed sizeof(struct pt_regs) % 16 from 0 to 8,
>> which causes the interrupt frame allocation on kernel entry to put the
>> kernel stack out of alignment.
>> 
>> Add a pad field to fix alignment, and add a BUILD_BUG_ON to catch this
>> in future.
>> 
>> Fixes: 4c2de74cc869 ("powerpc/64: Interrupts save PPR on stack rather
>> than thread_struct")
>> Signed-off-by: Nicholas Piggin 
>> [...]
>
> Thanks for fixing this. Commit 4c2de74cc869 ("powerpc/64: Interrupts save
> PPR on stack rather than thread_struct") was also leading to incorrect
> kernel stack traces.

OK thanks.

In future if you see something weird like that please report it to the
list.

cheers

> E.g.
> If you are using `perf record -g` and expect to see a stack trace like this:
>
> c02b19a0 bpf_check+0x1910 
> (/usr/lib/debug/lib/modules/4.18.17-200.fc28.ppc64le/vmlinux)
> c02a5554 bpf_prog_load+0x684 
> (/usr/lib/debug/lib/modules/4.18.17-200.fc28.ppc64le/vmlinux)
> c02a6938 sys_bpf+0xaf8 
> (/usr/lib/debug/lib/modules/4.18.17-200.fc28.ppc64le/vmlinux)
> c000b9e4 system_call+0x5c 
> (/usr/lib/debug/lib/modules/4.18.17-200.fc28.ppc64le/vmlinux)
> 7fff815bca90 syscall+0x50 (/usr/lib64/libc-2.27.so)
> 7fff7d96ee0c bpf_prog_load+0x16c (/usr/lib64/libbcc.so.0.7.0)
> [...]
>
> you would instead see something like this:
>
> c02bdb88 bpf_check+0xb88 
> (/lib/modules/4.20.0-rc1+/build/vmlinux)
> c02bdb60 bpf_check+0xb60 
> (/lib/modules/4.20.0-rc1+/build/vmlinux)
> 3fff8f350a90 syscall+0x50 (/usr/lib64/libc-2.27.so)
> 3fff8b788e0c bpf_prog_load+0x16c (/usr/lib64/libbcc.so.0.7.0)
> [...]
>
> --
> With Regards,
> Sandipan


Re: [PATCH v2] powerpc/ptrace: replace ptrace_report_syscall() with a tracehook call

2018-11-16 Thread Michael Ellerman
Elvira Khabirova  writes:

> Arch code should use tracehook_*() helpers, as documented
> in include/linux/tracehook.h.

Thanks.

It probably also should have a comment explaining why we're ignoring the
return value and why that's OK.

cheers

> Fixes: 5521eb4bca2d ("powerpc/ptrace: Add support for PTRACE_SYSEMU")
> Signed-off-by: Elvira Khabirova 
> ---
>  arch/powerpc/kernel/ptrace.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
> index afb819f4ca68..d79d907f9acc 100644
> --- a/arch/powerpc/kernel/ptrace.c
> +++ b/arch/powerpc/kernel/ptrace.c
> @@ -3266,7 +3266,7 @@ long do_syscall_trace_enter(struct pt_regs *regs)
>   user_exit();
>  
>   if (test_thread_flag(TIF_SYSCALL_EMU)) {
> - ptrace_report_syscall(regs);
> + (void) tracehook_report_syscall_entry(regs);
>   /*
>* Returning -1 will skip the syscall execution. We want to
>* avoid clobbering any register also, thus, not 'gotoing'
> -- 
> 2.19.1


RE: [PATCH 0/2] PCI/AER: Consistently use _OSC to determine who owns AER

2018-11-16 Thread David Laight
From: Alexandru Gagniuc
> Sent: 15 November 2018 23:16
...
> I've asked around a few people at Dell and they unanimously agree that
> _OSC is the correct way to determine ownership of AER.

This is all very well, but we have systems (they might be Dell ones)
where failure of a PCIe link (even when all the drivers are removed)
causes an NMI - and crashes the kernel.

There are other systems which have AER registers available for
some of the PCIe devices, but the BIOS ignores them and _OSC
doesn't let the kernel take control.
In this case the AER registers can contain useful information
after a read returns ~0u.
It would be useful to be able to get this information without
having to grovel through all the PCIe config space.

David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, 
UK
Registration No: 1397386 (Wales)



[GIT PULL] Please pull powerpc/linux.git powerpc-4.20-3 tag

2018-11-16 Thread Michael Ellerman
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Hi Linus,

Please pull some more powerpc fixes for 4.20:

The following changes since commit 651022382c7f8da46cb4872a545ee1da6d097d2a:

  Linux 4.20-rc1 (2018-11-04 15:37:52 -0800)

are available in the git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git 
tags/powerpc-4.20-3

for you to fetch changes up to b2fed34a628df6118b5d4e13f49a33e15f704fa9:

  selftests/powerpc: Adjust wild_bctr to build with old binutils (2018-11-15 
23:05:17 +1100)

- --
powerpc fixes for 4.20 #3

Two weeks worth of fixes since rc1.

 - I broke 16-byte alignment of the stack when we moved PPR into pt_regs.
   Despite being required by the ABI this broke almost nothing, we eventually
   hit it in code where GCC does arithmetic on the stack pointer assuming the
   bottom 4 bits are clear. Fix it by padding the in-kernel pt_regs by 8 bytes.

 - A couple of commits fixing minor bugs in the recent SLB rewrite.

 - A build fix related to tracepoints in KVM in some configurations.

 - Our old "IO workarounds" code written for Cell couldn't coexist in a kernel
   that runs on Power9 with the Radix MMU, fix that.

 - Remove the NPU DMA ops, these just printed a warning and should never have
   been called.

 - Suppress an overly chatty message triggered by CPU hotplug in some configs.

 - Two small selftest fixes.

Thanks to:
  Alistair Popple, Gustavo Romero, Nicholas Piggin, Satheesh Rajendran, Scott 
Wood.

- --
Alistair Popple (1):
  powerpc/powernv/npu: Remove NPU DMA ops

Gustavo Romero (1):
  selftests/powerpc: Adjust wild_bctr to build with old binutils

Michael Ellerman (6):
  powerpc/mm/64s: Consolidate SLB assertions
  powerpc/mm/64s: Use PPC_SLBFEE macro
  powerpc/mm/64s: Only use slbfee on CPUs that support it
  powerpc/mm/64s: Fix preempt warning in slb_allocate_kernel()
  powerpc/io: Fix the IO workarounds code to work with Radix
  selftests/powerpc: Fix wild_bctr test to work on ppc64

Nicholas Piggin (1):
  powerpc/64: Fix kernel stack 16-byte alignment

Satheesh Rajendran (1):
  powerpc/numa: Suppress "VPHN is not supported" messages

Scott Wood (1):
  KVM: PPC: Move and undef TRACE_INCLUDE_PATH/FILE


 arch/powerpc/include/asm/io.h  | 20 +++-
 arch/powerpc/include/asm/ppc-opcode.h  |  2 +
 arch/powerpc/include/asm/ptrace.h  |  1 +
 arch/powerpc/kernel/setup_64.c |  2 +
 arch/powerpc/kvm/trace.h   |  8 +++-
 arch/powerpc/kvm/trace_booke.h |  9 +++-
 arch/powerpc/kvm/trace_hv.h|  9 +++-
 arch/powerpc/kvm/trace_pr.h|  9 +++-
 arch/powerpc/mm/numa.c |  2 +-
 arch/powerpc/mm/slb.c  | 35 ++
 arch/powerpc/platforms/powernv/npu-dma.c   | 64 ++
 tools/testing/selftests/powerpc/mm/wild_bctr.c | 21 +++--
 12 files changed, 76 insertions(+), 106 deletions(-)
-BEGIN PGP SIGNATURE-

iQIcBAEBAgAGBQJb7rB9AAoJEFHr6jzI4aWA7uYP/2bbEUaIpGw2OP5AxedSWtIh
7RBX5rtzC8sA+ifpI7utcz8woOH+8HmzXf3f0BsjLlDZO61dCBzPM8yEkgiHmEMH
t1ApMKCUkwTI1R+1somVhyV2fYct+Eb9Qa929IIKqgC5r8nElYqaE7jr56U7jFQE
TZwMoeThTGxfXMa+IuSWLGtvbUeC6LtKoWjoynnZQC4RMQqKRc8xaRpN5W//ZQyq
dtQ8kc9UWrSl5xj5ah/evn/0oWl1cSX95juO00rGsTL5iuUQNcUVZcJAmwoiPAN/
GCNYDLqEX8SwzKidnAmTR6AUBSLP48kGKrUwjMZVfvT0SMNyIL9lq9u6N5ucyq+u
b0HLMrlqZiYasL3fsKHo+dbJ1emzZdjMIYNe/x+6GAgfBTvRePkqVwLgB1uSOjdr
k41aDRaoagOUbIs6y6tXHyp/mFbP3VswBA9n1ZGjr/KsgrlBQftCTOeSuPKSdAf+
WKrzakoj4SIvOZdUGbttb0HJHFHE5xCGIzGH7NaO/AyfFzkIZjq86TU4skqN0nQw
lgHNA9QgXlpBMwRvEBM28FW058bsVw7Dgez/vJijlEQNC7fi6TDJTzYiroBEdmF4
82FEUU9ZECw+zb6OI7E3VntTqWdM8E3qCGI9tLoCrFpoagERHfayTTsW7iQJ/Scj
dTL6b40yqw88T+myURIZ
=lNgM
-END PGP SIGNATURE-


[PATCH v2] powerpc/ptrace: replace ptrace_report_syscall() with a tracehook call

2018-11-16 Thread Elvira Khabirova
Arch code should use tracehook_*() helpers, as documented
in include/linux/tracehook.h.

Fixes: 5521eb4bca2d ("powerpc/ptrace: Add support for PTRACE_SYSEMU")
Signed-off-by: Elvira Khabirova 
---
 arch/powerpc/kernel/ptrace.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index afb819f4ca68..d79d907f9acc 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -3266,7 +3266,7 @@ long do_syscall_trace_enter(struct pt_regs *regs)
user_exit();
 
if (test_thread_flag(TIF_SYSCALL_EMU)) {
-   ptrace_report_syscall(regs);
+   (void) tracehook_report_syscall_entry(regs);
/*
 * Returning -1 will skip the syscall execution. We want to
 * avoid clobbering any register also, thus, not 'gotoing'
-- 
2.19.1



[PATCH 10/10] perf/doc: update design.txt for exclude_{host|guest} flags

2018-11-16 Thread Andrew Murray
Update design.txt to reflect the presence of the exclude_host
and exclude_guest perf flags.

Signed-off-by: Andrew Murray 
---
 tools/perf/design.txt | 4 
 1 file changed, 4 insertions(+)

diff --git a/tools/perf/design.txt b/tools/perf/design.txt
index a28dca2..7de7d83 100644
--- a/tools/perf/design.txt
+++ b/tools/perf/design.txt
@@ -222,6 +222,10 @@ The 'exclude_user', 'exclude_kernel' and 'exclude_hv' bits 
provide a
 way to request that counting of events be restricted to times when the
 CPU is in user, kernel and/or hypervisor mode.
 
+Furthermore the 'exclude_host' and 'exclude_guest' bits provide a way
+to request counting of events restricted to guest and host contexts when
+using virtualisation.
+
 The 'mmap' and 'munmap' bits allow recording of PROT_EXEC mmap/munmap
 operations, these can be used to relate userspace IP addresses to actual
 code, even after the mapping (or even the whole process) is gone,
-- 
2.7.4



[PATCH 09/10] drivers/perf: perf/core: generalise event exclusion checking with perf macro

2018-11-16 Thread Andrew Murray
Replace checking of perf event exclusion flags with perf macro.

This is a functional change as exclude_host and exclude_guest are added
in the following files:

 - drivers/perf/qcom_l2_pmu.c
 - drivers/perf/qcom_l3_pmu.c
 - drivers/perf/arm_pmu.c

And exclude_idle and exclude_hv are added in these files:

 - drivers/perf/xgene_pmu.c

Signed-off-by: Andrew Murray 
---
 drivers/perf/arm-cci.c   | 7 +--
 drivers/perf/arm-ccn.c   | 5 +
 drivers/perf/arm_dsu_pmu.c   | 7 +--
 drivers/perf/arm_pmu.c   | 9 +
 drivers/perf/hisilicon/hisi_uncore_pmu.c | 7 +--
 drivers/perf/qcom_l2_pmu.c   | 3 +--
 drivers/perf/qcom_l3_pmu.c   | 3 +--
 drivers/perf/xgene_pmu.c | 3 +--
 8 files changed, 8 insertions(+), 36 deletions(-)

diff --git a/drivers/perf/arm-cci.c b/drivers/perf/arm-cci.c
index 1bfeb16..d749f19 100644
--- a/drivers/perf/arm-cci.c
+++ b/drivers/perf/arm-cci.c
@@ -1328,12 +1328,7 @@ static int cci_pmu_event_init(struct perf_event *event)
return -EOPNOTSUPP;
 
/* We have no filtering of any kind */
-   if (event->attr.exclude_user||
-   event->attr.exclude_kernel  ||
-   event->attr.exclude_hv  ||
-   event->attr.exclude_idle||
-   event->attr.exclude_host||
-   event->attr.exclude_guest)
+   if (event_has_exclude_flags(event))
return -EINVAL;
 
/*
diff --git a/drivers/perf/arm-ccn.c b/drivers/perf/arm-ccn.c
index 7dd850e..9a22a95 100644
--- a/drivers/perf/arm-ccn.c
+++ b/drivers/perf/arm-ccn.c
@@ -741,10 +741,7 @@ static int arm_ccn_pmu_event_init(struct perf_event *event)
return -EOPNOTSUPP;
}
 
-   if (has_branch_stack(event) || event->attr.exclude_user ||
-   event->attr.exclude_kernel || event->attr.exclude_hv ||
-   event->attr.exclude_idle || event->attr.exclude_host ||
-   event->attr.exclude_guest) {
+   if (has_branch_stack(event) || event_has_exclude_flags(event)) {
dev_dbg(ccn->dev, "Can't exclude execution levels!\n");
return -EINVAL;
}
diff --git a/drivers/perf/arm_dsu_pmu.c b/drivers/perf/arm_dsu_pmu.c
index 660cb8a..300ff3d 100644
--- a/drivers/perf/arm_dsu_pmu.c
+++ b/drivers/perf/arm_dsu_pmu.c
@@ -563,12 +563,7 @@ static int dsu_pmu_event_init(struct perf_event *event)
}
 
if (has_branch_stack(event) ||
-   event->attr.exclude_user ||
-   event->attr.exclude_kernel ||
-   event->attr.exclude_hv ||
-   event->attr.exclude_idle ||
-   event->attr.exclude_host ||
-   event->attr.exclude_guest) {
+   event_has_exclude_flags(event)) {
dev_dbg(dsu_pmu->pmu.dev, "Can't support filtering\n");
return -EINVAL;
}
diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
index 7f01f6f..a03634f 100644
--- a/drivers/perf/arm_pmu.c
+++ b/drivers/perf/arm_pmu.c
@@ -357,13 +357,6 @@ static irqreturn_t armpmu_dispatch_irq(int irq, void *dev)
 }
 
 static int
-event_requires_mode_exclusion(struct perf_event_attr *attr)
-{
-   return attr->exclude_idle || attr->exclude_user ||
-  attr->exclude_kernel || attr->exclude_hv;
-}
-
-static int
 __hw_perf_event_init(struct perf_event *event)
 {
struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
@@ -395,7 +388,7 @@ __hw_perf_event_init(struct perf_event *event)
 */
if ((!armpmu->set_event_filter ||
 armpmu->set_event_filter(hwc, >attr)) &&
-event_requires_mode_exclusion(>attr)) {
+event_has_exclude_flags(event)) {
pr_debug("ARM performance counters do not support "
 "mode exclusion\n");
return -EOPNOTSUPP;
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c 
b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index 9efd241..d3edff9 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -143,12 +143,7 @@ int hisi_uncore_pmu_event_init(struct perf_event *event)
return -EOPNOTSUPP;
 
/* counters do not have these bits */
-   if (event->attr.exclude_user||
-   event->attr.exclude_kernel  ||
-   event->attr.exclude_host||
-   event->attr.exclude_guest   ||
-   event->attr.exclude_hv  ||
-   event->attr.exclude_idle)
+   if (event_has_exclude_flags(event))
return -EINVAL;
 
/*
diff --git a/drivers/perf/qcom_l2_pmu.c b/drivers/perf/qcom_l2_pmu.c
index 842135c..d7d85a2 100644
--- a/drivers/perf/qcom_l2_pmu.c
+++ b/drivers/perf/qcom_l2_pmu.c
@@ -510,8 +510,7 @@ static int l2_cache_event_init(struct perf_event *event)
}
 
/* We cannot filter accurately so we just don't allow it. */
-   if 

[PATCH 08/10] perf/core: Remove unused perf_flags

2018-11-16 Thread Andrew Murray
Now that perf_flags is not used we remove it.

Signed-off-by: Andrew Murray 
---
 include/uapi/linux/perf_event.h   | 2 --
 tools/include/uapi/linux/perf_event.h | 2 --
 2 files changed, 4 deletions(-)

diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index f35eb72..ba89bd3 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -445,8 +445,6 @@ struct perf_event_query_bpf {
__u32   ids[0];
 };
 
-#define perf_flags(attr)   (*(&(attr)->read_format + 1))
-
 /*
  * Ioctls that can be done on a perf event fd:
  */
diff --git a/tools/include/uapi/linux/perf_event.h 
b/tools/include/uapi/linux/perf_event.h
index f35eb72..ba89bd3 100644
--- a/tools/include/uapi/linux/perf_event.h
+++ b/tools/include/uapi/linux/perf_event.h
@@ -445,8 +445,6 @@ struct perf_event_query_bpf {
__u32   ids[0];
 };
 
-#define perf_flags(attr)   (*(&(attr)->read_format + 1))
-
 /*
  * Ioctls that can be done on a perf event fd:
  */
-- 
2.7.4



[PATCH 07/10] x86: perf/core: generalise event exclusion checking with perf macro

2018-11-16 Thread Andrew Murray
Replace checking of perf event exclusion flags with perf macro.

This is a functional change as exclude_host and exclude_guest are
added in these files:

arch/x86/events/intel/uncore.c

and exclude_idle and exclude_hv are added in these files:

arch/x86/events/amd/iommu.c
arch/x86/events/amd/uncore.c

Signed-off-by: Andrew Murray 
---
 arch/x86/events/amd/ibs.c  | 11 +--
 arch/x86/events/amd/iommu.c|  3 +--
 arch/x86/events/amd/power.c|  8 +---
 arch/x86/events/amd/uncore.c   |  3 +--
 arch/x86/events/intel/cstate.c |  7 +--
 arch/x86/events/intel/rapl.c   |  7 +--
 arch/x86/events/intel/uncore.c |  3 +--
 arch/x86/events/intel/uncore_snb.c |  7 +--
 arch/x86/events/msr.c  |  7 +--
 9 files changed, 9 insertions(+), 47 deletions(-)

diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
index d50bb4d..a51981c 100644
--- a/arch/x86/events/amd/ibs.c
+++ b/arch/x86/events/amd/ibs.c
@@ -253,15 +253,6 @@ static int perf_ibs_precise_event(struct perf_event 
*event, u64 *config)
return -EOPNOTSUPP;
 }
 
-static const struct perf_event_attr ibs_notsupp = {
-   .exclude_user   = 1,
-   .exclude_kernel = 1,
-   .exclude_hv = 1,
-   .exclude_idle   = 1,
-   .exclude_host   = 1,
-   .exclude_guest  = 1,
-};
-
 static int perf_ibs_init(struct perf_event *event)
 {
struct hw_perf_event *hwc = >hw;
@@ -282,7 +273,7 @@ static int perf_ibs_init(struct perf_event *event)
if (event->pmu != _ibs->pmu)
return -ENOENT;
 
-   if (perf_flags(>attr) & perf_flags(_notsupp))
+   if (event_has_exclude_flags(event))
return -EINVAL;
 
if (config & ~perf_ibs->config_mask)
diff --git a/arch/x86/events/amd/iommu.c b/arch/x86/events/amd/iommu.c
index 3210fee..fa7541b 100644
--- a/arch/x86/events/amd/iommu.c
+++ b/arch/x86/events/amd/iommu.c
@@ -224,8 +224,7 @@ static int perf_iommu_event_init(struct perf_event *event)
return -EINVAL;
 
/* IOMMU counters do not have usr/os/guest/host bits */
-   if (event->attr.exclude_user || event->attr.exclude_kernel ||
-   event->attr.exclude_host || event->attr.exclude_guest)
+   if (event_has_exclude_flags(event))
return -EINVAL;
 
if (event->cpu < 0)
diff --git a/arch/x86/events/amd/power.c b/arch/x86/events/amd/power.c
index 2aefacf..4129fbe 100644
--- a/arch/x86/events/amd/power.c
+++ b/arch/x86/events/amd/power.c
@@ -136,13 +136,7 @@ static int pmu_event_init(struct perf_event *event)
return -ENOENT;
 
/* Unsupported modes and filters. */
-   if (event->attr.exclude_user   ||
-   event->attr.exclude_kernel ||
-   event->attr.exclude_hv ||
-   event->attr.exclude_idle   ||
-   event->attr.exclude_host   ||
-   event->attr.exclude_guest  ||
-   /* no sampling */
+   if (event_has_exclude_flags(event) ||
event->attr.sample_period)
return -EINVAL;
 
diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c
index 8671de1..c2015c7 100644
--- a/arch/x86/events/amd/uncore.c
+++ b/arch/x86/events/amd/uncore.c
@@ -202,8 +202,7 @@ static int amd_uncore_event_init(struct perf_event *event)
return -EINVAL;
 
/* NB and Last level cache counters do not have usr/os/guest/host bits 
*/
-   if (event->attr.exclude_user || event->attr.exclude_kernel ||
-   event->attr.exclude_host || event->attr.exclude_guest)
+   if (event_has_exclude_flags(event))
return -EINVAL;
 
/* and we do not enable counter overflow interrupts */
diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c
index 9f8084f..9366833 100644
--- a/arch/x86/events/intel/cstate.c
+++ b/arch/x86/events/intel/cstate.c
@@ -280,12 +280,7 @@ static int cstate_pmu_event_init(struct perf_event *event)
return -ENOENT;
 
/* unsupported modes and filters */
-   if (event->attr.exclude_user   ||
-   event->attr.exclude_kernel ||
-   event->attr.exclude_hv ||
-   event->attr.exclude_idle   ||
-   event->attr.exclude_host   ||
-   event->attr.exclude_guest  ||
+   if (event_has_exclude_flags(event) ||
event->attr.sample_period) /* no sampling */
return -EINVAL;
 
diff --git a/arch/x86/events/intel/rapl.c b/arch/x86/events/intel/rapl.c
index 32f3e94..428d40c 100644
--- a/arch/x86/events/intel/rapl.c
+++ b/arch/x86/events/intel/rapl.c
@@ -397,12 +397,7 @@ static int rapl_pmu_event_init(struct perf_event *event)
return -EINVAL;
 
/* unsupported modes and filters */
-   if (event->attr.exclude_user   ||
-   event->attr.exclude_kernel ||
-   event->attr.exclude_hv ||
-   event->attr.exclude_idle   ||
-   event->attr.exclude_host   ||
-   

[PATCH 06/10] alpha: perf/core: generalise event exclusion checking with perf macro

2018-11-16 Thread Andrew Murray
Replace checking of perf event exclusion flags with perf macro.

This is a functional change as __hw_perf_event_init will now indicate
that it doesn't support exclude_host and exclude_guest event flags.

Signed-off-by: Andrew Murray 
---
 arch/alpha/kernel/perf_event.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/alpha/kernel/perf_event.c b/arch/alpha/kernel/perf_event.c
index 5613aa37..36f98ee 100644
--- a/arch/alpha/kernel/perf_event.c
+++ b/arch/alpha/kernel/perf_event.c
@@ -631,10 +631,8 @@ static int __hw_perf_event_init(struct perf_event *event)
}
 
/* The EV67 does not support mode exclusion */
-   if (attr->exclude_kernel || attr->exclude_user
-   || attr->exclude_hv || attr->exclude_idle) {
+   if (event_has_exclude_flags(event))
return -EPERM;
-   }
 
/*
 * We place the event type in event_base here and leave calculation
-- 
2.7.4



[PATCH 05/10] powerpc/pmu/fsl: add additional validation to event_init

2018-11-16 Thread Andrew Murray
The fsl PMU driver doesn't support host/guest mode exclusion so
let's report this when event_init is called with these exclusion
flags set.

Signed-off-by: Andrew Murray 
---
 arch/powerpc/perf/core-fsl-emb.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/powerpc/perf/core-fsl-emb.c b/arch/powerpc/perf/core-fsl-emb.c
index ba48584..b1cc9d1 100644
--- a/arch/powerpc/perf/core-fsl-emb.c
+++ b/arch/powerpc/perf/core-fsl-emb.c
@@ -559,6 +559,8 @@ static int fsl_emb_pmu_event_init(struct perf_event *event)
event->hw.config_base |= PMLCA_FCS;
if (event->attr.exclude_idle)
return -ENOTSUPP;
+   if (event->attr.exclude_host || event->attr.exclude_guest)
+   return -ENOTSUPP;
 
event->hw.last_period = event->hw.sample_period;
local64_set(>hw.period_left, event->hw.last_period);
-- 
2.7.4



[PATCH 04/10] powerpc: perf/core: generalise event exclusion checking with perf macro

2018-11-16 Thread Andrew Murray
Replace checking of perf event exclusion flags with perf macro.

Signed-off-by: Andrew Murray 
---
 arch/powerpc/perf/hv-24x7.c |  7 +--
 arch/powerpc/perf/hv-gpci.c |  7 +--
 arch/powerpc/perf/imc-pmu.c | 14 ++
 3 files changed, 4 insertions(+), 24 deletions(-)

diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c
index 72238ee..60db22d 100644
--- a/arch/powerpc/perf/hv-24x7.c
+++ b/arch/powerpc/perf/hv-24x7.c
@@ -1307,12 +1307,7 @@ static int h_24x7_event_init(struct perf_event *event)
}
 
/* unsupported modes and filters */
-   if (event->attr.exclude_user   ||
-   event->attr.exclude_kernel ||
-   event->attr.exclude_hv ||
-   event->attr.exclude_idle   ||
-   event->attr.exclude_host   ||
-   event->attr.exclude_guest)
+   if (event_has_exclude_flags(event))
return -EINVAL;
 
/* no branch sampling */
diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c
index 43fabb3..2d2b5c0 100644
--- a/arch/powerpc/perf/hv-gpci.c
+++ b/arch/powerpc/perf/hv-gpci.c
@@ -233,12 +233,7 @@ static int h_gpci_event_init(struct perf_event *event)
}
 
/* unsupported modes and filters */
-   if (event->attr.exclude_user   ||
-   event->attr.exclude_kernel ||
-   event->attr.exclude_hv ||
-   event->attr.exclude_idle   ||
-   event->attr.exclude_host   ||
-   event->attr.exclude_guest)
+   if (event_has_exclude_flags(event))
return -EINVAL;
 
/* no branch sampling */
diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c
index 1fafc32b..1ae1d3f 100644
--- a/arch/powerpc/perf/imc-pmu.c
+++ b/arch/powerpc/perf/imc-pmu.c
@@ -474,12 +474,7 @@ static int nest_imc_event_init(struct perf_event *event)
return -EINVAL;
 
/* unsupported modes and filters */
-   if (event->attr.exclude_user   ||
-   event->attr.exclude_kernel ||
-   event->attr.exclude_hv ||
-   event->attr.exclude_idle   ||
-   event->attr.exclude_host   ||
-   event->attr.exclude_guest)
+   if (event_has_exclude_flags(event))
return -EINVAL;
 
if (event->cpu < 0)
@@ -749,12 +744,7 @@ static int core_imc_event_init(struct perf_event *event)
return -EINVAL;
 
/* unsupported modes and filters */
-   if (event->attr.exclude_user   ||
-   event->attr.exclude_kernel ||
-   event->attr.exclude_hv ||
-   event->attr.exclude_idle   ||
-   event->attr.exclude_host   ||
-   event->attr.exclude_guest)
+   if (event_has_exclude_flags(event))
return -EINVAL;
 
if (event->cpu < 0)
-- 
2.7.4



[PATCH 03/10] arm: perf: add additional validation to set_event_filter

2018-11-16 Thread Andrew Murray
The armv7pmu driver doesn't support host/guest mode exclusion so
let's report this when set_event_filter is called with these
exclusion flags set.

Signed-off-by: Andrew Murray 
---
 arch/arm/kernel/perf_event_v7.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index a4fb0f8..c4c9fbb 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -1074,6 +1074,8 @@ static int armv7pmu_set_event_filter(struct hw_perf_event 
*event,
 
if (attr->exclude_idle)
return -EPERM;
+   if (attr->exclude_host || attr->exclude_guest)
+   return -EPERM;
if (attr->exclude_user)
config_base |= ARMV7_EXCLUDE_USER;
if (attr->exclude_kernel)
-- 
2.7.4



[PATCH 01/10] perf/core: Add macro to test for event exclusion flags

2018-11-16 Thread Andrew Murray
Add a macro that tests if any of the perf event exclusion flags
are set on a given event.

Signed-off-by: Andrew Murray 
---
 include/linux/perf_event.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 53c500f..89ee7fa 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1004,6 +1004,15 @@ perf_event__output_id_sample(struct perf_event *event,
 extern void
 perf_log_lost_samples(struct perf_event *event, u64 lost);
 
+static inline bool event_has_exclude_flags(struct perf_event *event)
+{
+   struct perf_event_attr *attr = >attr;
+
+   return attr->exclude_idle || attr->exclude_user ||
+  attr->exclude_kernel || attr->exclude_hv ||
+  attr->exclude_guest || attr->exclude_host;
+}
+
 static inline bool is_sampling_event(struct perf_event *event)
 {
return event->attr.sample_period != 0;
-- 
2.7.4



[PATCH 02/10] arm: perf/core: generalise event exclusion checking with perf macro

2018-11-16 Thread Andrew Murray
Replace checking of perf event exclusion flags with perf macro.

Signed-off-by: Andrew Murray 
---
 arch/arm/mach-imx/mmdc.c | 8 +---
 arch/arm/mm/cache-l2x0-pmu.c | 7 +--
 2 files changed, 2 insertions(+), 13 deletions(-)

diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c
index 04b3bf7..d9d468f 100644
--- a/arch/arm/mach-imx/mmdc.c
+++ b/arch/arm/mach-imx/mmdc.c
@@ -293,13 +293,7 @@ static int mmdc_pmu_event_init(struct perf_event *event)
return -EOPNOTSUPP;
}
 
-   if (event->attr.exclude_user||
-   event->attr.exclude_kernel  ||
-   event->attr.exclude_hv  ||
-   event->attr.exclude_idle||
-   event->attr.exclude_host||
-   event->attr.exclude_guest   ||
-   event->attr.sample_period)
+   if (event_has_exclude_flags(event) || event->attr.sample_period)
return -EINVAL;
 
if (cfg < 0 || cfg >= MMDC_NUM_COUNTERS)
diff --git a/arch/arm/mm/cache-l2x0-pmu.c b/arch/arm/mm/cache-l2x0-pmu.c
index afe5b4c..968fdf8 100644
--- a/arch/arm/mm/cache-l2x0-pmu.c
+++ b/arch/arm/mm/cache-l2x0-pmu.c
@@ -314,12 +314,7 @@ static int l2x0_pmu_event_init(struct perf_event *event)
event->attach_state & PERF_ATTACH_TASK)
return -EINVAL;
 
-   if (event->attr.exclude_user   ||
-   event->attr.exclude_kernel ||
-   event->attr.exclude_hv ||
-   event->attr.exclude_idle   ||
-   event->attr.exclude_host   ||
-   event->attr.exclude_guest)
+   if (event_has_exclude_flags(event))
return -EINVAL;
 
if (event->cpu < 0)
-- 
2.7.4



[PATCH 00/10] perf/core: Generalise event exclusion checking

2018-11-16 Thread Andrew Murray
Many PMU drivers do not have the capability to exclude counting events
that occur in specific contexts such as idle, kernel, guest, etc. These
drivers indicate this by returning an error in their event_init upon
testing the events attribute flags.

However this approach requires that each time a new event modifier is
added to perf, all the perf drivers need to be modified to indicate that
they don't support the attribute. This results in additional boiler-plate
code common to many drivers that needs to be maintained. An example of
this is the addition of exclude_host and exclude_guest in 2011 yet many
PMU drivers do not support this or indicate an error on events that make
use of it.

This patch generalises the test for exclusion and updates PMU drivers to
use it. This is a functional change as some PMU drivers will now correctly
report that they don't support certain events whereas they previously did.

An alternative approach might have been to provide a static perf_event_attr
with exclusion events set such that each PMU driver could compare against
(see ref [1]) - however this is less readable. A longer term approach may
instead be for PMU's to advertise their capabilities on registration.

All drivers touched by this patchset have been compile tested.

[1] https://lore.kernel.org/patchwork/patch/325116/
~   

Andrew Murray (10):
  perf/core: Add macro to test for event exclusion flags
  arm: perf/core: generalise event exclusion checking with perf macro
  arm: perf: add additional validation to set_event_filter
  powerpc: perf/core: generalise event exclusion checking with perf
macro
  powerpc/pmu/fsl: add additional validation to event_init
  alpha: perf/core: generalise event exclusion checking with perf macro
  x86: perf/core: generalise event exclusion checking with perf macro
  perf/core: Remove unused perf_flags
  drivers/perf: perf/core: generalise event exclusion checking with perf
macro
  perf/doc: update design.txt for exclude_{host|guest} flags

 arch/alpha/kernel/perf_event.c   |  4 +---
 arch/arm/kernel/perf_event_v7.c  |  2 ++
 arch/arm/mach-imx/mmdc.c |  8 +---
 arch/arm/mm/cache-l2x0-pmu.c |  7 +--
 arch/powerpc/perf/core-fsl-emb.c |  2 ++
 arch/powerpc/perf/hv-24x7.c  |  7 +--
 arch/powerpc/perf/hv-gpci.c  |  7 +--
 arch/powerpc/perf/imc-pmu.c  | 14 ++
 arch/x86/events/amd/ibs.c| 11 +--
 arch/x86/events/amd/iommu.c  |  3 +--
 arch/x86/events/amd/power.c  |  8 +---
 arch/x86/events/amd/uncore.c |  3 +--
 arch/x86/events/intel/cstate.c   |  7 +--
 arch/x86/events/intel/rapl.c |  7 +--
 arch/x86/events/intel/uncore.c   |  3 +--
 arch/x86/events/intel/uncore_snb.c   |  7 +--
 arch/x86/events/msr.c|  7 +--
 drivers/perf/arm-cci.c   |  7 +--
 drivers/perf/arm-ccn.c   |  5 +
 drivers/perf/arm_dsu_pmu.c   |  7 +--
 drivers/perf/arm_pmu.c   |  9 +
 drivers/perf/hisilicon/hisi_uncore_pmu.c |  7 +--
 drivers/perf/qcom_l2_pmu.c   |  3 +--
 drivers/perf/qcom_l3_pmu.c   |  3 +--
 drivers/perf/xgene_pmu.c |  3 +--
 include/linux/perf_event.h   |  9 +
 include/uapi/linux/perf_event.h  |  2 --
 tools/include/uapi/linux/perf_event.h|  2 --
 tools/perf/design.txt|  4 
 29 files changed, 41 insertions(+), 127 deletions(-)

-- 
2.7.4



Re: [PATCH] powerpc/mm: dump block address translation on book3s/32

2018-11-16 Thread Michael Ellerman
Christophe LEROY  writes:

> Le 15/11/2018 à 12:46, Michael Ellerman a écrit :
>> Christophe Leroy  writes:
>> 
>>> This patch adds a debugfs file to dump block address translation:
>>>
>>> ~# cat /sys/kernel/debug/block_address_translation
>> 
>> My instinct is it should be in /sys/kernel/debug/powerpc. But I guess
>> the other page table dump files are not.
>
> Lol.
>
> Looks like we have the same instinct ...
>
> But you rejected my patch https://patchwork.ozlabs.org/patch/750426/ :)

Haha. My argument was that the kernel page table dump is not powerpc
specific, but this file *is* powerpc specific. Though I guess it's in
the same are as the page table / hash table dump, so it may as well live
next to them.

>>> diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
>>> index ca96e7be4d0e..2adad10b5856 100644
>>> --- a/arch/powerpc/mm/Makefile
>>> +++ b/arch/powerpc/mm/Makefile
>>> @@ -47,7 +47,7 @@ ifdef CONFIG_PPC_PTDUMP
>>>   obj-$(CONFIG_4xx) += dump_linuxpagetables-generic.o
>>>   obj-$(CONFIG_PPC_8xx) += dump_linuxpagetables-8xx.o
>>>   obj-$(CONFIG_PPC_BOOK3E_MMU)  += dump_linuxpagetables-generic.o
>>> -obj-$(CONFIG_PPC_BOOK3S_32)+= dump_linuxpagetables-generic.o
>>> +obj-$(CONFIG_PPC_BOOK3S_32)+= dump_linuxpagetables-generic.o 
>>> dump_bats.o
>> 
>> BOOK3S_32 covers quite a lot of CPUs.
>> 
>> But below the only check is that you're on 601 or 603.
>> 
>> So is the 603 code going to work on all other BOOK3S_32 CPUs?
>
> If I understand function setbat() correctly, it should.
>
> See 
> https://elixir.bootlin.com/linux/v4.20-rc1/source/arch/powerpc/mm/ppc_mmu_32.c#L115
>  
> Tell me if you see something I missed.

I don't know those 32-bit CPUs at all, so as long as you've thought
about it that's good enough for me. We can catch bugs in testing anyway.

cheers


Re: [PATCH] arch/powerpc: Use dma_zalloc_coherent

2018-11-16 Thread Michael Ellerman
Sabyasachi Gupta  writes:

> On Mon, Nov 5, 2018 at 8:58 AM Sabyasachi Gupta
>  wrote:
>>
>> Replaced dma_alloc_coherent + memset with dma_zalloc_coherent
>>
>> Signed-off-by: Sabyasachi Gupta 
>
> Any comment on this patch?

Wait longer :)

I'm still chasing bugs in 4.20-rc2, I haven't started merging many
patches for 4.21 yet.

Your patches are tracked in patchwork here:
  https://patchwork.ozlabs.org/project/linuxppc-dev/list/?submitter=75253


If they're still in "new" state around rc5 then feel free to ping me
again.

cheers


>> diff --git a/arch/powerpc/platforms/pasemi/dma_lib.c 
>> b/arch/powerpc/platforms/pasemi/dma_lib.c
>> index 53384eb..d18d164 100644
>> --- a/arch/powerpc/platforms/pasemi/dma_lib.c
>> +++ b/arch/powerpc/platforms/pasemi/dma_lib.c
>> @@ -255,15 +255,13 @@ int pasemi_dma_alloc_ring(struct pasemi_dmachan *chan, 
>> int ring_size)
>>
>> chan->ring_size = ring_size;
>>
>> -   chan->ring_virt = dma_alloc_coherent(_pdev->dev,
>> +   chan->ring_virt = dma_zalloc_coherent(_pdev->dev,
>>  ring_size * sizeof(u64),
>>  >ring_dma, GFP_KERNEL);
>>
>> if (!chan->ring_virt)
>> return -ENOMEM;
>>
>> -   memset(chan->ring_virt, 0, ring_size * sizeof(u64));
>> -
>> return 0;
>>  }
>>  EXPORT_SYMBOL(pasemi_dma_alloc_ring);
>> --
>> 2.7.4
>>


Re: [mainline][ppc][bnx2x] watchdog: CPU 80 self-detected hard LOCKUP @ opal_interrupt+0x28/0x70 when module load/unload

2018-11-16 Thread Michael Ellerman
Abdul Haleem  writes:
> On Fri, 2018-11-16 at 15:44 +1100, Michael Ellerman wrote:
>> Abdul Haleem  writes:
>> > On Thu, 2018-11-15 at 16:40 +0530, Abdul Haleem wrote:
>> >> On Mon, 2018-09-24 at 15:49 +0530, Abdul Haleem wrote:
>> >> > On Mon, 2018-09-24 at 19:35 +1000, Oliver wrote:
>> >> > > On Mon, Sep 24, 2018 at 6:56 PM, Abdul Haleem
>> >> > >  wrote:
>> >> > > > Greeting's
>> >> > > >
>> >> > > > bnx2x module load/unload test results in continuous hard LOCKUP 
>> >> > > > trace on
>> >> > > > my powerpc bare-metal running mainline 4.19.0-rc4 kernel
>> ^^
>> >> 
>> >> Warnings also show up on 4.20.0-rc2-next-20181114
>> >
>> > We have a patch fix available https://patchwork.ozlabs.org/patch/998054/
>> >
>> > It fixed the problem.
>> 
>> But the bug it fixes wasn't present in 4.19.0-rc4, which is the version
>> you originally reported against. Or is that version string not accurate?
>
> Yes, version string wrong. the bug was first seen on linux-next
> 4.19.0-rc3-next-20180913 and on mainline version 4.19.0-rc8

OK. The commit that the above patch fixes was first in next-20181015, or
mainline as of v4.20-rc1~24.

cheers


Re: [PATCH] Powerpc/perf: Wire up PMI throttling

2018-11-16 Thread Ravi Bangoria



On 11/15/18 6:13 PM, Michael Ellerman wrote:
> Ravi Bangoria  writes:
> 
>> Commit 14c63f17b1fde ("perf: Drop sample rate when sampling is too
>> slow") introduced a way to throttle PMU interrupts if we're spending
>> too much time just processing those. Wire up powerpc PMI handler to
>> use this infrastructure.
> 
> To be clear we have throttling of the *rate* of interrupts, but this
> adds throttling based on the *time taken* to process the interrupts. Or
> at least that's my understanding?

Right. This throttles based on time taken to process the interrupts.

> 
>> diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
>> index 9a86572db1ef..44f85fa22356 100644
>> --- a/arch/powerpc/kernel/traps.c
>> +++ b/arch/powerpc/kernel/traps.c
>> @@ -18,6 +18,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>  #include 
>>  #include 
>>  #include 
>> @@ -1803,9 +1804,12 @@ void vsx_unavailable_tm(struct pt_regs *regs)
>>  
>>  void performance_monitor_exception(struct pt_regs *regs)
>>  {
>> +u64 start_clock;
>>  __this_cpu_inc(irq_stat.pmu_irqs);
>>  
>> +start_clock = sched_clock();
>>  perf_irq(regs);
>> +perf_sample_event_took(sched_clock() - start_clock);
>>  }
> 
> Despite the name, perf_irq() may not actually be the perf IRQ handler :)
> 
> It's a function pointer which might call perf or might call oprofile, or
> a dummy handler.
> 
> I don't think we should be calling perf_sample_event_took() if we're not
> actually using perf, that is wasteful at best.
> 
> So the timing logic should go in the perf specific handler I think.
> ie. perf_event_interrupt().

Makes sense. I'll re-send with that change.

Thanks,
Ravi



Re: [PATCH] powerpc/64: Fix kernel stack 16-byte alignment

2018-11-16 Thread Sandipan Das
On 15/11/18 8:04 AM, Nicholas Piggin wrote:
> Commit 4c2de74cc869 ("powerpc/64: Interrupts save PPR on stack rather
> than thread_struct") changed sizeof(struct pt_regs) % 16 from 0 to 8,
> which causes the interrupt frame allocation on kernel entry to put the
> kernel stack out of alignment.
> 
> Add a pad field to fix alignment, and add a BUILD_BUG_ON to catch this
> in future.
> 
> Fixes: 4c2de74cc869 ("powerpc/64: Interrupts save PPR on stack rather
> than thread_struct")
> Signed-off-by: Nicholas Piggin 
> [...]

Thanks for fixing this. Commit 4c2de74cc869 ("powerpc/64: Interrupts save
PPR on stack rather than thread_struct") was also leading to incorrect
kernel stack traces.

E.g.
If you are using `perf record -g` and expect to see a stack trace like this:

c02b19a0 bpf_check+0x1910 
(/usr/lib/debug/lib/modules/4.18.17-200.fc28.ppc64le/vmlinux)
c02a5554 bpf_prog_load+0x684 
(/usr/lib/debug/lib/modules/4.18.17-200.fc28.ppc64le/vmlinux)
c02a6938 sys_bpf+0xaf8 
(/usr/lib/debug/lib/modules/4.18.17-200.fc28.ppc64le/vmlinux)
c000b9e4 system_call+0x5c 
(/usr/lib/debug/lib/modules/4.18.17-200.fc28.ppc64le/vmlinux)
7fff815bca90 syscall+0x50 (/usr/lib64/libc-2.27.so)
7fff7d96ee0c bpf_prog_load+0x16c (/usr/lib64/libbcc.so.0.7.0)
[...]

you would instead see something like this:

c02bdb88 bpf_check+0xb88 
(/lib/modules/4.20.0-rc1+/build/vmlinux)
c02bdb60 bpf_check+0xb60 
(/lib/modules/4.20.0-rc1+/build/vmlinux)
3fff8f350a90 syscall+0x50 (/usr/lib64/libc-2.27.so)
3fff8b788e0c bpf_prog_load+0x16c (/usr/lib64/libbcc.so.0.7.0)
[...]

--
With Regards,
Sandipan



Re: [PATCH 4/9] PCI: consolidate PCI config entry in drivers/pci

2018-11-16 Thread Geert Uytterhoeven
On Thu, Nov 15, 2018 at 8:06 PM Christoph Hellwig  wrote:
> There is no good reason to duplicate the PCI menu in every architecture.
> Instead provide a selectable HAVE_PCI symbol that indicates availability
> of PCI support, and a FORCE_PCI symbol to for PCI on and the handle the
> rest in drivers/pci.
>
> Signed-off-by: Christoph Hellwig 
> Reviewed-by: Palmer Dabbelt 
> Acked-by: Max Filippov 
> Acked-by: Thomas Gleixner 
> Acked-by: Bjorn Helgaas 

For m68k:
Acked-by: Geert Uytterhoeven 

Gr{oetje,eeting}s,

Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds