mac80211: add dev_coredumpm() function
authorHauke Mehrtens <hauke@hauke-m.de>
Sun, 17 Sep 2017 12:50:01 +0000 (14:50 +0200)
committerHauke Mehrtens <hauke@hauke-m.de>
Sun, 17 Sep 2017 12:54:28 +0000 (14:54 +0200)
dev_coredumpm() was added with kernel 4.7, but it is used by iwlwifi.
When the dev coredump framework form compat-wireless is used this is not
a problem because it already contains this, but this is deactivated if
the build system finds out that it is already included in the kernel we
compile against. This option was now activated by the bluetooth driver
btmrvl. Having dev coredump in the kernel adds about 400 bytes to the
lzma compressed kernel for brcm47xx.

This is copied from a more recent backports version to add the
dev_coredumpm() function when the internal core devdump is not used.

Fixes: a5922f6 ("kernel: bluetooth: add marvell sdio bluetooth module")
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
package/kernel/mac80211/patches/013-backport-dev_coredumpm-function.patch [new file with mode: 0644]

diff --git a/package/kernel/mac80211/patches/013-backport-dev_coredumpm-function.patch b/package/kernel/mac80211/patches/013-backport-dev_coredumpm-function.patch
new file mode 100644 (file)
index 0000000..2c80aed
--- /dev/null
@@ -0,0 +1,156 @@
+From ec8549e611465558bdf1bb5e9d308f39e5e248cd Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Sun, 17 Sep 2017 14:41:48 +0200
+Subject: backport dev_coredumpm() function
+
+This is copied from a more recent backports version to add the
+dev_coredumpm() function when the internal core devdump is not used.
+---
+ compat/Makefile                |  1 +
+ compat/backport-4.7.c          | 82 ++++++++++++++++++++++++++++++++++++++++++
+ include/linux/bp-devcoredump.h | 32 +++++++++++++++++
+ include/linux/devcoredump.h    |  1 +
+ 4 files changed, 116 insertions(+)
+ create mode 100644 compat/backport-4.7.c
+ create mode 100644 include/linux/bp-devcoredump.h
+
+--- a/compat/Makefile
++++ b/compat/Makefile
+@@ -32,6 +32,7 @@ compat-$(CPTCFG_KERNEL_4_3) += backport-
+ compat-$(CPTCFG_KERNEL_4_4) += backport-4.4.o
+ compat-$(CPTCFG_KERNEL_4_5) += backport-4.5.o
+ compat-$(CPTCFG_KERNEL_4_6) += backport-4.6.o
++compat-$(CPTCFG_KERNEL_4_6) += backport-4.7.o
+ compat-$(CPTCFG_BPAUTO_BUILD_CRYPTO_CCM) += crypto-ccm.o
+ compat-$(CPTCFG_BPAUTO_CRYPTO_SKCIPHER) += crypto-skcipher.o
+--- /dev/null
++++ b/compat/backport-4.7.c
+@@ -0,0 +1,82 @@
++/*
++ * Copyright(c) 2016 Hauke Mehrtens <hauke@hauke-m.de>
++ *
++ * Backport functionality introduced in Linux 4.7.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/export.h>
++#include <linux/list.h>
++#include <linux/rcupdate.h>
++#include <linux/slab.h>
++#include <linux/spinlock.h>
++#include <linux/skbuff.h>
++#include <net/netlink.h>
++
++/*
++ * Below 3.18 or if the kernel has devcoredump disabled, we copied the
++ * entire devcoredump, so no need to define these functions.
++ */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0) && \
++      !defined(CPTCFG_BPAUTO_BUILD_WANT_DEV_COREDUMP)
++#include <linux/devcoredump.h>
++#include <linux/scatterlist.h>
++
++static void devcd_free_sgtable(void *data)
++{
++      struct scatterlist *table = data;
++      int i;
++      struct page *page;
++      struct scatterlist *iter;
++      struct scatterlist *delete_iter;
++
++      /* free pages */
++      iter = table;
++      for_each_sg(table, iter, sg_nents(table), i) {
++              page = sg_page(iter);
++              if (page)
++                      __free_page(page);
++      }
++
++      /* then free all chained tables */
++      iter = table;
++      delete_iter = table;    /* always points on a head of a table */
++      while (!sg_is_last(iter)) {
++              iter++;
++              if (sg_is_chain(iter)) {
++                      iter = sg_chain_ptr(iter);
++                      kfree(delete_iter);
++                      delete_iter = iter;
++              }
++      }
++
++      /* free the last table */
++      kfree(delete_iter);
++}
++
++static ssize_t devcd_read_from_sgtable(char *buffer, loff_t offset,
++                                     size_t buf_len, void *data,
++                                     size_t data_len)
++{
++      struct scatterlist *table = data;
++
++      if (offset > data_len)
++              return -EINVAL;
++
++      if (offset + buf_len > data_len)
++              buf_len = data_len - offset;
++      return sg_pcopy_to_buffer(table, sg_nents(table), buffer, buf_len,
++                                offset);
++}
++
++void dev_coredumpsg(struct device *dev, struct scatterlist *table,
++                  size_t datalen, gfp_t gfp)
++{
++      dev_coredumpm(dev, THIS_MODULE, table, datalen, gfp,
++                    devcd_read_from_sgtable, devcd_free_sgtable);
++}
++EXPORT_SYMBOL_GPL(dev_coredumpsg);
++#endif /* >= 3.18.0 */
+--- /dev/null
++++ b/include/linux/bp-devcoredump.h
+@@ -0,0 +1,32 @@
++#ifndef __BACKPORT_LINUX_DEVCOREDUMP_H
++#define __BACKPORT_LINUX_DEVCOREDUMP_H
++#include <linux/version.h>
++#include <linux/scatterlist.h>
++
++/* We only need to add our wrapper inside the range from 3.18 until
++ * 4.6, outside that we can let our BPAUTO mechanism handle it.
++ */
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)  && \
++     LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0))
++static inline
++void backport_dev_coredumpm(struct device *dev, struct module *owner,
++                          void *data, size_t datalen, gfp_t gfp,
++                          ssize_t (*read_fn)(char *buffer, loff_t offset,
++                                          size_t count, void *data,
++                                          size_t datalen),
++                          void (*free_fn)(void *data))
++{
++      return dev_coredumpm(dev, owner, (const void *)data, datalen, gfp,
++                           (void *)read_fn, (void *)free_fn);
++}
++
++#define dev_coredumpm LINUX_BACKPORT(dev_coredumpm)
++
++#define dev_coredumpsg LINUX_BACKPORT(dev_coredumpsg)
++void dev_coredumpsg(struct device *dev, struct scatterlist *table,
++                  size_t datalen, gfp_t gfp);
++
++#endif /* (LINUX_VERSION_IS_GEQ(3,18,0) &&    \
++         LINUX_VERSION_IS_LESS(4,7,0)) */
++
++#endif /* __BACKPORT_LINUX_DEVCOREDUMP_H */
+--- a/include/linux/devcoredump.h
++++ b/include/linux/devcoredump.h
+@@ -1,6 +1,7 @@
+ /* Automatically created during backport process */
+ #ifndef CPTCFG_BPAUTO_BUILD_WANT_DEV_COREDUMP
+ #include_next <linux/devcoredump.h>
++#include <linux/bp-devcoredump.h>
+ #else
+ #undef dev_coredumpv
+ #define dev_coredumpv LINUX_BACKPORT(dev_coredumpv)