Re: [PATCH] arch/powerpc: Use dma_zalloc_coherent
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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()
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
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()
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()
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
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()
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()
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
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
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()
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()
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
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
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
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
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
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
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
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
-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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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