1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Copyright(c) 2015 Intel Deutschland GmbH 4 */ 5 #ifndef __DEVCOREDUMP_H 6 #define __DEVCOREDUMP_H 7 8 #include <linux/device.h> 9 #include <linux/module.h> 10 #include <linux/vmalloc.h> 11 12 #include <linux/scatterlist.h> 13 #include <linux/slab.h> 14 15 /* if data isn't read by userspace after 5 minutes then delete it */ 16 #define DEVCD_TIMEOUT (HZ * 60 * 5) 17 18 /* 19 * _devcd_free_sgtable - free all the memory of the given scatterlist table 20 * (i.e. both pages and scatterlist instances) 21 * NOTE: if two tables allocated and chained using the sg_chain function then 22 * this function should be called only once on the first table 23 * @table: pointer to sg_table to free 24 */ 25 static inline void _devcd_free_sgtable(struct scatterlist *table) 26 { 27 int i; 28 struct page *page; 29 struct scatterlist *iter; 30 struct scatterlist *delete_iter; 31 32 /* free pages */ 33 iter = table; 34 for_each_sg(table, iter, sg_nents(table), i) { 35 page = sg_page(iter); 36 if (page) 37 __free_page(page); 38 } 39 40 /* then free all chained tables */ 41 iter = table; 42 delete_iter = table; /* always points on a head of a table */ 43 while (!sg_is_last(iter)) { 44 iter++; 45 if (sg_is_chain(iter)) { 46 iter = sg_chain_ptr(iter); 47 kfree(delete_iter); 48 delete_iter = iter; 49 } 50 } 51 52 /* free the last table */ 53 kfree(delete_iter); 54 } 55 56 #ifdef CONFIG_DEV_COREDUMP 57 void dev_coredumpv(struct device *dev, void *data, size_t datalen, 58 gfp_t gfp); 59 60 void dev_coredumpm_timeout(struct device *dev, struct module *owner, 61 void *data, size_t datalen, gfp_t gfp, 62 ssize_t (*read)(char *buffer, loff_t offset, 63 size_t count, void *data, 64 size_t datalen), 65 void (*free)(void *data), 66 unsigned long timeout); 67 68 void dev_coredumpsg(struct device *dev, struct scatterlist *table, 69 size_t datalen, gfp_t gfp); 70 71 void dev_coredump_put(struct device *dev); 72 #else 73 static inline void dev_coredumpv(struct device *dev, void *data, 74 size_t datalen, gfp_t gfp) 75 { 76 vfree(data); 77 } 78 79 static inline void 80 dev_coredumpm_timeout(struct device *dev, struct module *owner, 81 void *data, size_t datalen, gfp_t gfp, 82 ssize_t (*read)(char *buffer, loff_t offset, 83 size_t count, void *data, 84 size_t datalen), 85 void (*free)(void *data), 86 unsigned long timeout) 87 { 88 free(data); 89 } 90 91 static inline void dev_coredumpsg(struct device *dev, struct scatterlist *table, 92 size_t datalen, gfp_t gfp) 93 { 94 _devcd_free_sgtable(table); 95 } 96 static inline void dev_coredump_put(struct device *dev) 97 { 98 } 99 #endif /* CONFIG_DEV_COREDUMP */ 100 101 /** 102 * dev_coredumpm - create device coredump with read/free methods 103 * @dev: the struct device for the crashed device 104 * @owner: the module that contains the read/free functions, use %THIS_MODULE 105 * @data: data cookie for the @read/@free functions 106 * @datalen: length of the data 107 * @gfp: allocation flags 108 * @read: function to read from the given buffer 109 * @free: function to free the given buffer 110 * 111 * Creates a new device coredump for the given device. If a previous one hasn't 112 * been read yet, the new coredump is discarded. The data lifetime is determined 113 * by the device coredump framework and when it is no longer needed the @free 114 * function will be called to free the data. 115 */ 116 static inline void dev_coredumpm(struct device *dev, struct module *owner, 117 void *data, size_t datalen, gfp_t gfp, 118 ssize_t (*read)(char *buffer, loff_t offset, size_t count, 119 void *data, size_t datalen), 120 void (*free)(void *data)) 121 { 122 dev_coredumpm_timeout(dev, owner, data, datalen, gfp, read, free, 123 DEVCD_TIMEOUT); 124 } 125 126 #endif /* __DEVCOREDUMP_H */ 127
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.