From ec8549e611465558bdf1bb5e9d308f39e5e248cd Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens 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 + * + * 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 +#include +#include +#include +#include +#include +#include + +/* + * 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 +#include + +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 +#include + +/* 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 +#include #else #undef dev_coredumpv #define dev_coredumpv LINUX_BACKPORT(dev_coredumpv)