diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Kconfig | 15 | ||||
-rw-r--r-- | lib/Kconfig.debug | 86 | ||||
-rw-r--r-- | lib/Makefile | 9 | ||||
-rw-r--r-- | lib/cpumask.c | 4 | ||||
-rw-r--r-- | lib/debugobjects.c | 127 | ||||
-rw-r--r-- | lib/dma-debug.c | 955 | ||||
-rw-r--r-- | lib/dynamic_debug.c | 769 | ||||
-rw-r--r-- | lib/dynamic_printk.c | 414 | ||||
-rw-r--r-- | lib/idr.c | 46 | ||||
-rw-r--r-- | lib/kernel_lock.c | 2 | ||||
-rw-r--r-- | lib/kobject.c | 2 | ||||
-rw-r--r-- | lib/kobject_uevent.c | 12 | ||||
-rw-r--r-- | lib/lmb.c | 42 | ||||
-rw-r--r-- | lib/locking-selftest.c | 4 | ||||
-rw-r--r-- | lib/nlattr.c | 502 | ||||
-rw-r--r-- | lib/rbtree.c | 14 | ||||
-rw-r--r-- | lib/swiotlb.c | 88 | ||||
-rw-r--r-- | lib/vsprintf.c | 1005 |
18 files changed, 3312 insertions, 784 deletions
diff --git a/lib/Kconfig b/lib/Kconfig index daa481824d9c..8ade0a7a91e0 100644 --- a/lib/Kconfig +++ b/lib/Kconfig | |||
@@ -2,6 +2,9 @@ | |||
2 | # Library configuration | 2 | # Library configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | config BINARY_PRINTF | ||
6 | def_bool n | ||
7 | |||
5 | menu "Library routines" | 8 | menu "Library routines" |
6 | 9 | ||
7 | config BITREVERSE | 10 | config BITREVERSE |
@@ -150,12 +153,6 @@ config TEXTSEARCH_BM | |||
150 | config TEXTSEARCH_FSM | 153 | config TEXTSEARCH_FSM |
151 | tristate | 154 | tristate |
152 | 155 | ||
153 | # | ||
154 | # plist support is select#ed if needed | ||
155 | # | ||
156 | config PLIST | ||
157 | boolean | ||
158 | |||
159 | config HAS_IOMEM | 156 | config HAS_IOMEM |
160 | boolean | 157 | boolean |
161 | depends on !NO_IOMEM | 158 | depends on !NO_IOMEM |
@@ -188,4 +185,10 @@ config DISABLE_OBSOLETE_CPUMASK_FUNCTIONS | |||
188 | bool "Disable obsolete cpumask functions" if DEBUG_PER_CPU_MAPS | 185 | bool "Disable obsolete cpumask functions" if DEBUG_PER_CPU_MAPS |
189 | depends on EXPERIMENTAL && BROKEN | 186 | depends on EXPERIMENTAL && BROKEN |
190 | 187 | ||
188 | # | ||
189 | # Netlink attribute parsing support is select'ed if needed | ||
190 | # | ||
191 | config NLATTR | ||
192 | bool | ||
193 | |||
191 | endmenu | 194 | endmenu |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 1bcf9cd4baa0..9638d99644af 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -402,7 +402,7 @@ config LOCKDEP | |||
402 | bool | 402 | bool |
403 | depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT | 403 | depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT |
404 | select STACKTRACE | 404 | select STACKTRACE |
405 | select FRAME_POINTER if !X86 && !MIPS && !PPC | 405 | select FRAME_POINTER if !X86 && !MIPS && !PPC && !ARM_UNWIND |
406 | select KALLSYMS | 406 | select KALLSYMS |
407 | select KALLSYMS_ALL | 407 | select KALLSYMS_ALL |
408 | 408 | ||
@@ -796,6 +796,7 @@ config SYSCTL_SYSCALL_CHECK | |||
796 | to properly maintain and use. This enables checks that help | 796 | to properly maintain and use. This enables checks that help |
797 | you to keep things correct. | 797 | you to keep things correct. |
798 | 798 | ||
799 | source mm/Kconfig.debug | ||
799 | source kernel/trace/Kconfig | 800 | source kernel/trace/Kconfig |
800 | 801 | ||
801 | config PROVIDE_OHCI1394_DMA_INIT | 802 | config PROVIDE_OHCI1394_DMA_INIT |
@@ -847,60 +848,81 @@ config BUILD_DOCSRC | |||
847 | 848 | ||
848 | Say N if you are unsure. | 849 | Say N if you are unsure. |
849 | 850 | ||
850 | config DYNAMIC_PRINTK_DEBUG | 851 | config DYNAMIC_DEBUG |
851 | bool "Enable dynamic printk() call support" | 852 | bool "Enable dynamic printk() support" |
852 | default n | 853 | default n |
853 | depends on PRINTK | 854 | depends on PRINTK |
855 | depends on DEBUG_FS | ||
854 | select PRINTK_DEBUG | 856 | select PRINTK_DEBUG |
855 | help | 857 | help |
856 | 858 | ||
857 | Compiles debug level messages into the kernel, which would not | 859 | Compiles debug level messages into the kernel, which would not |
858 | otherwise be available at runtime. These messages can then be | 860 | otherwise be available at runtime. These messages can then be |
859 | enabled/disabled on a per module basis. This mechanism implicitly | 861 | enabled/disabled based on various levels of scope - per source file, |
860 | enables all pr_debug() and dev_dbg() calls. The impact of this | 862 | function, module, format string, and line number. This mechanism |
861 | compile option is a larger kernel text size of about 2%. | 863 | implicitly enables all pr_debug() and dev_dbg() calls. The impact of |
864 | this compile option is a larger kernel text size of about 2%. | ||
862 | 865 | ||
863 | Usage: | 866 | Usage: |
864 | 867 | ||
865 | Dynamic debugging is controlled by the debugfs file, | 868 | Dynamic debugging is controlled via the 'dynamic_debug/ddebug' file, |
866 | dynamic_printk/modules. This file contains a list of the modules that | 869 | which is contained in the 'debugfs' filesystem. Thus, the debugfs |
867 | can be enabled. The format of the file is the module name, followed | 870 | filesystem must first be mounted before making use of this feature. |
868 | by a set of flags that can be enabled. The first flag is always the | 871 | We refer the control file as: <debugfs>/dynamic_debug/ddebug. This |
869 | 'enabled' flag. For example: | 872 | file contains a list of the debug statements that can be enabled. The |
873 | format for each line of the file is: | ||
870 | 874 | ||
871 | <module_name> <enabled=0/1> | 875 | filename:lineno [module]function flags format |
872 | . | ||
873 | . | ||
874 | . | ||
875 | 876 | ||
876 | <module_name> : Name of the module in which the debug call resides | 877 | filename : source file of the debug statement |
877 | <enabled=0/1> : whether the messages are enabled or not | 878 | lineno : line number of the debug statement |
879 | module : module that contains the debug statement | ||
880 | function : function that contains the debug statement | ||
881 | flags : 'p' means the line is turned 'on' for printing | ||
882 | format : the format used for the debug statement | ||
878 | 883 | ||
879 | From a live system: | 884 | From a live system: |
880 | 885 | ||
881 | snd_hda_intel enabled=0 | 886 | nullarbor:~ # cat <debugfs>/dynamic_debug/ddebug |
882 | fixup enabled=0 | 887 | # filename:lineno [module]function flags format |
883 | driver enabled=0 | 888 | fs/aio.c:222 [aio]__put_ioctx - "__put_ioctx:\040freeing\040%p\012" |
889 | fs/aio.c:248 [aio]ioctx_alloc - "ENOMEM:\040nr_events\040too\040high\012" | ||
890 | fs/aio.c:1770 [aio]sys_io_cancel - "calling\040cancel\012" | ||
884 | 891 | ||
885 | Enable a module: | 892 | Example usage: |
886 | 893 | ||
887 | $echo "set enabled=1 <module_name>" > dynamic_printk/modules | 894 | // enable the message at line 1603 of file svcsock.c |
895 | nullarbor:~ # echo -n 'file svcsock.c line 1603 +p' > | ||
896 | <debugfs>/dynamic_debug/ddebug | ||
888 | 897 | ||
889 | Disable a module: | 898 | // enable all the messages in file svcsock.c |
899 | nullarbor:~ # echo -n 'file svcsock.c +p' > | ||
900 | <debugfs>/dynamic_debug/ddebug | ||
890 | 901 | ||
891 | $echo "set enabled=0 <module_name>" > dynamic_printk/modules | 902 | // enable all the messages in the NFS server module |
903 | nullarbor:~ # echo -n 'module nfsd +p' > | ||
904 | <debugfs>/dynamic_debug/ddebug | ||
892 | 905 | ||
893 | Enable all modules: | 906 | // enable all 12 messages in the function svc_process() |
907 | nullarbor:~ # echo -n 'func svc_process +p' > | ||
908 | <debugfs>/dynamic_debug/ddebug | ||
894 | 909 | ||
895 | $echo "set enabled=1 all" > dynamic_printk/modules | 910 | // disable all 12 messages in the function svc_process() |
911 | nullarbor:~ # echo -n 'func svc_process -p' > | ||
912 | <debugfs>/dynamic_debug/ddebug | ||
896 | 913 | ||
897 | Disable all modules: | 914 | See Documentation/dynamic-debug-howto.txt for additional information. |
898 | 915 | ||
899 | $echo "set enabled=0 all" > dynamic_printk/modules | 916 | config DMA_API_DEBUG |
900 | 917 | bool "Enable debugging of DMA-API usage" | |
901 | Finally, passing "dynamic_printk" at the command line enables | 918 | depends on HAVE_DMA_API_DEBUG |
902 | debugging for all modules. This mode can be turned off via the above | 919 | help |
903 | disable command. | 920 | Enable this option to debug the use of the DMA API by device drivers. |
921 | With this option you will be able to detect common bugs in device | ||
922 | drivers like double-freeing of DMA mappings or freeing mappings that | ||
923 | were never allocated. | ||
924 | This option causes a performance degredation. Use only if you want | ||
925 | to debug device drivers. If unsure, say N. | ||
904 | 926 | ||
905 | source "samples/Kconfig" | 927 | source "samples/Kconfig" |
906 | 928 | ||
diff --git a/lib/Makefile b/lib/Makefile index 790de7c25d0d..d6edd6753f40 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
@@ -12,7 +12,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \ | |||
12 | idr.o int_sqrt.o extable.o prio_tree.o \ | 12 | idr.o int_sqrt.o extable.o prio_tree.o \ |
13 | sha1.o irq_regs.o reciprocal_div.o argv_split.o \ | 13 | sha1.o irq_regs.o reciprocal_div.o argv_split.o \ |
14 | proportions.o prio_heap.o ratelimit.o show_mem.o \ | 14 | proportions.o prio_heap.o ratelimit.o show_mem.o \ |
15 | is_single_threaded.o decompress.o | 15 | is_single_threaded.o plist.o decompress.o |
16 | 16 | ||
17 | lib-$(CONFIG_MMU) += ioremap.o | 17 | lib-$(CONFIG_MMU) += ioremap.o |
18 | lib-$(CONFIG_SMP) += cpumask.o | 18 | lib-$(CONFIG_SMP) += cpumask.o |
@@ -41,7 +41,6 @@ lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o | |||
41 | lib-$(CONFIG_GENERIC_FIND_LAST_BIT) += find_last_bit.o | 41 | lib-$(CONFIG_GENERIC_FIND_LAST_BIT) += find_last_bit.o |
42 | obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o | 42 | obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o |
43 | obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o | 43 | obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o |
44 | obj-$(CONFIG_PLIST) += plist.o | ||
45 | obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o | 44 | obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o |
46 | obj-$(CONFIG_DEBUG_LIST) += list_debug.o | 45 | obj-$(CONFIG_DEBUG_LIST) += list_debug.o |
47 | obj-$(CONFIG_DEBUG_OBJECTS) += debugobjects.o | 46 | obj-$(CONFIG_DEBUG_OBJECTS) += debugobjects.o |
@@ -87,7 +86,11 @@ obj-$(CONFIG_HAVE_LMB) += lmb.o | |||
87 | 86 | ||
88 | obj-$(CONFIG_HAVE_ARCH_TRACEHOOK) += syscall.o | 87 | obj-$(CONFIG_HAVE_ARCH_TRACEHOOK) += syscall.o |
89 | 88 | ||
90 | obj-$(CONFIG_DYNAMIC_PRINTK_DEBUG) += dynamic_printk.o | 89 | obj-$(CONFIG_DYNAMIC_DEBUG) += dynamic_debug.o |
90 | |||
91 | obj-$(CONFIG_NLATTR) += nlattr.o | ||
92 | |||
93 | obj-$(CONFIG_DMA_API_DEBUG) += dma-debug.o | ||
91 | 94 | ||
92 | hostprogs-y := gen_crc32table | 95 | hostprogs-y := gen_crc32table |
93 | clean-files := crc32table.h | 96 | clean-files := crc32table.h |
diff --git a/lib/cpumask.c b/lib/cpumask.c index 3389e2440da0..1f71b97de0f9 100644 --- a/lib/cpumask.c +++ b/lib/cpumask.c | |||
@@ -109,10 +109,10 @@ bool alloc_cpumask_var_node(cpumask_var_t *mask, gfp_t flags, int node) | |||
109 | #endif | 109 | #endif |
110 | /* FIXME: Bandaid to save us from old primitives which go to NR_CPUS. */ | 110 | /* FIXME: Bandaid to save us from old primitives which go to NR_CPUS. */ |
111 | if (*mask) { | 111 | if (*mask) { |
112 | unsigned char *ptr = (unsigned char *)cpumask_bits(*mask); | ||
112 | unsigned int tail; | 113 | unsigned int tail; |
113 | tail = BITS_TO_LONGS(NR_CPUS - nr_cpumask_bits) * sizeof(long); | 114 | tail = BITS_TO_LONGS(NR_CPUS - nr_cpumask_bits) * sizeof(long); |
114 | memset(cpumask_bits(*mask) + cpumask_size() - tail, | 115 | memset(ptr + cpumask_size() - tail, 0, tail); |
115 | 0, tail); | ||
116 | } | 116 | } |
117 | 117 | ||
118 | return *mask != NULL; | 118 | return *mask != NULL; |
diff --git a/lib/debugobjects.c b/lib/debugobjects.c index 5d99be1fd988..2755a3bd16a1 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c | |||
@@ -30,7 +30,7 @@ struct debug_bucket { | |||
30 | 30 | ||
31 | static struct debug_bucket obj_hash[ODEBUG_HASH_SIZE]; | 31 | static struct debug_bucket obj_hash[ODEBUG_HASH_SIZE]; |
32 | 32 | ||
33 | static struct debug_obj obj_static_pool[ODEBUG_POOL_SIZE]; | 33 | static struct debug_obj obj_static_pool[ODEBUG_POOL_SIZE] __initdata; |
34 | 34 | ||
35 | static DEFINE_SPINLOCK(pool_lock); | 35 | static DEFINE_SPINLOCK(pool_lock); |
36 | 36 | ||
@@ -50,12 +50,23 @@ static int debug_objects_enabled __read_mostly | |||
50 | 50 | ||
51 | static struct debug_obj_descr *descr_test __read_mostly; | 51 | static struct debug_obj_descr *descr_test __read_mostly; |
52 | 52 | ||
53 | static void free_obj_work(struct work_struct *work); | ||
54 | static DECLARE_WORK(debug_obj_work, free_obj_work); | ||
55 | |||
53 | static int __init enable_object_debug(char *str) | 56 | static int __init enable_object_debug(char *str) |
54 | { | 57 | { |
55 | debug_objects_enabled = 1; | 58 | debug_objects_enabled = 1; |
56 | return 0; | 59 | return 0; |
57 | } | 60 | } |
61 | |||
62 | static int __init disable_object_debug(char *str) | ||
63 | { | ||
64 | debug_objects_enabled = 0; | ||
65 | return 0; | ||
66 | } | ||
67 | |||
58 | early_param("debug_objects", enable_object_debug); | 68 | early_param("debug_objects", enable_object_debug); |
69 | early_param("no_debug_objects", disable_object_debug); | ||
59 | 70 | ||
60 | static const char *obj_states[ODEBUG_STATE_MAX] = { | 71 | static const char *obj_states[ODEBUG_STATE_MAX] = { |
61 | [ODEBUG_STATE_NONE] = "none", | 72 | [ODEBUG_STATE_NONE] = "none", |
@@ -146,25 +157,51 @@ alloc_object(void *addr, struct debug_bucket *b, struct debug_obj_descr *descr) | |||
146 | } | 157 | } |
147 | 158 | ||
148 | /* | 159 | /* |
149 | * Put the object back into the pool or give it back to kmem_cache: | 160 | * workqueue function to free objects. |
150 | */ | 161 | */ |
151 | static void free_object(struct debug_obj *obj) | 162 | static void free_obj_work(struct work_struct *work) |
152 | { | 163 | { |
153 | unsigned long idx = (unsigned long)(obj - obj_static_pool); | 164 | struct debug_obj *obj; |
154 | unsigned long flags; | 165 | unsigned long flags; |
155 | 166 | ||
156 | if (obj_pool_free < ODEBUG_POOL_SIZE || idx < ODEBUG_POOL_SIZE) { | 167 | spin_lock_irqsave(&pool_lock, flags); |
157 | spin_lock_irqsave(&pool_lock, flags); | 168 | while (obj_pool_free > ODEBUG_POOL_SIZE) { |
158 | hlist_add_head(&obj->node, &obj_pool); | 169 | obj = hlist_entry(obj_pool.first, typeof(*obj), node); |
159 | obj_pool_free++; | 170 | hlist_del(&obj->node); |
160 | obj_pool_used--; | 171 | obj_pool_free--; |
161 | spin_unlock_irqrestore(&pool_lock, flags); | 172 | /* |
162 | } else { | 173 | * We release pool_lock across kmem_cache_free() to |
163 | spin_lock_irqsave(&pool_lock, flags); | 174 | * avoid contention on pool_lock. |
164 | obj_pool_used--; | 175 | */ |
165 | spin_unlock_irqrestore(&pool_lock, flags); | 176 | spin_unlock_irqrestore(&pool_lock, flags); |
166 | kmem_cache_free(obj_cache, obj); | 177 | kmem_cache_free(obj_cache, obj); |
178 | spin_lock_irqsave(&pool_lock, flags); | ||
167 | } | 179 | } |
180 | spin_unlock_irqrestore(&pool_lock, flags); | ||
181 | } | ||
182 | |||
183 | /* | ||
184 | * Put the object back into the pool and schedule work to free objects | ||
185 | * if necessary. | ||
186 | */ | ||
187 | static void free_object(struct debug_obj *obj) | ||
188 | { | ||
189 | unsigned long flags; | ||
190 | int sched = 0; | ||
191 | |||
192 | spin_lock_irqsave(&pool_lock, flags); | ||
193 | /* | ||
194 | * schedule work when the pool is filled and the cache is | ||
195 | * initialized: | ||
196 | */ | ||
197 | if (obj_pool_free > ODEBUG_POOL_SIZE && obj_cache) | ||
198 | sched = !work_pending(&debug_obj_work); | ||
199 | hlist_add_head(&obj->node, &obj_pool); | ||
200 | obj_pool_free++; | ||
201 | obj_pool_used--; | ||
202 | spin_unlock_irqrestore(&pool_lock, flags); | ||
203 | if (sched) | ||
204 | schedule_work(&debug_obj_work); | ||
168 | } | 205 | } |
169 | 206 | ||
170 | /* | 207 | /* |
@@ -876,6 +913,63 @@ void __init debug_objects_early_init(void) | |||
876 | } | 913 | } |
877 | 914 | ||
878 | /* | 915 | /* |
916 | * Convert the statically allocated objects to dynamic ones: | ||
917 | */ | ||
918 | static int debug_objects_replace_static_objects(void) | ||
919 | { | ||
920 | struct debug_bucket *db = obj_hash; | ||
921 | struct hlist_node *node, *tmp; | ||
922 | struct debug_obj *obj, *new; | ||
923 | HLIST_HEAD(objects); | ||
924 | int i, cnt = 0; | ||
925 | |||
926 | for (i = 0; i < ODEBUG_POOL_SIZE; i++) { | ||
927 | obj = kmem_cache_zalloc(obj_cache, GFP_KERNEL); | ||
928 | if (!obj) | ||
929 | goto free; | ||
930 | hlist_add_head(&obj->node, &objects); | ||
931 | } | ||
932 | |||
933 | /* | ||
934 | * When debug_objects_mem_init() is called we know that only | ||
935 | * one CPU is up, so disabling interrupts is enough | ||
936 | * protection. This avoids the lockdep hell of lock ordering. | ||
937 | */ | ||
938 | local_irq_disable(); | ||
939 | |||
940 | /* Remove the statically allocated objects from the pool */ | ||
941 | hlist_for_each_entry_safe(obj, node, tmp, &obj_pool, node) | ||
942 | hlist_del(&obj->node); | ||
943 | /* Move the allocated objects to the pool */ | ||
944 | hlist_move_list(&objects, &obj_pool); | ||
945 | |||
946 | /* Replace the active object references */ | ||
947 | for (i = 0; i < ODEBUG_HASH_SIZE; i++, db++) { | ||
948 | hlist_move_list(&db->list, &objects); | ||
949 | |||
950 | hlist_for_each_entry(obj, node, &objects, node) { | ||
951 | new = hlist_entry(obj_pool.first, typeof(*obj), node); | ||
952 | hlist_del(&new->node); | ||
953 | /* copy object data */ | ||
954 | *new = *obj; | ||
955 | hlist_add_head(&new->node, &db->list); | ||
956 | cnt++; | ||
957 | } | ||
958 | } | ||
959 | |||
960 | printk(KERN_DEBUG "ODEBUG: %d of %d active objects replaced\n", cnt, | ||
961 | obj_pool_used); | ||
962 | local_irq_enable(); | ||
963 | return 0; | ||
964 | free: | ||
965 | hlist_for_each_entry_safe(obj, node, tmp, &objects, node) { | ||
966 | hlist_del(&obj->node); | ||
967 | kmem_cache_free(obj_cache, obj); | ||
968 | } | ||
969 | return -ENOMEM; | ||
970 | } | ||
971 | |||
972 | /* | ||
879 | * Called after the kmem_caches are functional to setup a dedicated | 973 | * Called after the kmem_caches are functional to setup a dedicated |
880 | * cache pool, which has the SLAB_DEBUG_OBJECTS flag set. This flag | 974 | * cache pool, which has the SLAB_DEBUG_OBJECTS flag set. This flag |
881 | * prevents that the debug code is called on kmem_cache_free() for the | 975 | * prevents that the debug code is called on kmem_cache_free() for the |
@@ -890,8 +984,11 @@ void __init debug_objects_mem_init(void) | |||
890 | sizeof (struct debug_obj), 0, | 984 | sizeof (struct debug_obj), 0, |
891 | SLAB_DEBUG_OBJECTS, NULL); | 985 | SLAB_DEBUG_OBJECTS, NULL); |
892 | 986 | ||
893 | if (!obj_cache) | 987 | if (!obj_cache || debug_objects_replace_static_objects()) { |
894 | debug_objects_enabled = 0; | 988 | debug_objects_enabled = 0; |
895 | else | 989 | if (obj_cache) |
990 | kmem_cache_destroy(obj_cache); | ||
991 | printk(KERN_WARNING "ODEBUG: out of memory.\n"); | ||
992 | } else | ||
896 | debug_objects_selftest(); | 993 | debug_objects_selftest(); |
897 | } | 994 | } |
diff --git a/lib/dma-debug.c b/lib/dma-debug.c new file mode 100644 index 000000000000..d3da7edc034f --- /dev/null +++ b/lib/dma-debug.c | |||
@@ -0,0 +1,955 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Author: Joerg Roedel <joerg.roedel@amd.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License version 2 as published | ||
8 | * by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | */ | ||
19 | |||
20 | #include <linux/scatterlist.h> | ||
21 | #include <linux/dma-mapping.h> | ||
22 | #include <linux/stacktrace.h> | ||
23 | #include <linux/dma-debug.h> | ||
24 | #include <linux/spinlock.h> | ||
25 | #include <linux/debugfs.h> | ||
26 | #include <linux/device.h> | ||
27 | #include <linux/types.h> | ||
28 | #include <linux/sched.h> | ||
29 | #include <linux/list.h> | ||
30 | #include <linux/slab.h> | ||
31 | |||
32 | #include <asm/sections.h> | ||
33 | |||
34 | #define HASH_SIZE 1024ULL | ||
35 | #define HASH_FN_SHIFT 13 | ||
36 | #define HASH_FN_MASK (HASH_SIZE - 1) | ||
37 | |||
38 | enum { | ||
39 | dma_debug_single, | ||
40 | dma_debug_page, | ||
41 | dma_debug_sg, | ||
42 | dma_debug_coherent, | ||
43 | }; | ||
44 | |||
45 | #define DMA_DEBUG_STACKTRACE_ENTRIES 5 | ||
46 | |||
47 | struct dma_debug_entry { | ||
48 | struct list_head list; | ||
49 | struct device *dev; | ||
50 | int type; | ||
51 | phys_addr_t paddr; | ||
52 | u64 dev_addr; | ||
53 | u64 size; | ||
54 | int direction; | ||
55 | int sg_call_ents; | ||
56 | int sg_mapped_ents; | ||
57 | #ifdef CONFIG_STACKTRACE | ||
58 | struct stack_trace stacktrace; | ||
59 | unsigned long st_entries[DMA_DEBUG_STACKTRACE_ENTRIES]; | ||
60 | #endif | ||
61 | }; | ||
62 | |||
63 | struct hash_bucket { | ||
64 | struct list_head list; | ||
65 | spinlock_t lock; | ||
66 | } ____cacheline_aligned_in_smp; | ||
67 | |||
68 | /* Hash list to save the allocated dma addresses */ | ||
69 | static struct hash_bucket dma_entry_hash[HASH_SIZE]; | ||
70 | /* List of pre-allocated dma_debug_entry's */ | ||
71 | static LIST_HEAD(free_entries); | ||
72 | /* Lock for the list above */ | ||
73 | static DEFINE_SPINLOCK(free_entries_lock); | ||
74 | |||
75 | /* Global disable flag - will be set in case of an error */ | ||
76 | static bool global_disable __read_mostly; | ||
77 | |||
78 | /* Global error count */ | ||
79 | static u32 error_count; | ||
80 | |||
81 | /* Global error show enable*/ | ||
82 | static u32 show_all_errors __read_mostly; | ||
83 | /* Number of errors to show */ | ||
84 | static u32 show_num_errors = 1; | ||
85 | |||
86 | static u32 num_free_entries; | ||
87 | static u32 min_free_entries; | ||
88 | |||
89 | /* number of preallocated entries requested by kernel cmdline */ | ||
90 | static u32 req_entries; | ||
91 | |||
92 | /* debugfs dentry's for the stuff above */ | ||
93 | static struct dentry *dma_debug_dent __read_mostly; | ||
94 | static struct dentry *global_disable_dent __read_mostly; | ||
95 | static struct dentry *error_count_dent __read_mostly; | ||
96 | static struct dentry *show_all_errors_dent __read_mostly; | ||
97 | static struct dentry *show_num_errors_dent __read_mostly; | ||
98 | static struct dentry *num_free_entries_dent __read_mostly; | ||
99 | static struct dentry *min_free_entries_dent __read_mostly; | ||
100 | |||
101 | static const char *type2name[4] = { "single", "page", | ||
102 | "scather-gather", "coherent" }; | ||
103 | |||
104 | static const char *dir2name[4] = { "DMA_BIDIRECTIONAL", "DMA_TO_DEVICE", | ||
105 | "DMA_FROM_DEVICE", "DMA_NONE" }; | ||
106 | |||
107 | /* | ||
108 | * The access to some variables in this macro is racy. We can't use atomic_t | ||
109 | * here because all these variables are exported to debugfs. Some of them even | ||
110 | * writeable. This is also the reason why a lock won't help much. But anyway, | ||
111 | * the races are no big deal. Here is why: | ||
112 | * | ||
113 | * error_count: the addition is racy, but the worst thing that can happen is | ||
114 | * that we don't count some errors | ||
115 | * show_num_errors: the subtraction is racy. Also no big deal because in | ||
116 | * worst case this will result in one warning more in the | ||
117 | * system log than the user configured. This variable is | ||
118 | * writeable via debugfs. | ||
119 | */ | ||
120 | static inline void dump_entry_trace(struct dma_debug_entry *entry) | ||
121 | { | ||
122 | #ifdef CONFIG_STACKTRACE | ||
123 | if (entry) { | ||
124 | printk(KERN_WARNING "Mapped at:\n"); | ||
125 | print_stack_trace(&entry->stacktrace, 0); | ||
126 | } | ||
127 | #endif | ||
128 | } | ||
129 | |||
130 | #define err_printk(dev, entry, format, arg...) do { \ | ||
131 | error_count += 1; \ | ||
132 | if (show_all_errors || show_num_errors > 0) { \ | ||
133 | WARN(1, "%s %s: " format, \ | ||
134 | dev_driver_string(dev), \ | ||
135 | dev_name(dev) , ## arg); \ | ||
136 | dump_entry_trace(entry); \ | ||
137 | } \ | ||
138 | if (!show_all_errors && show_num_errors > 0) \ | ||
139 | show_num_errors -= 1; \ | ||
140 | } while (0); | ||
141 | |||
142 | /* | ||
143 | * Hash related functions | ||
144 | * | ||
145 | * Every DMA-API request is saved into a struct dma_debug_entry. To | ||
146 | * have quick access to these structs they are stored into a hash. | ||
147 | */ | ||
148 | static int hash_fn(struct dma_debug_entry *entry) | ||
149 | { | ||
150 | /* | ||
151 | * Hash function is based on the dma address. | ||
152 | * We use bits 20-27 here as the index into the hash | ||
153 | */ | ||
154 | return (entry->dev_addr >> HASH_FN_SHIFT) & HASH_FN_MASK; | ||
155 | } | ||
156 | |||
157 | /* | ||
158 | * Request exclusive access to a hash bucket for a given dma_debug_entry. | ||
159 | */ | ||
160 | static struct hash_bucket *get_hash_bucket(struct dma_debug_entry *entry, | ||
161 | unsigned long *flags) | ||
162 | { | ||
163 | int idx = hash_fn(entry); | ||
164 | unsigned long __flags; | ||
165 | |||
166 | spin_lock_irqsave(&dma_entry_hash[idx].lock, __flags); | ||
167 | *flags = __flags; | ||
168 | return &dma_entry_hash[idx]; | ||
169 | } | ||
170 | |||
171 | /* | ||
172 | * Give up exclusive access to the hash bucket | ||
173 | */ | ||
174 | static void put_hash_bucket(struct hash_bucket *bucket, | ||
175 | unsigned long *flags) | ||
176 | { | ||
177 | unsigned long __flags = *flags; | ||
178 | |||
179 | spin_unlock_irqrestore(&bucket->lock, __flags); | ||
180 | } | ||
181 | |||
182 | /* | ||
183 | * Search a given entry in the hash bucket list | ||
184 | */ | ||
185 | static struct dma_debug_entry *hash_bucket_find(struct hash_bucket *bucket, | ||
186 | struct dma_debug_entry *ref) | ||
187 | { | ||
188 | struct dma_debug_entry *entry; | ||
189 | |||
190 | list_for_each_entry(entry, &bucket->list, list) { | ||
191 | if ((entry->dev_addr == ref->dev_addr) && | ||
192 | (entry->dev == ref->dev)) | ||
193 | return entry; | ||
194 | } | ||
195 | |||
196 | return NULL; | ||
197 | } | ||
198 | |||
199 | /* | ||
200 | * Add an entry to a hash bucket | ||
201 | */ | ||
202 | static void hash_bucket_add(struct hash_bucket *bucket, | ||
203 | struct dma_debug_entry *entry) | ||
204 | { | ||
205 | list_add_tail(&entry->list, &bucket->list); | ||
206 | } | ||
207 | |||
208 | /* | ||
209 | * Remove entry from a hash bucket list | ||
210 | */ | ||
211 | static void hash_bucket_del(struct dma_debug_entry *entry) | ||
212 | { | ||
213 | list_del(&entry->list); | ||
214 | } | ||
215 | |||
216 | /* | ||
217 | * Dump mapping entries for debugging purposes | ||
218 | */ | ||
219 | void debug_dma_dump_mappings(struct device *dev) | ||
220 | { | ||
221 | int idx; | ||
222 | |||
223 | for (idx = 0; idx < HASH_SIZE; idx++) { | ||
224 | struct hash_bucket *bucket = &dma_entry_hash[idx]; | ||
225 | struct dma_debug_entry *entry; | ||
226 | unsigned long flags; | ||
227 | |||
228 | spin_lock_irqsave(&bucket->lock, flags); | ||
229 | |||
230 | list_for_each_entry(entry, &bucket->list, list) { | ||
231 | if (!dev || dev == entry->dev) { | ||
232 | dev_info(entry->dev, | ||
233 | "%s idx %d P=%Lx D=%Lx L=%Lx %s\n", | ||
234 | type2name[entry->type], idx, | ||
235 | (unsigned long long)entry->paddr, | ||
236 | entry->dev_addr, entry->size, | ||
237 | dir2name[entry->direction]); | ||
238 | } | ||
239 | } | ||
240 | |||
241 | spin_unlock_irqrestore(&bucket->lock, flags); | ||
242 | } | ||
243 | } | ||
244 | EXPORT_SYMBOL(debug_dma_dump_mappings); | ||
245 | |||
246 | /* | ||
247 | * Wrapper function for adding an entry to the hash. | ||
248 | * This function takes care of locking itself. | ||
249 | */ | ||
250 | static void add_dma_entry(struct dma_debug_entry *entry) | ||
251 | { | ||
252 | struct hash_bucket *bucket; | ||
253 | unsigned long flags; | ||
254 | |||
255 | bucket = get_hash_bucket(entry, &flags); | ||
256 | hash_bucket_add(bucket, entry); | ||
257 | put_hash_bucket(bucket, &flags); | ||
258 | } | ||
259 | |||
260 | /* struct dma_entry allocator | ||
261 | * | ||
262 | * The next two functions implement the allocator for | ||
263 | * struct dma_debug_entries. | ||
264 | */ | ||
265 | static struct dma_debug_entry *dma_entry_alloc(void) | ||
266 | { | ||
267 | struct dma_debug_entry *entry = NULL; | ||
268 | unsigned long flags; | ||
269 | |||
270 | spin_lock_irqsave(&free_entries_lock, flags); | ||
271 | |||
272 | if (list_empty(&free_entries)) { | ||
273 | printk(KERN_ERR "DMA-API: debugging out of memory " | ||
274 | "- disabling\n"); | ||
275 | global_disable = true; | ||
276 | goto out; | ||
277 | } | ||
278 | |||
279 | entry = list_entry(free_entries.next, struct dma_debug_entry, list); | ||
280 | list_del(&entry->list); | ||
281 | memset(entry, 0, sizeof(*entry)); | ||
282 | |||
283 | #ifdef CONFIG_STACKTRACE | ||
284 | entry->stacktrace.max_entries = DMA_DEBUG_STACKTRACE_ENTRIES; | ||
285 | entry->stacktrace.entries = entry->st_entries; | ||
286 | entry->stacktrace.skip = 2; | ||
287 | save_stack_trace(&entry->stacktrace); | ||
288 | #endif | ||
289 | num_free_entries -= 1; | ||
290 | if (num_free_entries < min_free_entries) | ||
291 | min_free_entries = num_free_entries; | ||
292 | |||
293 | out: | ||
294 | spin_unlock_irqrestore(&free_entries_lock, flags); | ||
295 | |||
296 | return entry; | ||
297 | } | ||
298 | |||
299 | static void dma_entry_free(struct dma_debug_entry *entry) | ||
300 | { | ||
301 | unsigned long flags; | ||
302 | |||
303 | /* | ||
304 | * add to beginning of the list - this way the entries are | ||
305 | * more likely cache hot when they are reallocated. | ||
306 | */ | ||
307 | spin_lock_irqsave(&free_entries_lock, flags); | ||
308 | list_add(&entry->list, &free_entries); | ||
309 | num_free_entries += 1; | ||
310 | spin_unlock_irqrestore(&free_entries_lock, flags); | ||
311 | } | ||
312 | |||
313 | /* | ||
314 | * DMA-API debugging init code | ||
315 | * | ||
316 | * The init code does two things: | ||
317 | * 1. Initialize core data structures | ||
318 | * 2. Preallocate a given number of dma_debug_entry structs | ||
319 | */ | ||
320 | |||
321 | static int prealloc_memory(u32 num_entries) | ||
322 | { | ||
323 | struct dma_debug_entry *entry, *next_entry; | ||
324 | int i; | ||
325 | |||
326 | for (i = 0; i < num_entries; ++i) { | ||
327 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); | ||
328 | if (!entry) | ||
329 | goto out_err; | ||
330 | |||
331 | list_add_tail(&entry->list, &free_entries); | ||
332 | } | ||
333 | |||
334 | num_free_entries = num_entries; | ||
335 | min_free_entries = num_entries; | ||
336 | |||
337 | printk(KERN_INFO "DMA-API: preallocated %d debug entries\n", | ||
338 | num_entries); | ||
339 | |||
340 | return 0; | ||
341 | |||
342 | out_err: | ||
343 | |||
344 | list_for_each_entry_safe(entry, next_entry, &free_entries, list) { | ||
345 | list_del(&entry->list); | ||
346 | kfree(entry); | ||
347 | } | ||
348 | |||
349 | return -ENOMEM; | ||
350 | } | ||
351 | |||
352 | static int dma_debug_fs_init(void) | ||
353 | { | ||
354 | dma_debug_dent = debugfs_create_dir("dma-api", NULL); | ||
355 | if (!dma_debug_dent) { | ||
356 | printk(KERN_ERR "DMA-API: can not create debugfs directory\n"); | ||
357 | return -ENOMEM; | ||
358 | } | ||
359 | |||
360 | global_disable_dent = debugfs_create_bool("disabled", 0444, | ||
361 | dma_debug_dent, | ||
362 | (u32 *)&global_disable); | ||
363 | if (!global_disable_dent) | ||
364 | goto out_err; | ||
365 | |||
366 | error_count_dent = debugfs_create_u32("error_count", 0444, | ||
367 | dma_debug_dent, &error_count); | ||
368 | if (!error_count_dent) | ||
369 | goto out_err; | ||
370 | |||
371 | show_all_errors_dent = debugfs_create_u32("all_errors", 0644, | ||
372 | dma_debug_dent, | ||
373 | &show_all_errors); | ||
374 | if (!show_all_errors_dent) | ||
375 | goto out_err; | ||
376 | |||
377 | show_num_errors_dent = debugfs_create_u32("num_errors", 0644, | ||
378 | dma_debug_dent, | ||
379 | &show_num_errors); | ||
380 | if (!show_num_errors_dent) | ||
381 | goto out_err; | ||
382 | |||
383 | num_free_entries_dent = debugfs_create_u32("num_free_entries", 0444, | ||
384 | dma_debug_dent, | ||
385 | &num_free_entries); | ||
386 | if (!num_free_entries_dent) | ||
387 | goto out_err; | ||
388 | |||
389 | min_free_entries_dent = debugfs_create_u32("min_free_entries", 0444, | ||
390 | dma_debug_dent, | ||
391 | &min_free_entries); | ||
392 | if (!min_free_entries_dent) | ||
393 | goto out_err; | ||
394 | |||
395 | return 0; | ||
396 | |||
397 | out_err: | ||
398 | debugfs_remove_recursive(dma_debug_dent); | ||
399 | |||
400 | return -ENOMEM; | ||
401 | } | ||
402 | |||
403 | static int device_dma_allocations(struct device *dev) | ||
404 | { | ||
405 | struct dma_debug_entry *entry; | ||
406 | unsigned long flags; | ||
407 | int count = 0, i; | ||
408 | |||
409 | for (i = 0; i < HASH_SIZE; ++i) { | ||
410 | spin_lock_irqsave(&dma_entry_hash[i].lock, flags); | ||
411 | list_for_each_entry(entry, &dma_entry_hash[i].list, list) { | ||
412 | if (entry->dev == dev) | ||
413 | count += 1; | ||
414 | } | ||
415 | spin_unlock_irqrestore(&dma_entry_hash[i].lock, flags); | ||
416 | } | ||
417 | |||
418 | return count; | ||
419 | } | ||
420 | |||
421 | static int dma_debug_device_change(struct notifier_block *nb, | ||
422 | unsigned long action, void *data) | ||
423 | { | ||
424 | struct device *dev = data; | ||
425 | int count; | ||
426 | |||
427 | |||
428 | switch (action) { | ||
429 | case BUS_NOTIFY_UNBIND_DRIVER: | ||
430 | count = device_dma_allocations(dev); | ||
431 | if (count == 0) | ||
432 | break; | ||
433 | err_printk(dev, NULL, "DMA-API: device driver has pending " | ||
434 | "DMA allocations while released from device " | ||
435 | "[count=%d]\n", count); | ||
436 | break; | ||
437 | default: | ||
438 | break; | ||
439 | } | ||
440 | |||
441 | return 0; | ||
442 | } | ||
443 | |||
444 | void dma_debug_add_bus(struct bus_type *bus) | ||
445 | { | ||
446 | struct notifier_block *nb; | ||
447 | |||
448 | nb = kzalloc(sizeof(struct notifier_block), GFP_KERNEL); | ||
449 | if (nb == NULL) { | ||
450 | printk(KERN_ERR "dma_debug_add_bus: out of memory\n"); | ||
451 | return; | ||
452 | } | ||
453 | |||
454 | nb->notifier_call = dma_debug_device_change; | ||
455 | |||
456 | bus_register_notifier(bus, nb); | ||
457 | } | ||
458 | |||
459 | /* | ||
460 | * Let the architectures decide how many entries should be preallocated. | ||
461 | */ | ||
462 | void dma_debug_init(u32 num_entries) | ||
463 | { | ||
464 | int i; | ||
465 | |||
466 | if (global_disable) | ||
467 | return; | ||
468 | |||
469 | for (i = 0; i < HASH_SIZE; ++i) { | ||
470 | INIT_LIST_HEAD(&dma_entry_hash[i].list); | ||
471 | dma_entry_hash[i].lock = SPIN_LOCK_UNLOCKED; | ||
472 | } | ||
473 | |||
474 | if (dma_debug_fs_init() != 0) { | ||
475 | printk(KERN_ERR "DMA-API: error creating debugfs entries " | ||
476 | "- disabling\n"); | ||
477 | global_disable = true; | ||
478 | |||
479 | return; | ||
480 | } | ||
481 | |||
482 | if (req_entries) | ||
483 | num_entries = req_entries; | ||
484 | |||
485 | if (prealloc_memory(num_entries) != 0) { | ||
486 | printk(KERN_ERR "DMA-API: debugging out of memory error " | ||
487 | "- disabled\n"); | ||
488 | global_disable = true; | ||
489 | |||
490 | return; | ||
491 | } | ||
492 | |||
493 | printk(KERN_INFO "DMA-API: debugging enabled by kernel config\n"); | ||
494 | } | ||
495 | |||
496 | static __init int dma_debug_cmdline(char *str) | ||
497 | { | ||
498 | if (!str) | ||
499 | return -EINVAL; | ||
500 | |||
501 | if (strncmp(str, "off", 3) == 0) { | ||
502 | printk(KERN_INFO "DMA-API: debugging disabled on kernel " | ||
503 | "command line\n"); | ||
504 | global_disable = true; | ||
505 | } | ||
506 | |||
507 | return 0; | ||
508 | } | ||
509 | |||
510 | static __init int dma_debug_entries_cmdline(char *str) | ||
511 | { | ||
512 | int res; | ||
513 | |||
514 | if (!str) | ||
515 | return -EINVAL; | ||
516 | |||
517 | res = get_option(&str, &req_entries); | ||
518 | |||
519 | if (!res) | ||
520 | req_entries = 0; | ||
521 | |||
522 | return 0; | ||
523 | } | ||
524 | |||
525 | __setup("dma_debug=", dma_debug_cmdline); | ||
526 | __setup("dma_debug_entries=", dma_debug_entries_cmdline); | ||
527 | |||
528 | static void check_unmap(struct dma_debug_entry *ref) | ||
529 | { | ||
530 | struct dma_debug_entry *entry; | ||
531 | struct hash_bucket *bucket; | ||
532 | unsigned long flags; | ||
533 | |||
534 | if (dma_mapping_error(ref->dev, ref->dev_addr)) { | ||
535 | err_printk(ref->dev, NULL, "DMA-API: device driver tries " | ||
536 | "to free an invalid DMA memory address\n"); | ||
537 | return; | ||
538 | } | ||
539 | |||
540 | bucket = get_hash_bucket(ref, &flags); | ||
541 | entry = hash_bucket_find(bucket, ref); | ||
542 | |||
543 | if (!entry) { | ||
544 | err_printk(ref->dev, NULL, "DMA-API: device driver tries " | ||
545 | "to free DMA memory it has not allocated " | ||
546 | "[device address=0x%016llx] [size=%llu bytes]\n", | ||
547 | ref->dev_addr, ref->size); | ||
548 | goto out; | ||
549 | } | ||
550 | |||
551 | if (ref->size != entry->size) { | ||
552 | err_printk(ref->dev, entry, "DMA-API: device driver frees " | ||
553 | "DMA memory with different size " | ||
554 | "[device address=0x%016llx] [map size=%llu bytes] " | ||
555 | "[unmap size=%llu bytes]\n", | ||
556 | ref->dev_addr, entry->size, ref->size); | ||
557 | } | ||
558 | |||
559 | if (ref->type != entry->type) { | ||
560 | err_printk(ref->dev, entry, "DMA-API: device driver frees " | ||
561 | "DMA memory with wrong function " | ||
562 | "[device address=0x%016llx] [size=%llu bytes] " | ||
563 | "[mapped as %s] [unmapped as %s]\n", | ||
564 | ref->dev_addr, ref->size, | ||
565 | type2name[entry->type], type2name[ref->type]); | ||
566 | } else if ((entry->type == dma_debug_coherent) && | ||
567 | (ref->paddr != entry->paddr)) { | ||
568 | err_printk(ref->dev, entry, "DMA-API: device driver frees " | ||
569 | "DMA memory with different CPU address " | ||
570 | "[device address=0x%016llx] [size=%llu bytes] " | ||
571 | "[cpu alloc address=%p] [cpu free address=%p]", | ||
572 | ref->dev_addr, ref->size, | ||
573 | (void *)entry->paddr, (void *)ref->paddr); | ||
574 | } | ||
575 | |||
576 | if (ref->sg_call_ents && ref->type == dma_debug_sg && | ||
577 | ref->sg_call_ents != entry->sg_call_ents) { | ||
578 | err_printk(ref->dev, entry, "DMA-API: device driver frees " | ||
579 | "DMA sg list with different entry count " | ||
580 | "[map count=%d] [unmap count=%d]\n", | ||
581 | entry->sg_call_ents, ref->sg_call_ents); | ||
582 | } | ||
583 | |||
584 | /* | ||
585 | * This may be no bug in reality - but most implementations of the | ||
586 | * DMA API don't handle this properly, so check for it here | ||
587 | */ | ||
588 | if (ref->direction != entry->direction) { | ||
589 | err_printk(ref->dev, entry, "DMA-API: device driver frees " | ||
590 | "DMA memory with different direction " | ||
591 | "[device address=0x%016llx] [size=%llu bytes] " | ||
592 | "[mapped with %s] [unmapped with %s]\n", | ||
593 | ref->dev_addr, ref->size, | ||
594 | dir2name[entry->direction], | ||
595 | dir2name[ref->direction]); | ||
596 | } | ||
597 | |||
598 | hash_bucket_del(entry); | ||
599 | dma_entry_free(entry); | ||
600 | |||
601 | out: | ||
602 | put_hash_bucket(bucket, &flags); | ||
603 | } | ||
604 | |||
605 | static void check_for_stack(struct device *dev, void *addr) | ||
606 | { | ||
607 | if (object_is_on_stack(addr)) | ||
608 | err_printk(dev, NULL, "DMA-API: device driver maps memory from" | ||
609 | "stack [addr=%p]\n", addr); | ||
610 | } | ||
611 | |||
612 | static inline bool overlap(void *addr, u64 size, void *start, void *end) | ||
613 | { | ||
614 | void *addr2 = (char *)addr + size; | ||
615 | |||
616 | return ((addr >= start && addr < end) || | ||
617 | (addr2 >= start && addr2 < end) || | ||
618 | ((addr < start) && (addr2 >= end))); | ||
619 | } | ||
620 | |||
621 | static void check_for_illegal_area(struct device *dev, void *addr, u64 size) | ||
622 | { | ||
623 | if (overlap(addr, size, _text, _etext) || | ||
624 | overlap(addr, size, __start_rodata, __end_rodata)) | ||
625 | err_printk(dev, NULL, "DMA-API: device driver maps " | ||
626 | "memory from kernel text or rodata " | ||
627 | "[addr=%p] [size=%llu]\n", addr, size); | ||
628 | } | ||
629 | |||
630 | static void check_sync(struct device *dev, dma_addr_t addr, | ||
631 | u64 size, u64 offset, int direction, bool to_cpu) | ||
632 | { | ||
633 | struct dma_debug_entry ref = { | ||
634 | .dev = dev, | ||
635 | .dev_addr = addr, | ||
636 | .size = size, | ||
637 | .direction = direction, | ||
638 | }; | ||
639 | struct dma_debug_entry *entry; | ||
640 | struct hash_bucket *bucket; | ||
641 | unsigned long flags; | ||
642 | |||
643 | bucket = get_hash_bucket(&ref, &flags); | ||
644 | |||
645 | entry = hash_bucket_find(bucket, &ref); | ||
646 | |||
647 | if (!entry) { | ||
648 | err_printk(dev, NULL, "DMA-API: device driver tries " | ||
649 | "to sync DMA memory it has not allocated " | ||
650 | "[device address=0x%016llx] [size=%llu bytes]\n", | ||
651 | (unsigned long long)addr, size); | ||
652 | goto out; | ||
653 | } | ||
654 | |||
655 | if ((offset + size) > entry->size) { | ||
656 | err_printk(dev, entry, "DMA-API: device driver syncs" | ||
657 | " DMA memory outside allocated range " | ||
658 | "[device address=0x%016llx] " | ||
659 | "[allocation size=%llu bytes] [sync offset=%llu] " | ||
660 | "[sync size=%llu]\n", entry->dev_addr, entry->size, | ||
661 | offset, size); | ||
662 | } | ||
663 | |||
664 | if (direction != entry->direction) { | ||
665 | err_printk(dev, entry, "DMA-API: device driver syncs " | ||
666 | "DMA memory with different direction " | ||
667 | "[device address=0x%016llx] [size=%llu bytes] " | ||
668 | "[mapped with %s] [synced with %s]\n", | ||
669 | (unsigned long long)addr, entry->size, | ||
670 | dir2name[entry->direction], | ||
671 | dir2name[direction]); | ||
672 | } | ||
673 | |||
674 | if (entry->direction == DMA_BIDIRECTIONAL) | ||
675 | goto out; | ||
676 | |||
677 | if (to_cpu && !(entry->direction == DMA_FROM_DEVICE) && | ||
678 | !(direction == DMA_TO_DEVICE)) | ||
679 | err_printk(dev, entry, "DMA-API: device driver syncs " | ||
680 | "device read-only DMA memory for cpu " | ||
681 | "[device address=0x%016llx] [size=%llu bytes] " | ||
682 | "[mapped with %s] [synced with %s]\n", | ||
683 | (unsigned long long)addr, entry->size, | ||
684 | dir2name[entry->direction], | ||
685 | dir2name[direction]); | ||
686 | |||
687 | if (!to_cpu && !(entry->direction == DMA_TO_DEVICE) && | ||
688 | !(direction == DMA_FROM_DEVICE)) | ||
689 | err_printk(dev, entry, "DMA-API: device driver syncs " | ||
690 | "device write-only DMA memory to device " | ||
691 | "[device address=0x%016llx] [size=%llu bytes] " | ||
692 | "[mapped with %s] [synced with %s]\n", | ||
693 | (unsigned long long)addr, entry->size, | ||
694 | dir2name[entry->direction], | ||
695 | dir2name[direction]); | ||
696 | |||
697 | out: | ||
698 | put_hash_bucket(bucket, &flags); | ||
699 | |||
700 | } | ||
701 | |||
702 | void debug_dma_map_page(struct device *dev, struct page *page, size_t offset, | ||
703 | size_t size, int direction, dma_addr_t dma_addr, | ||
704 | bool map_single) | ||
705 | { | ||
706 | struct dma_debug_entry *entry; | ||
707 | |||
708 | if (unlikely(global_disable)) | ||
709 | return; | ||
710 | |||
711 | if (unlikely(dma_mapping_error(dev, dma_addr))) | ||
712 | return; | ||
713 | |||
714 | entry = dma_entry_alloc(); | ||
715 | if (!entry) | ||
716 | return; | ||
717 | |||
718 | entry->dev = dev; | ||
719 | entry->type = dma_debug_page; | ||
720 | entry->paddr = page_to_phys(page) + offset; | ||
721 | entry->dev_addr = dma_addr; | ||
722 | entry->size = size; | ||
723 | entry->direction = direction; | ||
724 | |||
725 | if (map_single) | ||
726 | entry->type = dma_debug_single; | ||
727 | |||
728 | if (!PageHighMem(page)) { | ||
729 | void *addr = ((char *)page_address(page)) + offset; | ||
730 | check_for_stack(dev, addr); | ||
731 | check_for_illegal_area(dev, addr, size); | ||
732 | } | ||
733 | |||
734 | add_dma_entry(entry); | ||
735 | } | ||
736 | EXPORT_SYMBOL(debug_dma_map_page); | ||
737 | |||
738 | void debug_dma_unmap_page(struct device *dev, dma_addr_t addr, | ||
739 | size_t size, int direction, bool map_single) | ||
740 | { | ||
741 | struct dma_debug_entry ref = { | ||
742 | .type = dma_debug_page, | ||
743 | .dev = dev, | ||
744 | .dev_addr = addr, | ||
745 | .size = size, | ||
746 | .direction = direction, | ||
747 | }; | ||
748 | |||
749 | if (unlikely(global_disable)) | ||
750 | return; | ||
751 | |||
752 | if (map_single) | ||
753 | ref.type = dma_debug_single; | ||
754 | |||
755 | check_unmap(&ref); | ||
756 | } | ||
757 | EXPORT_SYMBOL(debug_dma_unmap_page); | ||
758 | |||
759 | void debug_dma_map_sg(struct device *dev, struct scatterlist *sg, | ||
760 | int nents, int mapped_ents, int direction) | ||
761 | { | ||
762 | struct dma_debug_entry *entry; | ||
763 | struct scatterlist *s; | ||
764 | int i; | ||
765 | |||
766 | if (unlikely(global_disable)) | ||
767 | return; | ||
768 | |||
769 | for_each_sg(sg, s, mapped_ents, i) { | ||
770 | entry = dma_entry_alloc(); | ||
771 | if (!entry) | ||
772 | return; | ||
773 | |||
774 | entry->type = dma_debug_sg; | ||
775 | entry->dev = dev; | ||
776 | entry->paddr = sg_phys(s); | ||
777 | entry->size = s->length; | ||
778 | entry->dev_addr = s->dma_address; | ||
779 | entry->direction = direction; | ||
780 | entry->sg_call_ents = nents; | ||
781 | entry->sg_mapped_ents = mapped_ents; | ||
782 | |||
783 | if (!PageHighMem(sg_page(s))) { | ||
784 | check_for_stack(dev, sg_virt(s)); | ||
785 | check_for_illegal_area(dev, sg_virt(s), s->length); | ||
786 | } | ||
787 | |||
788 | add_dma_entry(entry); | ||
789 | } | ||
790 | } | ||
791 | EXPORT_SYMBOL(debug_dma_map_sg); | ||
792 | |||
793 | void debug_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, | ||
794 | int nelems, int dir) | ||
795 | { | ||
796 | struct dma_debug_entry *entry; | ||
797 | struct scatterlist *s; | ||
798 | int mapped_ents = 0, i; | ||
799 | unsigned long flags; | ||
800 | |||
801 | if (unlikely(global_disable)) | ||
802 | return; | ||
803 | |||
804 | for_each_sg(sglist, s, nelems, i) { | ||
805 | |||
806 | struct dma_debug_entry ref = { | ||
807 | .type = dma_debug_sg, | ||
808 | .dev = dev, | ||
809 | .paddr = sg_phys(s), | ||
810 | .dev_addr = s->dma_address, | ||
811 | .size = s->length, | ||
812 | .direction = dir, | ||
813 | .sg_call_ents = 0, | ||
814 | }; | ||
815 | |||
816 | if (mapped_ents && i >= mapped_ents) | ||
817 | break; | ||
818 | |||
819 | if (mapped_ents == 0) { | ||
820 | struct hash_bucket *bucket; | ||
821 | ref.sg_call_ents = nelems; | ||
822 | bucket = get_hash_bucket(&ref, &flags); | ||
823 | entry = hash_bucket_find(bucket, &ref); | ||
824 | if (entry) | ||
825 | mapped_ents = entry->sg_mapped_ents; | ||
826 | put_hash_bucket(bucket, &flags); | ||
827 | } | ||
828 | |||
829 | check_unmap(&ref); | ||
830 | } | ||
831 | } | ||
832 | EXPORT_SYMBOL(debug_dma_unmap_sg); | ||
833 | |||
834 | void debug_dma_alloc_coherent(struct device *dev, size_t size, | ||
835 | dma_addr_t dma_addr, void *virt) | ||
836 | { | ||
837 | struct dma_debug_entry *entry; | ||
838 | |||
839 | if (unlikely(global_disable)) | ||
840 | return; | ||
841 | |||
842 | if (unlikely(virt == NULL)) | ||
843 | return; | ||
844 | |||
845 | entry = dma_entry_alloc(); | ||
846 | if (!entry) | ||
847 | return; | ||
848 | |||
849 | entry->type = dma_debug_coherent; | ||
850 | entry->dev = dev; | ||
851 | entry->paddr = virt_to_phys(virt); | ||
852 | entry->size = size; | ||
853 | entry->dev_addr = dma_addr; | ||
854 | entry->direction = DMA_BIDIRECTIONAL; | ||
855 | |||
856 | add_dma_entry(entry); | ||
857 | } | ||
858 | EXPORT_SYMBOL(debug_dma_alloc_coherent); | ||
859 | |||
860 | void debug_dma_free_coherent(struct device *dev, size_t size, | ||
861 | void *virt, dma_addr_t addr) | ||
862 | { | ||
863 | struct dma_debug_entry ref = { | ||
864 | .type = dma_debug_coherent, | ||
865 | .dev = dev, | ||
866 | .paddr = virt_to_phys(virt), | ||
867 | .dev_addr = addr, | ||
868 | .size = size, | ||
869 | .direction = DMA_BIDIRECTIONAL, | ||
870 | }; | ||
871 | |||
872 | if (unlikely(global_disable)) | ||
873 | return; | ||
874 | |||
875 | check_unmap(&ref); | ||
876 | } | ||
877 | EXPORT_SYMBOL(debug_dma_free_coherent); | ||
878 | |||
879 | void debug_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, | ||
880 | size_t size, int direction) | ||
881 | { | ||
882 | if (unlikely(global_disable)) | ||
883 | return; | ||
884 | |||
885 | check_sync(dev, dma_handle, size, 0, direction, true); | ||
886 | } | ||
887 | EXPORT_SYMBOL(debug_dma_sync_single_for_cpu); | ||
888 | |||
889 | void debug_dma_sync_single_for_device(struct device *dev, | ||
890 | dma_addr_t dma_handle, size_t size, | ||
891 | int direction) | ||
892 | { | ||
893 | if (unlikely(global_disable)) | ||
894 | return; | ||
895 | |||
896 | check_sync(dev, dma_handle, size, 0, direction, false); | ||
897 | } | ||
898 | EXPORT_SYMBOL(debug_dma_sync_single_for_device); | ||
899 | |||
900 | void debug_dma_sync_single_range_for_cpu(struct device *dev, | ||
901 | dma_addr_t dma_handle, | ||
902 | unsigned long offset, size_t size, | ||
903 | int direction) | ||
904 | { | ||
905 | if (unlikely(global_disable)) | ||
906 | return; | ||
907 | |||
908 | check_sync(dev, dma_handle, size, offset, direction, true); | ||
909 | } | ||
910 | EXPORT_SYMBOL(debug_dma_sync_single_range_for_cpu); | ||
911 | |||
912 | void debug_dma_sync_single_range_for_device(struct device *dev, | ||
913 | dma_addr_t dma_handle, | ||
914 | unsigned long offset, | ||
915 | size_t size, int direction) | ||
916 | { | ||
917 | if (unlikely(global_disable)) | ||
918 | return; | ||
919 | |||
920 | check_sync(dev, dma_handle, size, offset, direction, false); | ||
921 | } | ||
922 | EXPORT_SYMBOL(debug_dma_sync_single_range_for_device); | ||
923 | |||
924 | void debug_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, | ||
925 | int nelems, int direction) | ||
926 | { | ||
927 | struct scatterlist *s; | ||
928 | int i; | ||
929 | |||
930 | if (unlikely(global_disable)) | ||
931 | return; | ||
932 | |||
933 | for_each_sg(sg, s, nelems, i) { | ||
934 | check_sync(dev, s->dma_address, s->dma_length, 0, | ||
935 | direction, true); | ||
936 | } | ||
937 | } | ||
938 | EXPORT_SYMBOL(debug_dma_sync_sg_for_cpu); | ||
939 | |||
940 | void debug_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, | ||
941 | int nelems, int direction) | ||
942 | { | ||
943 | struct scatterlist *s; | ||
944 | int i; | ||
945 | |||
946 | if (unlikely(global_disable)) | ||
947 | return; | ||
948 | |||
949 | for_each_sg(sg, s, nelems, i) { | ||
950 | check_sync(dev, s->dma_address, s->dma_length, 0, | ||
951 | direction, false); | ||
952 | } | ||
953 | } | ||
954 | EXPORT_SYMBOL(debug_dma_sync_sg_for_device); | ||
955 | |||
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c new file mode 100644 index 000000000000..833139ce1e22 --- /dev/null +++ b/lib/dynamic_debug.c | |||
@@ -0,0 +1,769 @@ | |||
1 | /* | ||
2 | * lib/dynamic_debug.c | ||
3 | * | ||
4 | * make pr_debug()/dev_dbg() calls runtime configurable based upon their | ||
5 | * source module. | ||
6 | * | ||
7 | * Copyright (C) 2008 Jason Baron <jbaron@redhat.com> | ||
8 | * By Greg Banks <gnb@melbourne.sgi.com> | ||
9 | * Copyright (c) 2008 Silicon Graphics Inc. All Rights Reserved. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/moduleparam.h> | ||
15 | #include <linux/kallsyms.h> | ||
16 | #include <linux/version.h> | ||
17 | #include <linux/types.h> | ||
18 | #include <linux/mutex.h> | ||
19 | #include <linux/proc_fs.h> | ||
20 | #include <linux/seq_file.h> | ||
21 | #include <linux/list.h> | ||
22 | #include <linux/sysctl.h> | ||
23 | #include <linux/ctype.h> | ||
24 | #include <linux/uaccess.h> | ||
25 | #include <linux/dynamic_debug.h> | ||
26 | #include <linux/debugfs.h> | ||
27 | |||
28 | extern struct _ddebug __start___verbose[]; | ||
29 | extern struct _ddebug __stop___verbose[]; | ||
30 | |||
31 | /* dynamic_debug_enabled, and dynamic_debug_enabled2 are bitmasks in which | ||
32 | * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They | ||
33 | * use independent hash functions, to reduce the chance of false positives. | ||
34 | */ | ||
35 | long long dynamic_debug_enabled; | ||
36 | EXPORT_SYMBOL_GPL(dynamic_debug_enabled); | ||
37 | long long dynamic_debug_enabled2; | ||
38 | EXPORT_SYMBOL_GPL(dynamic_debug_enabled2); | ||
39 | |||
40 | struct ddebug_table { | ||
41 | struct list_head link; | ||
42 | char *mod_name; | ||
43 | unsigned int num_ddebugs; | ||
44 | unsigned int num_enabled; | ||
45 | struct _ddebug *ddebugs; | ||
46 | }; | ||
47 | |||
48 | struct ddebug_query { | ||
49 | const char *filename; | ||
50 | const char *module; | ||
51 | const char *function; | ||
52 | const char *format; | ||
53 | unsigned int first_lineno, last_lineno; | ||
54 | }; | ||
55 | |||
56 | struct ddebug_iter { | ||
57 | struct ddebug_table *table; | ||
58 | unsigned int idx; | ||
59 | }; | ||
60 | |||
61 | static DEFINE_MUTEX(ddebug_lock); | ||
62 | static LIST_HEAD(ddebug_tables); | ||
63 | static int verbose = 0; | ||
64 | |||
65 | /* Return the last part of a pathname */ | ||
66 | static inline const char *basename(const char *path) | ||
67 | { | ||
68 | const char *tail = strrchr(path, '/'); | ||
69 | return tail ? tail+1 : path; | ||
70 | } | ||
71 | |||
72 | /* format a string into buf[] which describes the _ddebug's flags */ | ||
73 | static char *ddebug_describe_flags(struct _ddebug *dp, char *buf, | ||
74 | size_t maxlen) | ||
75 | { | ||
76 | char *p = buf; | ||
77 | |||
78 | BUG_ON(maxlen < 4); | ||
79 | if (dp->flags & _DPRINTK_FLAGS_PRINT) | ||
80 | *p++ = 'p'; | ||
81 | if (p == buf) | ||
82 | *p++ = '-'; | ||
83 | *p = '\0'; | ||
84 | |||
85 | return buf; | ||
86 | } | ||
87 | |||
88 | /* | ||
89 | * must be called with ddebug_lock held | ||
90 | */ | ||
91 | |||
92 | static int disabled_hash(char hash, bool first_table) | ||
93 | { | ||
94 | struct ddebug_table *dt; | ||
95 | char table_hash_value; | ||
96 | |||
97 | list_for_each_entry(dt, &ddebug_tables, link) { | ||
98 | if (first_table) | ||
99 | table_hash_value = dt->ddebugs->primary_hash; | ||
100 | else | ||
101 | table_hash_value = dt->ddebugs->secondary_hash; | ||
102 | if (dt->num_enabled && (hash == table_hash_value)) | ||
103 | return 0; | ||
104 | } | ||
105 | return 1; | ||
106 | } | ||
107 | |||
108 | /* | ||
109 | * Search the tables for _ddebug's which match the given | ||
110 | * `query' and apply the `flags' and `mask' to them. Tells | ||
111 | * the user which ddebug's were changed, or whether none | ||
112 | * were matched. | ||
113 | */ | ||
114 | static void ddebug_change(const struct ddebug_query *query, | ||
115 | unsigned int flags, unsigned int mask) | ||
116 | { | ||
117 | int i; | ||
118 | struct ddebug_table *dt; | ||
119 | unsigned int newflags; | ||
120 | unsigned int nfound = 0; | ||
121 | char flagbuf[8]; | ||
122 | |||
123 | /* search for matching ddebugs */ | ||
124 | mutex_lock(&ddebug_lock); | ||
125 | list_for_each_entry(dt, &ddebug_tables, link) { | ||
126 | |||
127 | /* match against the module name */ | ||
128 | if (query->module != NULL && | ||
129 | strcmp(query->module, dt->mod_name)) | ||
130 | continue; | ||
131 | |||
132 | for (i = 0 ; i < dt->num_ddebugs ; i++) { | ||
133 | struct _ddebug *dp = &dt->ddebugs[i]; | ||
134 | |||
135 | /* match against the source filename */ | ||
136 | if (query->filename != NULL && | ||
137 | strcmp(query->filename, dp->filename) && | ||
138 | strcmp(query->filename, basename(dp->filename))) | ||
139 | continue; | ||
140 | |||
141 | /* match against the function */ | ||
142 | if (query->function != NULL && | ||
143 | strcmp(query->function, dp->function)) | ||
144 | continue; | ||
145 | |||
146 | /* match against the format */ | ||
147 | if (query->format != NULL && | ||
148 | strstr(dp->format, query->format) == NULL) | ||
149 | continue; | ||
150 | |||
151 | /* match against the line number range */ | ||
152 | if (query->first_lineno && | ||
153 | dp->lineno < query->first_lineno) | ||
154 | continue; | ||
155 | if (query->last_lineno && | ||
156 | dp->lineno > query->last_lineno) | ||
157 | continue; | ||
158 | |||
159 | nfound++; | ||
160 | |||
161 | newflags = (dp->flags & mask) | flags; | ||
162 | if (newflags == dp->flags) | ||
163 | continue; | ||
164 | |||
165 | if (!newflags) | ||
166 | dt->num_enabled--; | ||
167 | else if (!dp-flags) | ||
168 | dt->num_enabled++; | ||
169 | dp->flags = newflags; | ||
170 | if (newflags) { | ||
171 | dynamic_debug_enabled |= | ||
172 | (1LL << dp->primary_hash); | ||
173 | dynamic_debug_enabled2 |= | ||
174 | (1LL << dp->secondary_hash); | ||
175 | } else { | ||
176 | if (disabled_hash(dp->primary_hash, true)) | ||
177 | dynamic_debug_enabled &= | ||
178 | ~(1LL << dp->primary_hash); | ||
179 | if (disabled_hash(dp->secondary_hash, false)) | ||
180 | dynamic_debug_enabled2 &= | ||
181 | ~(1LL << dp->secondary_hash); | ||
182 | } | ||
183 | if (verbose) | ||
184 | printk(KERN_INFO | ||
185 | "ddebug: changed %s:%d [%s]%s %s\n", | ||
186 | dp->filename, dp->lineno, | ||
187 | dt->mod_name, dp->function, | ||
188 | ddebug_describe_flags(dp, flagbuf, | ||
189 | sizeof(flagbuf))); | ||
190 | } | ||
191 | } | ||
192 | mutex_unlock(&ddebug_lock); | ||
193 | |||
194 | if (!nfound && verbose) | ||
195 | printk(KERN_INFO "ddebug: no matches for query\n"); | ||
196 | } | ||
197 | |||
198 | /* | ||
199 | * Split the buffer `buf' into space-separated words. | ||
200 | * Handles simple " and ' quoting, i.e. without nested, | ||
201 | * embedded or escaped \". Return the number of words | ||
202 | * or <0 on error. | ||
203 | */ | ||
204 | static int ddebug_tokenize(char *buf, char *words[], int maxwords) | ||
205 | { | ||
206 | int nwords = 0; | ||
207 | |||
208 | while (*buf) { | ||
209 | char *end; | ||
210 | |||
211 | /* Skip leading whitespace */ | ||
212 | while (*buf && isspace(*buf)) | ||
213 | buf++; | ||
214 | if (!*buf) | ||
215 | break; /* oh, it was trailing whitespace */ | ||
216 | |||
217 | /* Run `end' over a word, either whitespace separated or quoted */ | ||
218 | if (*buf == '"' || *buf == '\'') { | ||
219 | int quote = *buf++; | ||
220 | for (end = buf ; *end && *end != quote ; end++) | ||
221 | ; | ||
222 | if (!*end) | ||
223 | return -EINVAL; /* unclosed quote */ | ||
224 | } else { | ||
225 | for (end = buf ; *end && !isspace(*end) ; end++) | ||
226 | ; | ||
227 | BUG_ON(end == buf); | ||
228 | } | ||
229 | /* Here `buf' is the start of the word, `end' is one past the end */ | ||
230 | |||
231 | if (nwords == maxwords) | ||
232 | return -EINVAL; /* ran out of words[] before bytes */ | ||
233 | if (*end) | ||
234 | *end++ = '\0'; /* terminate the word */ | ||
235 | words[nwords++] = buf; | ||
236 | buf = end; | ||
237 | } | ||
238 | |||
239 | if (verbose) { | ||
240 | int i; | ||
241 | printk(KERN_INFO "%s: split into words:", __func__); | ||
242 | for (i = 0 ; i < nwords ; i++) | ||
243 | printk(" \"%s\"", words[i]); | ||
244 | printk("\n"); | ||
245 | } | ||
246 | |||
247 | return nwords; | ||
248 | } | ||
249 | |||
250 | /* | ||
251 | * Parse a single line number. Note that the empty string "" | ||
252 | * is treated as a special case and converted to zero, which | ||
253 | * is later treated as a "don't care" value. | ||
254 | */ | ||
255 | static inline int parse_lineno(const char *str, unsigned int *val) | ||
256 | { | ||
257 | char *end = NULL; | ||
258 | BUG_ON(str == NULL); | ||
259 | if (*str == '\0') { | ||
260 | *val = 0; | ||
261 | return 0; | ||
262 | } | ||
263 | *val = simple_strtoul(str, &end, 10); | ||
264 | return end == NULL || end == str || *end != '\0' ? -EINVAL : 0; | ||
265 | } | ||
266 | |||
267 | /* | ||
268 | * Undo octal escaping in a string, inplace. This is useful to | ||
269 | * allow the user to express a query which matches a format | ||
270 | * containing embedded spaces. | ||
271 | */ | ||
272 | #define isodigit(c) ((c) >= '0' && (c) <= '7') | ||
273 | static char *unescape(char *str) | ||
274 | { | ||
275 | char *in = str; | ||
276 | char *out = str; | ||
277 | |||
278 | while (*in) { | ||
279 | if (*in == '\\') { | ||
280 | if (in[1] == '\\') { | ||
281 | *out++ = '\\'; | ||
282 | in += 2; | ||
283 | continue; | ||
284 | } else if (in[1] == 't') { | ||
285 | *out++ = '\t'; | ||
286 | in += 2; | ||
287 | continue; | ||
288 | } else if (in[1] == 'n') { | ||
289 | *out++ = '\n'; | ||
290 | in += 2; | ||
291 | continue; | ||
292 | } else if (isodigit(in[1]) && | ||
293 | isodigit(in[2]) && | ||
294 | isodigit(in[3])) { | ||
295 | *out++ = ((in[1] - '0')<<6) | | ||
296 | ((in[2] - '0')<<3) | | ||
297 | (in[3] - '0'); | ||
298 | in += 4; | ||
299 | continue; | ||
300 | } | ||
301 | } | ||
302 | *out++ = *in++; | ||
303 | } | ||
304 | *out = '\0'; | ||
305 | |||
306 | return str; | ||
307 | } | ||
308 | |||
309 | /* | ||
310 | * Parse words[] as a ddebug query specification, which is a series | ||
311 | * of (keyword, value) pairs chosen from these possibilities: | ||
312 | * | ||
313 | * func <function-name> | ||
314 | * file <full-pathname> | ||
315 | * file <base-filename> | ||
316 | * module <module-name> | ||
317 | * format <escaped-string-to-find-in-format> | ||
318 | * line <lineno> | ||
319 | * line <first-lineno>-<last-lineno> // where either may be empty | ||
320 | */ | ||
321 | static int ddebug_parse_query(char *words[], int nwords, | ||
322 | struct ddebug_query *query) | ||
323 | { | ||
324 | unsigned int i; | ||
325 | |||
326 | /* check we have an even number of words */ | ||
327 | if (nwords % 2 != 0) | ||
328 | return -EINVAL; | ||
329 | memset(query, 0, sizeof(*query)); | ||
330 | |||
331 | for (i = 0 ; i < nwords ; i += 2) { | ||
332 | if (!strcmp(words[i], "func")) | ||
333 | query->function = words[i+1]; | ||
334 | else if (!strcmp(words[i], "file")) | ||
335 | query->filename = words[i+1]; | ||
336 | else if (!strcmp(words[i], "module")) | ||
337 | query->module = words[i+1]; | ||
338 | else if (!strcmp(words[i], "format")) | ||
339 | query->format = unescape(words[i+1]); | ||
340 | else if (!strcmp(words[i], "line")) { | ||
341 | char *first = words[i+1]; | ||
342 | char *last = strchr(first, '-'); | ||
343 | if (last) | ||
344 | *last++ = '\0'; | ||
345 | if (parse_lineno(first, &query->first_lineno) < 0) | ||
346 | return -EINVAL; | ||
347 | if (last != NULL) { | ||
348 | /* range <first>-<last> */ | ||
349 | if (parse_lineno(last, &query->last_lineno) < 0) | ||
350 | return -EINVAL; | ||
351 | } else { | ||
352 | query->last_lineno = query->first_lineno; | ||
353 | } | ||
354 | } else { | ||
355 | if (verbose) | ||
356 | printk(KERN_ERR "%s: unknown keyword \"%s\"\n", | ||
357 | __func__, words[i]); | ||
358 | return -EINVAL; | ||
359 | } | ||
360 | } | ||
361 | |||
362 | if (verbose) | ||
363 | printk(KERN_INFO "%s: q->function=\"%s\" q->filename=\"%s\" " | ||
364 | "q->module=\"%s\" q->format=\"%s\" q->lineno=%u-%u\n", | ||
365 | __func__, query->function, query->filename, | ||
366 | query->module, query->format, query->first_lineno, | ||
367 | query->last_lineno); | ||
368 | |||
369 | return 0; | ||
370 | } | ||
371 | |||
372 | /* | ||
373 | * Parse `str' as a flags specification, format [-+=][p]+. | ||
374 | * Sets up *maskp and *flagsp to be used when changing the | ||
375 | * flags fields of matched _ddebug's. Returns 0 on success | ||
376 | * or <0 on error. | ||
377 | */ | ||
378 | static int ddebug_parse_flags(const char *str, unsigned int *flagsp, | ||
379 | unsigned int *maskp) | ||
380 | { | ||
381 | unsigned flags = 0; | ||
382 | int op = '='; | ||
383 | |||
384 | switch (*str) { | ||
385 | case '+': | ||
386 | case '-': | ||
387 | case '=': | ||
388 | op = *str++; | ||
389 | break; | ||
390 | default: | ||
391 | return -EINVAL; | ||
392 | } | ||
393 | if (verbose) | ||
394 | printk(KERN_INFO "%s: op='%c'\n", __func__, op); | ||
395 | |||
396 | for ( ; *str ; ++str) { | ||
397 | switch (*str) { | ||
398 | case 'p': | ||
399 | flags |= _DPRINTK_FLAGS_PRINT; | ||
400 | break; | ||
401 | default: | ||
402 | return -EINVAL; | ||
403 | } | ||
404 | } | ||
405 | if (flags == 0) | ||
406 | return -EINVAL; | ||
407 | if (verbose) | ||
408 | printk(KERN_INFO "%s: flags=0x%x\n", __func__, flags); | ||
409 | |||
410 | /* calculate final *flagsp, *maskp according to mask and op */ | ||
411 | switch (op) { | ||
412 | case '=': | ||
413 | *maskp = 0; | ||
414 | *flagsp = flags; | ||
415 | break; | ||
416 | case '+': | ||
417 | *maskp = ~0U; | ||
418 | *flagsp = flags; | ||
419 | break; | ||
420 | case '-': | ||
421 | *maskp = ~flags; | ||
422 | *flagsp = 0; | ||
423 | break; | ||
424 | } | ||
425 | if (verbose) | ||
426 | printk(KERN_INFO "%s: *flagsp=0x%x *maskp=0x%x\n", | ||
427 | __func__, *flagsp, *maskp); | ||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | /* | ||
432 | * File_ops->write method for <debugfs>/dynamic_debug/conrol. Gathers the | ||
433 | * command text from userspace, parses and executes it. | ||
434 | */ | ||
435 | static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf, | ||
436 | size_t len, loff_t *offp) | ||
437 | { | ||
438 | unsigned int flags = 0, mask = 0; | ||
439 | struct ddebug_query query; | ||
440 | #define MAXWORDS 9 | ||
441 | int nwords; | ||
442 | char *words[MAXWORDS]; | ||
443 | char tmpbuf[256]; | ||
444 | |||
445 | if (len == 0) | ||
446 | return 0; | ||
447 | /* we don't check *offp -- multiple writes() are allowed */ | ||
448 | if (len > sizeof(tmpbuf)-1) | ||
449 | return -E2BIG; | ||
450 | if (copy_from_user(tmpbuf, ubuf, len)) | ||
451 | return -EFAULT; | ||
452 | tmpbuf[len] = '\0'; | ||
453 | if (verbose) | ||
454 | printk(KERN_INFO "%s: read %d bytes from userspace\n", | ||
455 | __func__, (int)len); | ||
456 | |||
457 | nwords = ddebug_tokenize(tmpbuf, words, MAXWORDS); | ||
458 | if (nwords < 0) | ||
459 | return -EINVAL; | ||
460 | if (ddebug_parse_query(words, nwords-1, &query)) | ||
461 | return -EINVAL; | ||
462 | if (ddebug_parse_flags(words[nwords-1], &flags, &mask)) | ||
463 | return -EINVAL; | ||
464 | |||
465 | /* actually go and implement the change */ | ||
466 | ddebug_change(&query, flags, mask); | ||
467 | |||
468 | *offp += len; | ||
469 | return len; | ||
470 | } | ||
471 | |||
472 | /* | ||
473 | * Set the iterator to point to the first _ddebug object | ||
474 | * and return a pointer to that first object. Returns | ||
475 | * NULL if there are no _ddebugs at all. | ||
476 | */ | ||
477 | static struct _ddebug *ddebug_iter_first(struct ddebug_iter *iter) | ||
478 | { | ||
479 | if (list_empty(&ddebug_tables)) { | ||
480 | iter->table = NULL; | ||
481 | iter->idx = 0; | ||
482 | return NULL; | ||
483 | } | ||
484 | iter->table = list_entry(ddebug_tables.next, | ||
485 | struct ddebug_table, link); | ||
486 | iter->idx = 0; | ||
487 | return &iter->table->ddebugs[iter->idx]; | ||
488 | } | ||
489 | |||
490 | /* | ||
491 | * Advance the iterator to point to the next _ddebug | ||
492 | * object from the one the iterator currently points at, | ||
493 | * and returns a pointer to the new _ddebug. Returns | ||
494 | * NULL if the iterator has seen all the _ddebugs. | ||
495 | */ | ||
496 | static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter) | ||
497 | { | ||
498 | if (iter->table == NULL) | ||
499 | return NULL; | ||
500 | if (++iter->idx == iter->table->num_ddebugs) { | ||
501 | /* iterate to next table */ | ||
502 | iter->idx = 0; | ||
503 | if (list_is_last(&iter->table->link, &ddebug_tables)) { | ||
504 | iter->table = NULL; | ||
505 | return NULL; | ||
506 | } | ||
507 | iter->table = list_entry(iter->table->link.next, | ||
508 | struct ddebug_table, link); | ||
509 | } | ||
510 | return &iter->table->ddebugs[iter->idx]; | ||
511 | } | ||
512 | |||
513 | /* | ||
514 | * Seq_ops start method. Called at the start of every | ||
515 | * read() call from userspace. Takes the ddebug_lock and | ||
516 | * seeks the seq_file's iterator to the given position. | ||
517 | */ | ||
518 | static void *ddebug_proc_start(struct seq_file *m, loff_t *pos) | ||
519 | { | ||
520 | struct ddebug_iter *iter = m->private; | ||
521 | struct _ddebug *dp; | ||
522 | int n = *pos; | ||
523 | |||
524 | if (verbose) | ||
525 | printk(KERN_INFO "%s: called m=%p *pos=%lld\n", | ||
526 | __func__, m, (unsigned long long)*pos); | ||
527 | |||
528 | mutex_lock(&ddebug_lock); | ||
529 | |||
530 | if (!n) | ||
531 | return SEQ_START_TOKEN; | ||
532 | if (n < 0) | ||
533 | return NULL; | ||
534 | dp = ddebug_iter_first(iter); | ||
535 | while (dp != NULL && --n > 0) | ||
536 | dp = ddebug_iter_next(iter); | ||
537 | return dp; | ||
538 | } | ||
539 | |||
540 | /* | ||
541 | * Seq_ops next method. Called several times within a read() | ||
542 | * call from userspace, with ddebug_lock held. Walks to the | ||
543 | * next _ddebug object with a special case for the header line. | ||
544 | */ | ||
545 | static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos) | ||
546 | { | ||
547 | struct ddebug_iter *iter = m->private; | ||
548 | struct _ddebug *dp; | ||
549 | |||
550 | if (verbose) | ||
551 | printk(KERN_INFO "%s: called m=%p p=%p *pos=%lld\n", | ||
552 | __func__, m, p, (unsigned long long)*pos); | ||
553 | |||
554 | if (p == SEQ_START_TOKEN) | ||
555 | dp = ddebug_iter_first(iter); | ||
556 | else | ||
557 | dp = ddebug_iter_next(iter); | ||
558 | ++*pos; | ||
559 | return dp; | ||
560 | } | ||
561 | |||
562 | /* | ||
563 | * Seq_ops show method. Called several times within a read() | ||
564 | * call from userspace, with ddebug_lock held. Formats the | ||
565 | * current _ddebug as a single human-readable line, with a | ||
566 | * special case for the header line. | ||
567 | */ | ||
568 | static int ddebug_proc_show(struct seq_file *m, void *p) | ||
569 | { | ||
570 | struct ddebug_iter *iter = m->private; | ||
571 | struct _ddebug *dp = p; | ||
572 | char flagsbuf[8]; | ||
573 | |||
574 | if (verbose) | ||
575 | printk(KERN_INFO "%s: called m=%p p=%p\n", | ||
576 | __func__, m, p); | ||
577 | |||
578 | if (p == SEQ_START_TOKEN) { | ||
579 | seq_puts(m, | ||
580 | "# filename:lineno [module]function flags format\n"); | ||
581 | return 0; | ||
582 | } | ||
583 | |||
584 | seq_printf(m, "%s:%u [%s]%s %s \"", | ||
585 | dp->filename, dp->lineno, | ||
586 | iter->table->mod_name, dp->function, | ||
587 | ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf))); | ||
588 | seq_escape(m, dp->format, "\t\r\n\""); | ||
589 | seq_puts(m, "\"\n"); | ||
590 | |||
591 | return 0; | ||
592 | } | ||
593 | |||
594 | /* | ||
595 | * Seq_ops stop method. Called at the end of each read() | ||
596 | * call from userspace. Drops ddebug_lock. | ||
597 | */ | ||
598 | static void ddebug_proc_stop(struct seq_file *m, void *p) | ||
599 | { | ||
600 | if (verbose) | ||
601 | printk(KERN_INFO "%s: called m=%p p=%p\n", | ||
602 | __func__, m, p); | ||
603 | mutex_unlock(&ddebug_lock); | ||
604 | } | ||
605 | |||
606 | static const struct seq_operations ddebug_proc_seqops = { | ||
607 | .start = ddebug_proc_start, | ||
608 | .next = ddebug_proc_next, | ||
609 | .show = ddebug_proc_show, | ||
610 | .stop = ddebug_proc_stop | ||
611 | }; | ||
612 | |||
613 | /* | ||
614 | * File_ops->open method for <debugfs>/dynamic_debug/control. Does the seq_file | ||
615 | * setup dance, and also creates an iterator to walk the _ddebugs. | ||
616 | * Note that we create a seq_file always, even for O_WRONLY files | ||
617 | * where it's not needed, as doing so simplifies the ->release method. | ||
618 | */ | ||
619 | static int ddebug_proc_open(struct inode *inode, struct file *file) | ||
620 | { | ||
621 | struct ddebug_iter *iter; | ||
622 | int err; | ||
623 | |||
624 | if (verbose) | ||
625 | printk(KERN_INFO "%s: called\n", __func__); | ||
626 | |||
627 | iter = kzalloc(sizeof(*iter), GFP_KERNEL); | ||
628 | if (iter == NULL) | ||
629 | return -ENOMEM; | ||
630 | |||
631 | err = seq_open(file, &ddebug_proc_seqops); | ||
632 | if (err) { | ||
633 | kfree(iter); | ||
634 | return err; | ||
635 | } | ||
636 | ((struct seq_file *) file->private_data)->private = iter; | ||
637 | return 0; | ||
638 | } | ||
639 | |||
640 | static const struct file_operations ddebug_proc_fops = { | ||
641 | .owner = THIS_MODULE, | ||
642 | .open = ddebug_proc_open, | ||
643 | .read = seq_read, | ||
644 | .llseek = seq_lseek, | ||
645 | .release = seq_release_private, | ||
646 | .write = ddebug_proc_write | ||
647 | }; | ||
648 | |||
649 | /* | ||
650 | * Allocate a new ddebug_table for the given module | ||
651 | * and add it to the global list. | ||
652 | */ | ||
653 | int ddebug_add_module(struct _ddebug *tab, unsigned int n, | ||
654 | const char *name) | ||
655 | { | ||
656 | struct ddebug_table *dt; | ||
657 | char *new_name; | ||
658 | |||
659 | dt = kzalloc(sizeof(*dt), GFP_KERNEL); | ||
660 | if (dt == NULL) | ||
661 | return -ENOMEM; | ||
662 | new_name = kstrdup(name, GFP_KERNEL); | ||
663 | if (new_name == NULL) { | ||
664 | kfree(dt); | ||
665 | return -ENOMEM; | ||
666 | } | ||
667 | dt->mod_name = new_name; | ||
668 | dt->num_ddebugs = n; | ||
669 | dt->num_enabled = 0; | ||
670 | dt->ddebugs = tab; | ||
671 | |||
672 | mutex_lock(&ddebug_lock); | ||
673 | list_add_tail(&dt->link, &ddebug_tables); | ||
674 | mutex_unlock(&ddebug_lock); | ||
675 | |||
676 | if (verbose) | ||
677 | printk(KERN_INFO "%u debug prints in module %s\n", | ||
678 | n, dt->mod_name); | ||
679 | return 0; | ||
680 | } | ||
681 | EXPORT_SYMBOL_GPL(ddebug_add_module); | ||
682 | |||
683 | static void ddebug_table_free(struct ddebug_table *dt) | ||
684 | { | ||
685 | list_del_init(&dt->link); | ||
686 | kfree(dt->mod_name); | ||
687 | kfree(dt); | ||
688 | } | ||
689 | |||
690 | /* | ||
691 | * Called in response to a module being unloaded. Removes | ||
692 | * any ddebug_table's which point at the module. | ||
693 | */ | ||
694 | int ddebug_remove_module(char *mod_name) | ||
695 | { | ||
696 | struct ddebug_table *dt, *nextdt; | ||
697 | int ret = -ENOENT; | ||
698 | |||
699 | if (verbose) | ||
700 | printk(KERN_INFO "%s: removing module \"%s\"\n", | ||
701 | __func__, mod_name); | ||
702 | |||
703 | mutex_lock(&ddebug_lock); | ||
704 | list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) { | ||
705 | if (!strcmp(dt->mod_name, mod_name)) { | ||
706 | ddebug_table_free(dt); | ||
707 | ret = 0; | ||
708 | } | ||
709 | } | ||
710 | mutex_unlock(&ddebug_lock); | ||
711 | return ret; | ||
712 | } | ||
713 | EXPORT_SYMBOL_GPL(ddebug_remove_module); | ||
714 | |||
715 | static void ddebug_remove_all_tables(void) | ||
716 | { | ||
717 | mutex_lock(&ddebug_lock); | ||
718 | while (!list_empty(&ddebug_tables)) { | ||
719 | struct ddebug_table *dt = list_entry(ddebug_tables.next, | ||
720 | struct ddebug_table, | ||
721 | link); | ||
722 | ddebug_table_free(dt); | ||
723 | } | ||
724 | mutex_unlock(&ddebug_lock); | ||
725 | } | ||
726 | |||
727 | static int __init dynamic_debug_init(void) | ||
728 | { | ||
729 | struct dentry *dir, *file; | ||
730 | struct _ddebug *iter, *iter_start; | ||
731 | const char *modname = NULL; | ||
732 | int ret = 0; | ||
733 | int n = 0; | ||
734 | |||
735 | dir = debugfs_create_dir("dynamic_debug", NULL); | ||
736 | if (!dir) | ||
737 | return -ENOMEM; | ||
738 | file = debugfs_create_file("control", 0644, dir, NULL, | ||
739 | &ddebug_proc_fops); | ||
740 | if (!file) { | ||
741 | debugfs_remove(dir); | ||
742 | return -ENOMEM; | ||
743 | } | ||
744 | if (__start___verbose != __stop___verbose) { | ||
745 | iter = __start___verbose; | ||
746 | modname = iter->modname; | ||
747 | iter_start = iter; | ||
748 | for (; iter < __stop___verbose; iter++) { | ||
749 | if (strcmp(modname, iter->modname)) { | ||
750 | ret = ddebug_add_module(iter_start, n, modname); | ||
751 | if (ret) | ||
752 | goto out_free; | ||
753 | n = 0; | ||
754 | modname = iter->modname; | ||
755 | iter_start = iter; | ||
756 | } | ||
757 | n++; | ||
758 | } | ||
759 | ret = ddebug_add_module(iter_start, n, modname); | ||
760 | } | ||
761 | out_free: | ||
762 | if (ret) { | ||
763 | ddebug_remove_all_tables(); | ||
764 | debugfs_remove(dir); | ||
765 | debugfs_remove(file); | ||
766 | } | ||
767 | return 0; | ||
768 | } | ||
769 | module_init(dynamic_debug_init); | ||
diff --git a/lib/dynamic_printk.c b/lib/dynamic_printk.c deleted file mode 100644 index 165a19763dc9..000000000000 --- a/lib/dynamic_printk.c +++ /dev/null | |||
@@ -1,414 +0,0 @@ | |||
1 | /* | ||
2 | * lib/dynamic_printk.c | ||
3 | * | ||
4 | * make pr_debug()/dev_dbg() calls runtime configurable based upon their | ||
5 | * their source module. | ||
6 | * | ||
7 | * Copyright (C) 2008 Red Hat, Inc., Jason Baron <jbaron@redhat.com> | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/uaccess.h> | ||
13 | #include <linux/seq_file.h> | ||
14 | #include <linux/debugfs.h> | ||
15 | #include <linux/fs.h> | ||
16 | |||
17 | extern struct mod_debug __start___verbose[]; | ||
18 | extern struct mod_debug __stop___verbose[]; | ||
19 | |||
20 | struct debug_name { | ||
21 | struct hlist_node hlist; | ||
22 | struct hlist_node hlist2; | ||
23 | int hash1; | ||
24 | int hash2; | ||
25 | char *name; | ||
26 | int enable; | ||
27 | int type; | ||
28 | }; | ||
29 | |||
30 | static int nr_entries; | ||
31 | static int num_enabled; | ||
32 | int dynamic_enabled = DYNAMIC_ENABLED_NONE; | ||
33 | static struct hlist_head module_table[DEBUG_HASH_TABLE_SIZE] = | ||
34 | { [0 ... DEBUG_HASH_TABLE_SIZE-1] = HLIST_HEAD_INIT }; | ||
35 | static struct hlist_head module_table2[DEBUG_HASH_TABLE_SIZE] = | ||
36 | { [0 ... DEBUG_HASH_TABLE_SIZE-1] = HLIST_HEAD_INIT }; | ||
37 | static DECLARE_MUTEX(debug_list_mutex); | ||
38 | |||
39 | /* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which | ||
40 | * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They | ||
41 | * use independent hash functions, to reduce the chance of false positives. | ||
42 | */ | ||
43 | long long dynamic_printk_enabled; | ||
44 | EXPORT_SYMBOL_GPL(dynamic_printk_enabled); | ||
45 | long long dynamic_printk_enabled2; | ||
46 | EXPORT_SYMBOL_GPL(dynamic_printk_enabled2); | ||
47 | |||
48 | /* returns the debug module pointer. */ | ||
49 | static struct debug_name *find_debug_module(char *module_name) | ||
50 | { | ||
51 | int i; | ||
52 | struct hlist_head *head; | ||
53 | struct hlist_node *node; | ||
54 | struct debug_name *element; | ||
55 | |||
56 | element = NULL; | ||
57 | for (i = 0; i < DEBUG_HASH_TABLE_SIZE; i++) { | ||
58 | head = &module_table[i]; | ||
59 | hlist_for_each_entry_rcu(element, node, head, hlist) | ||
60 | if (!strcmp(element->name, module_name)) | ||
61 | return element; | ||
62 | } | ||
63 | return NULL; | ||
64 | } | ||
65 | |||
66 | /* returns the debug module pointer. */ | ||
67 | static struct debug_name *find_debug_module_hash(char *module_name, int hash) | ||
68 | { | ||
69 | struct hlist_head *head; | ||
70 | struct hlist_node *node; | ||
71 | struct debug_name *element; | ||
72 | |||
73 | element = NULL; | ||
74 | head = &module_table[hash]; | ||
75 | hlist_for_each_entry_rcu(element, node, head, hlist) | ||
76 | if (!strcmp(element->name, module_name)) | ||
77 | return element; | ||
78 | return NULL; | ||
79 | } | ||
80 | |||
81 | /* caller must hold mutex*/ | ||
82 | static int __add_debug_module(char *mod_name, int hash, int hash2) | ||
83 | { | ||
84 | struct debug_name *new; | ||
85 | char *module_name; | ||
86 | int ret = 0; | ||
87 | |||
88 | if (find_debug_module(mod_name)) { | ||
89 | ret = -EINVAL; | ||
90 | goto out; | ||
91 | } | ||
92 | module_name = kmalloc(strlen(mod_name) + 1, GFP_KERNEL); | ||
93 | if (!module_name) { | ||
94 | ret = -ENOMEM; | ||
95 | goto out; | ||
96 | } | ||
97 | module_name = strcpy(module_name, mod_name); | ||
98 | module_name[strlen(mod_name)] = '\0'; | ||
99 | new = kzalloc(sizeof(struct debug_name), GFP_KERNEL); | ||
100 | if (!new) { | ||
101 | kfree(module_name); | ||
102 | ret = -ENOMEM; | ||
103 | goto out; | ||
104 | } | ||
105 | INIT_HLIST_NODE(&new->hlist); | ||
106 | INIT_HLIST_NODE(&new->hlist2); | ||
107 | new->name = module_name; | ||
108 | new->hash1 = hash; | ||
109 | new->hash2 = hash2; | ||
110 | hlist_add_head_rcu(&new->hlist, &module_table[hash]); | ||
111 | hlist_add_head_rcu(&new->hlist2, &module_table2[hash2]); | ||
112 | nr_entries++; | ||
113 | out: | ||
114 | return ret; | ||
115 | } | ||
116 | |||
117 | int unregister_dynamic_debug_module(char *mod_name) | ||
118 | { | ||
119 | struct debug_name *element; | ||
120 | int ret = 0; | ||
121 | |||
122 | down(&debug_list_mutex); | ||
123 | element = find_debug_module(mod_name); | ||
124 | if (!element) { | ||
125 | ret = -EINVAL; | ||
126 | goto out; | ||
127 | } | ||
128 | hlist_del_rcu(&element->hlist); | ||
129 | hlist_del_rcu(&element->hlist2); | ||
130 | synchronize_rcu(); | ||
131 | kfree(element->name); | ||
132 | if (element->enable) | ||
133 | num_enabled--; | ||
134 | kfree(element); | ||
135 | nr_entries--; | ||
136 | out: | ||
137 | up(&debug_list_mutex); | ||
138 | return ret; | ||
139 | } | ||
140 | EXPORT_SYMBOL_GPL(unregister_dynamic_debug_module); | ||
141 | |||
142 | int register_dynamic_debug_module(char *mod_name, int type, char *share_name, | ||
143 | char *flags, int hash, int hash2) | ||
144 | { | ||
145 | struct debug_name *elem; | ||
146 | int ret = 0; | ||
147 | |||
148 | down(&debug_list_mutex); | ||
149 | elem = find_debug_module(mod_name); | ||
150 | if (!elem) { | ||
151 | if (__add_debug_module(mod_name, hash, hash2)) | ||
152 | goto out; | ||
153 | elem = find_debug_module(mod_name); | ||
154 | if (dynamic_enabled == DYNAMIC_ENABLED_ALL && | ||
155 | !strcmp(mod_name, share_name)) { | ||
156 | elem->enable = true; | ||
157 | num_enabled++; | ||
158 | } | ||
159 | } | ||
160 | elem->type |= type; | ||
161 | out: | ||
162 | up(&debug_list_mutex); | ||
163 | return ret; | ||
164 | } | ||
165 | EXPORT_SYMBOL_GPL(register_dynamic_debug_module); | ||
166 | |||
167 | int __dynamic_dbg_enabled_helper(char *mod_name, int type, int value, int hash) | ||
168 | { | ||
169 | struct debug_name *elem; | ||
170 | int ret = 0; | ||
171 | |||
172 | if (dynamic_enabled == DYNAMIC_ENABLED_ALL) | ||
173 | return 1; | ||
174 | rcu_read_lock(); | ||
175 | elem = find_debug_module_hash(mod_name, hash); | ||
176 | if (elem && elem->enable) | ||
177 | ret = 1; | ||
178 | rcu_read_unlock(); | ||
179 | return ret; | ||
180 | } | ||
181 | EXPORT_SYMBOL_GPL(__dynamic_dbg_enabled_helper); | ||
182 | |||
183 | static void set_all(bool enable) | ||
184 | { | ||
185 | struct debug_name *e; | ||
186 | struct hlist_node *node; | ||
187 | int i; | ||
188 | long long enable_mask; | ||
189 | |||
190 | for (i = 0; i < DEBUG_HASH_TABLE_SIZE; i++) { | ||
191 | if (module_table[i].first != NULL) { | ||
192 | hlist_for_each_entry(e, node, &module_table[i], hlist) { | ||
193 | e->enable = enable; | ||
194 | } | ||
195 | } | ||
196 | } | ||
197 | if (enable) | ||
198 | enable_mask = ULLONG_MAX; | ||
199 | else | ||
200 | enable_mask = 0; | ||
201 | dynamic_printk_enabled = enable_mask; | ||
202 | dynamic_printk_enabled2 = enable_mask; | ||
203 | } | ||
204 | |||
205 | static int disabled_hash(int i, bool first_table) | ||
206 | { | ||
207 | struct debug_name *e; | ||
208 | struct hlist_node *node; | ||
209 | |||
210 | if (first_table) { | ||
211 | hlist_for_each_entry(e, node, &module_table[i], hlist) { | ||
212 | if (e->enable) | ||
213 | return 0; | ||
214 | } | ||
215 | } else { | ||
216 | hlist_for_each_entry(e, node, &module_table2[i], hlist2) { | ||
217 | if (e->enable) | ||
218 | return 0; | ||
219 | } | ||
220 | } | ||
221 | return 1; | ||
222 | } | ||
223 | |||
224 | static ssize_t pr_debug_write(struct file *file, const char __user *buf, | ||
225 | size_t length, loff_t *ppos) | ||
226 | { | ||
227 | char *buffer, *s, *value_str, *setting_str; | ||
228 | int err, value; | ||
229 | struct debug_name *elem = NULL; | ||
230 | int all = 0; | ||
231 | |||
232 | if (length > PAGE_SIZE || length < 0) | ||
233 | return -EINVAL; | ||
234 | |||
235 | buffer = (char *)__get_free_page(GFP_KERNEL); | ||
236 | if (!buffer) | ||
237 | return -ENOMEM; | ||
238 | |||
239 | err = -EFAULT; | ||
240 | if (copy_from_user(buffer, buf, length)) | ||
241 | goto out; | ||
242 | |||
243 | err = -EINVAL; | ||
244 | if (length < PAGE_SIZE) | ||
245 | buffer[length] = '\0'; | ||
246 | else if (buffer[PAGE_SIZE-1]) | ||
247 | goto out; | ||
248 | |||
249 | err = -EINVAL; | ||
250 | down(&debug_list_mutex); | ||
251 | |||
252 | if (strncmp("set", buffer, 3)) | ||
253 | goto out_up; | ||
254 | s = buffer + 3; | ||
255 | setting_str = strsep(&s, "="); | ||
256 | if (s == NULL) | ||
257 | goto out_up; | ||
258 | setting_str = strstrip(setting_str); | ||
259 | value_str = strsep(&s, " "); | ||
260 | if (s == NULL) | ||
261 | goto out_up; | ||
262 | s = strstrip(s); | ||
263 | if (!strncmp(s, "all", 3)) | ||
264 | all = 1; | ||
265 | else | ||
266 | elem = find_debug_module(s); | ||
267 | if (!strncmp(setting_str, "enable", 6)) { | ||
268 | value = !!simple_strtol(value_str, NULL, 10); | ||
269 | if (all) { | ||
270 | if (value) { | ||
271 | set_all(true); | ||
272 | num_enabled = nr_entries; | ||
273 | dynamic_enabled = DYNAMIC_ENABLED_ALL; | ||
274 | } else { | ||
275 | set_all(false); | ||
276 | num_enabled = 0; | ||
277 | dynamic_enabled = DYNAMIC_ENABLED_NONE; | ||
278 | } | ||
279 | err = 0; | ||
280 | } else if (elem) { | ||
281 | if (value && (elem->enable == 0)) { | ||
282 | dynamic_printk_enabled |= (1LL << elem->hash1); | ||
283 | dynamic_printk_enabled2 |= (1LL << elem->hash2); | ||
284 | elem->enable = 1; | ||
285 | num_enabled++; | ||
286 | dynamic_enabled = DYNAMIC_ENABLED_SOME; | ||
287 | err = 0; | ||
288 | printk(KERN_DEBUG | ||
289 | "debugging enabled for module %s\n", | ||
290 | elem->name); | ||
291 | } else if (!value && (elem->enable == 1)) { | ||
292 | elem->enable = 0; | ||
293 | num_enabled--; | ||
294 | if (disabled_hash(elem->hash1, true)) | ||
295 | dynamic_printk_enabled &= | ||
296 | ~(1LL << elem->hash1); | ||
297 | if (disabled_hash(elem->hash2, false)) | ||
298 | dynamic_printk_enabled2 &= | ||
299 | ~(1LL << elem->hash2); | ||
300 | if (num_enabled) | ||
301 | dynamic_enabled = DYNAMIC_ENABLED_SOME; | ||
302 | else | ||
303 | dynamic_enabled = DYNAMIC_ENABLED_NONE; | ||
304 | err = 0; | ||
305 | printk(KERN_DEBUG | ||
306 | "debugging disabled for module %s\n", | ||
307 | elem->name); | ||
308 | } | ||
309 | } | ||
310 | } | ||
311 | if (!err) | ||
312 | err = length; | ||
313 | out_up: | ||
314 | up(&debug_list_mutex); | ||
315 | out: | ||
316 | free_page((unsigned long)buffer); | ||
317 | return err; | ||
318 | } | ||
319 | |||
320 | static void *pr_debug_seq_start(struct seq_file *f, loff_t *pos) | ||
321 | { | ||
322 | return (*pos < DEBUG_HASH_TABLE_SIZE) ? pos : NULL; | ||
323 | } | ||
324 | |||
325 | static void *pr_debug_seq_next(struct seq_file *s, void *v, loff_t *pos) | ||
326 | { | ||
327 | (*pos)++; | ||
328 | if (*pos >= DEBUG_HASH_TABLE_SIZE) | ||
329 | return NULL; | ||
330 | return pos; | ||
331 | } | ||
332 | |||
333 | static void pr_debug_seq_stop(struct seq_file *s, void *v) | ||
334 | { | ||
335 | /* Nothing to do */ | ||
336 | } | ||
337 | |||
338 | static int pr_debug_seq_show(struct seq_file *s, void *v) | ||
339 | { | ||
340 | struct hlist_head *head; | ||
341 | struct hlist_node *node; | ||
342 | struct debug_name *elem; | ||
343 | unsigned int i = *(loff_t *) v; | ||
344 | |||
345 | rcu_read_lock(); | ||
346 | head = &module_table[i]; | ||
347 | hlist_for_each_entry_rcu(elem, node, head, hlist) { | ||
348 | seq_printf(s, "%s enabled=%d", elem->name, elem->enable); | ||
349 | seq_printf(s, "\n"); | ||
350 | } | ||
351 | rcu_read_unlock(); | ||
352 | return 0; | ||
353 | } | ||
354 | |||
355 | static struct seq_operations pr_debug_seq_ops = { | ||
356 | .start = pr_debug_seq_start, | ||
357 | .next = pr_debug_seq_next, | ||
358 | .stop = pr_debug_seq_stop, | ||
359 | .show = pr_debug_seq_show | ||
360 | }; | ||
361 | |||
362 | static int pr_debug_open(struct inode *inode, struct file *filp) | ||
363 | { | ||
364 | return seq_open(filp, &pr_debug_seq_ops); | ||
365 | } | ||
366 | |||
367 | static const struct file_operations pr_debug_operations = { | ||
368 | .open = pr_debug_open, | ||
369 | .read = seq_read, | ||
370 | .write = pr_debug_write, | ||
371 | .llseek = seq_lseek, | ||
372 | .release = seq_release, | ||
373 | }; | ||
374 | |||
375 | static int __init dynamic_printk_init(void) | ||
376 | { | ||
377 | struct dentry *dir, *file; | ||
378 | struct mod_debug *iter; | ||
379 | unsigned long value; | ||
380 | |||
381 | dir = debugfs_create_dir("dynamic_printk", NULL); | ||
382 | if (!dir) | ||
383 | return -ENOMEM; | ||
384 | file = debugfs_create_file("modules", 0644, dir, NULL, | ||
385 | &pr_debug_operations); | ||
386 | if (!file) { | ||
387 | debugfs_remove(dir); | ||
388 | return -ENOMEM; | ||
389 | } | ||
390 | for (value = (unsigned long)__start___verbose; | ||
391 | value < (unsigned long)__stop___verbose; | ||
392 | value += sizeof(struct mod_debug)) { | ||
393 | iter = (struct mod_debug *)value; | ||
394 | register_dynamic_debug_module(iter->modname, | ||
395 | iter->type, | ||
396 | iter->logical_modname, | ||
397 | iter->flag_names, iter->hash, iter->hash2); | ||
398 | } | ||
399 | if (dynamic_enabled == DYNAMIC_ENABLED_ALL) | ||
400 | set_all(true); | ||
401 | return 0; | ||
402 | } | ||
403 | module_init(dynamic_printk_init); | ||
404 | /* may want to move this earlier so we can get traces as early as possible */ | ||
405 | |||
406 | static int __init dynamic_printk_setup(char *str) | ||
407 | { | ||
408 | if (str) | ||
409 | return -ENOENT; | ||
410 | dynamic_enabled = DYNAMIC_ENABLED_ALL; | ||
411 | return 0; | ||
412 | } | ||
413 | /* Use early_param(), so we can get debug output as early as possible */ | ||
414 | early_param("dynamic_printk", dynamic_printk_setup); | ||
@@ -579,6 +579,52 @@ int idr_for_each(struct idr *idp, | |||
579 | EXPORT_SYMBOL(idr_for_each); | 579 | EXPORT_SYMBOL(idr_for_each); |
580 | 580 | ||
581 | /** | 581 | /** |
582 | * idr_get_next - lookup next object of id to given id. | ||
583 | * @idp: idr handle | ||
584 | * @id: pointer to lookup key | ||
585 | * | ||
586 | * Returns pointer to registered object with id, which is next number to | ||
587 | * given id. | ||
588 | */ | ||
589 | |||
590 | void *idr_get_next(struct idr *idp, int *nextidp) | ||
591 | { | ||
592 | struct idr_layer *p, *pa[MAX_LEVEL]; | ||
593 | struct idr_layer **paa = &pa[0]; | ||
594 | int id = *nextidp; | ||
595 | int n, max; | ||
596 | |||
597 | /* find first ent */ | ||
598 | n = idp->layers * IDR_BITS; | ||
599 | max = 1 << n; | ||
600 | p = rcu_dereference(idp->top); | ||
601 | if (!p) | ||
602 | return NULL; | ||
603 | |||
604 | while (id < max) { | ||
605 | while (n > 0 && p) { | ||
606 | n -= IDR_BITS; | ||
607 | *paa++ = p; | ||
608 | p = rcu_dereference(p->ary[(id >> n) & IDR_MASK]); | ||
609 | } | ||
610 | |||
611 | if (p) { | ||
612 | *nextidp = id; | ||
613 | return p; | ||
614 | } | ||
615 | |||
616 | id += 1 << n; | ||
617 | while (n < fls(id)) { | ||
618 | n += IDR_BITS; | ||
619 | p = *--paa; | ||
620 | } | ||
621 | } | ||
622 | return NULL; | ||
623 | } | ||
624 | |||
625 | |||
626 | |||
627 | /** | ||
582 | * idr_replace - replace pointer for given id | 628 | * idr_replace - replace pointer for given id |
583 | * @idp: idr handle | 629 | * @idp: idr handle |
584 | * @ptr: pointer you want associated with the id | 630 | * @ptr: pointer you want associated with the id |
diff --git a/lib/kernel_lock.c b/lib/kernel_lock.c index 01a3c22c1b5a..39f1029e3525 100644 --- a/lib/kernel_lock.c +++ b/lib/kernel_lock.c | |||
@@ -39,7 +39,7 @@ static __cacheline_aligned_in_smp DEFINE_SPINLOCK(kernel_flag); | |||
39 | int __lockfunc __reacquire_kernel_lock(void) | 39 | int __lockfunc __reacquire_kernel_lock(void) |
40 | { | 40 | { |
41 | while (!_raw_spin_trylock(&kernel_flag)) { | 41 | while (!_raw_spin_trylock(&kernel_flag)) { |
42 | if (test_thread_flag(TIF_NEED_RESCHED)) | 42 | if (need_resched()) |
43 | return -EAGAIN; | 43 | return -EAGAIN; |
44 | cpu_relax(); | 44 | cpu_relax(); |
45 | } | 45 | } |
diff --git a/lib/kobject.c b/lib/kobject.c index 0487d1f64806..a6dec32f2ddd 100644 --- a/lib/kobject.c +++ b/lib/kobject.c | |||
@@ -212,7 +212,7 @@ static int kobject_add_internal(struct kobject *kobj) | |||
212 | * @fmt: format string used to build the name | 212 | * @fmt: format string used to build the name |
213 | * @vargs: vargs to format the string. | 213 | * @vargs: vargs to format the string. |
214 | */ | 214 | */ |
215 | static int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, | 215 | int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, |
216 | va_list vargs) | 216 | va_list vargs) |
217 | { | 217 | { |
218 | const char *old_name = kobj->name; | 218 | const char *old_name = kobj->name; |
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index 318328ddbd1c..97a777ad4f59 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c | |||
@@ -118,6 +118,13 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, | |||
118 | kset = top_kobj->kset; | 118 | kset = top_kobj->kset; |
119 | uevent_ops = kset->uevent_ops; | 119 | uevent_ops = kset->uevent_ops; |
120 | 120 | ||
121 | /* skip the event, if uevent_suppress is set*/ | ||
122 | if (kobj->uevent_suppress) { | ||
123 | pr_debug("kobject: '%s' (%p): %s: uevent_suppress " | ||
124 | "caused the event to drop!\n", | ||
125 | kobject_name(kobj), kobj, __func__); | ||
126 | return 0; | ||
127 | } | ||
121 | /* skip the event, if the filter returns zero. */ | 128 | /* skip the event, if the filter returns zero. */ |
122 | if (uevent_ops && uevent_ops->filter) | 129 | if (uevent_ops && uevent_ops->filter) |
123 | if (!uevent_ops->filter(kset, kobj)) { | 130 | if (!uevent_ops->filter(kset, kobj)) { |
@@ -227,6 +234,9 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, | |||
227 | NETLINK_CB(skb).dst_group = 1; | 234 | NETLINK_CB(skb).dst_group = 1; |
228 | retval = netlink_broadcast(uevent_sock, skb, 0, 1, | 235 | retval = netlink_broadcast(uevent_sock, skb, 0, 1, |
229 | GFP_KERNEL); | 236 | GFP_KERNEL); |
237 | /* ENOBUFS should be handled in userspace */ | ||
238 | if (retval == -ENOBUFS) | ||
239 | retval = 0; | ||
230 | } else | 240 | } else |
231 | retval = -ENOMEM; | 241 | retval = -ENOMEM; |
232 | } | 242 | } |
@@ -248,7 +258,7 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, | |||
248 | goto exit; | 258 | goto exit; |
249 | 259 | ||
250 | retval = call_usermodehelper(argv[0], argv, | 260 | retval = call_usermodehelper(argv[0], argv, |
251 | env->envp, UMH_WAIT_EXEC); | 261 | env->envp, UMH_NO_WAIT); |
252 | } | 262 | } |
253 | 263 | ||
254 | exit: | 264 | exit: |
@@ -29,33 +29,33 @@ static int __init early_lmb(char *p) | |||
29 | } | 29 | } |
30 | early_param("lmb", early_lmb); | 30 | early_param("lmb", early_lmb); |
31 | 31 | ||
32 | void lmb_dump_all(void) | 32 | static void lmb_dump(struct lmb_region *region, char *name) |
33 | { | 33 | { |
34 | unsigned long i; | 34 | unsigned long long base, size; |
35 | int i; | ||
36 | |||
37 | pr_info(" %s.cnt = 0x%lx\n", name, region->cnt); | ||
38 | |||
39 | for (i = 0; i < region->cnt; i++) { | ||
40 | base = region->region[i].base; | ||
41 | size = region->region[i].size; | ||
42 | |||
43 | pr_info(" %s[0x%x]\t0x%016llx - 0x%016llx, 0x%llx bytes\n", | ||
44 | name, i, base, base + size - 1, size); | ||
45 | } | ||
46 | } | ||
35 | 47 | ||
48 | void lmb_dump_all(void) | ||
49 | { | ||
36 | if (!lmb_debug) | 50 | if (!lmb_debug) |
37 | return; | 51 | return; |
38 | 52 | ||
39 | pr_info("lmb_dump_all:\n"); | 53 | pr_info("LMB configuration:\n"); |
40 | pr_info(" memory.cnt = 0x%lx\n", lmb.memory.cnt); | 54 | pr_info(" rmo_size = 0x%llx\n", (unsigned long long)lmb.rmo_size); |
41 | pr_info(" memory.size = 0x%llx\n", | 55 | pr_info(" memory.size = 0x%llx\n", (unsigned long long)lmb.memory.size); |
42 | (unsigned long long)lmb.memory.size); | ||
43 | for (i=0; i < lmb.memory.cnt ;i++) { | ||
44 | pr_info(" memory.region[0x%lx].base = 0x%llx\n", | ||
45 | i, (unsigned long long)lmb.memory.region[i].base); | ||
46 | pr_info(" .size = 0x%llx\n", | ||
47 | (unsigned long long)lmb.memory.region[i].size); | ||
48 | } | ||
49 | 56 | ||
50 | pr_info(" reserved.cnt = 0x%lx\n", lmb.reserved.cnt); | 57 | lmb_dump(&lmb.memory, "memory"); |
51 | pr_info(" reserved.size = 0x%llx\n", | 58 | lmb_dump(&lmb.reserved, "reserved"); |
52 | (unsigned long long)lmb.memory.size); | ||
53 | for (i=0; i < lmb.reserved.cnt ;i++) { | ||
54 | pr_info(" reserved.region[0x%lx].base = 0x%llx\n", | ||
55 | i, (unsigned long long)lmb.reserved.region[i].base); | ||
56 | pr_info(" .size = 0x%llx\n", | ||
57 | (unsigned long long)lmb.reserved.region[i].size); | ||
58 | } | ||
59 | } | 59 | } |
60 | 60 | ||
61 | static unsigned long lmb_addrs_overlap(u64 base1, u64 size1, u64 base2, | 61 | static unsigned long lmb_addrs_overlap(u64 base1, u64 size1, u64 base2, |
diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c index 280332c1827c..619313ed6c46 100644 --- a/lib/locking-selftest.c +++ b/lib/locking-selftest.c | |||
@@ -157,11 +157,11 @@ static void init_shared_classes(void) | |||
157 | #define SOFTIRQ_ENTER() \ | 157 | #define SOFTIRQ_ENTER() \ |
158 | local_bh_disable(); \ | 158 | local_bh_disable(); \ |
159 | local_irq_disable(); \ | 159 | local_irq_disable(); \ |
160 | trace_softirq_enter(); \ | 160 | lockdep_softirq_enter(); \ |
161 | WARN_ON(!in_softirq()); | 161 | WARN_ON(!in_softirq()); |
162 | 162 | ||
163 | #define SOFTIRQ_EXIT() \ | 163 | #define SOFTIRQ_EXIT() \ |
164 | trace_softirq_exit(); \ | 164 | lockdep_softirq_exit(); \ |
165 | local_irq_enable(); \ | 165 | local_irq_enable(); \ |
166 | local_bh_enable(); | 166 | local_bh_enable(); |
167 | 167 | ||
diff --git a/lib/nlattr.c b/lib/nlattr.c new file mode 100644 index 000000000000..c4706eb98d3d --- /dev/null +++ b/lib/nlattr.c | |||
@@ -0,0 +1,502 @@ | |||
1 | /* | ||
2 | * NETLINK Netlink attributes | ||
3 | * | ||
4 | * Authors: Thomas Graf <tgraf@suug.ch> | ||
5 | * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> | ||
6 | */ | ||
7 | |||
8 | #include <linux/module.h> | ||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/errno.h> | ||
11 | #include <linux/jiffies.h> | ||
12 | #include <linux/netdevice.h> | ||
13 | #include <linux/skbuff.h> | ||
14 | #include <linux/string.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <net/netlink.h> | ||
17 | |||
18 | static u16 nla_attr_minlen[NLA_TYPE_MAX+1] __read_mostly = { | ||
19 | [NLA_U8] = sizeof(u8), | ||
20 | [NLA_U16] = sizeof(u16), | ||
21 | [NLA_U32] = sizeof(u32), | ||
22 | [NLA_U64] = sizeof(u64), | ||
23 | [NLA_NESTED] = NLA_HDRLEN, | ||
24 | }; | ||
25 | |||
26 | static int validate_nla(struct nlattr *nla, int maxtype, | ||
27 | const struct nla_policy *policy) | ||
28 | { | ||
29 | const struct nla_policy *pt; | ||
30 | int minlen = 0, attrlen = nla_len(nla), type = nla_type(nla); | ||
31 | |||
32 | if (type <= 0 || type > maxtype) | ||
33 | return 0; | ||
34 | |||
35 | pt = &policy[type]; | ||
36 | |||
37 | BUG_ON(pt->type > NLA_TYPE_MAX); | ||
38 | |||
39 | switch (pt->type) { | ||
40 | case NLA_FLAG: | ||
41 | if (attrlen > 0) | ||
42 | return -ERANGE; | ||
43 | break; | ||
44 | |||
45 | case NLA_NUL_STRING: | ||
46 | if (pt->len) | ||
47 | minlen = min_t(int, attrlen, pt->len + 1); | ||
48 | else | ||
49 | minlen = attrlen; | ||
50 | |||
51 | if (!minlen || memchr(nla_data(nla), '\0', minlen) == NULL) | ||
52 | return -EINVAL; | ||
53 | /* fall through */ | ||
54 | |||
55 | case NLA_STRING: | ||
56 | if (attrlen < 1) | ||
57 | return -ERANGE; | ||
58 | |||
59 | if (pt->len) { | ||
60 | char *buf = nla_data(nla); | ||
61 | |||
62 | if (buf[attrlen - 1] == '\0') | ||
63 | attrlen--; | ||
64 | |||
65 | if (attrlen > pt->len) | ||
66 | return -ERANGE; | ||
67 | } | ||
68 | break; | ||
69 | |||
70 | case NLA_BINARY: | ||
71 | if (pt->len && attrlen > pt->len) | ||
72 | return -ERANGE; | ||
73 | break; | ||
74 | |||
75 | case NLA_NESTED_COMPAT: | ||
76 | if (attrlen < pt->len) | ||
77 | return -ERANGE; | ||
78 | if (attrlen < NLA_ALIGN(pt->len)) | ||
79 | break; | ||
80 | if (attrlen < NLA_ALIGN(pt->len) + NLA_HDRLEN) | ||
81 | return -ERANGE; | ||
82 | nla = nla_data(nla) + NLA_ALIGN(pt->len); | ||
83 | if (attrlen < NLA_ALIGN(pt->len) + NLA_HDRLEN + nla_len(nla)) | ||
84 | return -ERANGE; | ||
85 | break; | ||
86 | case NLA_NESTED: | ||
87 | /* a nested attributes is allowed to be empty; if its not, | ||
88 | * it must have a size of at least NLA_HDRLEN. | ||
89 | */ | ||
90 | if (attrlen == 0) | ||
91 | break; | ||
92 | default: | ||
93 | if (pt->len) | ||
94 | minlen = pt->len; | ||
95 | else if (pt->type != NLA_UNSPEC) | ||
96 | minlen = nla_attr_minlen[pt->type]; | ||
97 | |||
98 | if (attrlen < minlen) | ||
99 | return -ERANGE; | ||
100 | } | ||
101 | |||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | /** | ||
106 | * nla_validate - Validate a stream of attributes | ||
107 | * @head: head of attribute stream | ||
108 | * @len: length of attribute stream | ||
109 | * @maxtype: maximum attribute type to be expected | ||
110 | * @policy: validation policy | ||
111 | * | ||
112 | * Validates all attributes in the specified attribute stream against the | ||
113 | * specified policy. Attributes with a type exceeding maxtype will be | ||
114 | * ignored. See documenation of struct nla_policy for more details. | ||
115 | * | ||
116 | * Returns 0 on success or a negative error code. | ||
117 | */ | ||
118 | int nla_validate(struct nlattr *head, int len, int maxtype, | ||
119 | const struct nla_policy *policy) | ||
120 | { | ||
121 | struct nlattr *nla; | ||
122 | int rem, err; | ||
123 | |||
124 | nla_for_each_attr(nla, head, len, rem) { | ||
125 | err = validate_nla(nla, maxtype, policy); | ||
126 | if (err < 0) | ||
127 | goto errout; | ||
128 | } | ||
129 | |||
130 | err = 0; | ||
131 | errout: | ||
132 | return err; | ||
133 | } | ||
134 | |||
135 | /** | ||
136 | * nla_policy_len - Determin the max. length of a policy | ||
137 | * @policy: policy to use | ||
138 | * @n: number of policies | ||
139 | * | ||
140 | * Determines the max. length of the policy. It is currently used | ||
141 | * to allocated Netlink buffers roughly the size of the actual | ||
142 | * message. | ||
143 | * | ||
144 | * Returns 0 on success or a negative error code. | ||
145 | */ | ||
146 | int | ||
147 | nla_policy_len(const struct nla_policy *p, int n) | ||
148 | { | ||
149 | int i, len = 0; | ||
150 | |||
151 | for (i = 0; i < n; i++) { | ||
152 | if (p->len) | ||
153 | len += nla_total_size(p->len); | ||
154 | else if (nla_attr_minlen[p->type]) | ||
155 | len += nla_total_size(nla_attr_minlen[p->type]); | ||
156 | } | ||
157 | |||
158 | return len; | ||
159 | } | ||
160 | |||
161 | /** | ||
162 | * nla_parse - Parse a stream of attributes into a tb buffer | ||
163 | * @tb: destination array with maxtype+1 elements | ||
164 | * @maxtype: maximum attribute type to be expected | ||
165 | * @head: head of attribute stream | ||
166 | * @len: length of attribute stream | ||
167 | * @policy: validation policy | ||
168 | * | ||
169 | * Parses a stream of attributes and stores a pointer to each attribute in | ||
170 | * the tb array accessable via the attribute type. Attributes with a type | ||
171 | * exceeding maxtype will be silently ignored for backwards compatibility | ||
172 | * reasons. policy may be set to NULL if no validation is required. | ||
173 | * | ||
174 | * Returns 0 on success or a negative error code. | ||
175 | */ | ||
176 | int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, | ||
177 | const struct nla_policy *policy) | ||
178 | { | ||
179 | struct nlattr *nla; | ||
180 | int rem, err; | ||
181 | |||
182 | memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1)); | ||
183 | |||
184 | nla_for_each_attr(nla, head, len, rem) { | ||
185 | u16 type = nla_type(nla); | ||
186 | |||
187 | if (type > 0 && type <= maxtype) { | ||
188 | if (policy) { | ||
189 | err = validate_nla(nla, maxtype, policy); | ||
190 | if (err < 0) | ||
191 | goto errout; | ||
192 | } | ||
193 | |||
194 | tb[type] = nla; | ||
195 | } | ||
196 | } | ||
197 | |||
198 | if (unlikely(rem > 0)) | ||
199 | printk(KERN_WARNING "netlink: %d bytes leftover after parsing " | ||
200 | "attributes.\n", rem); | ||
201 | |||
202 | err = 0; | ||
203 | errout: | ||
204 | return err; | ||
205 | } | ||
206 | |||
207 | /** | ||
208 | * nla_find - Find a specific attribute in a stream of attributes | ||
209 | * @head: head of attribute stream | ||
210 | * @len: length of attribute stream | ||
211 | * @attrtype: type of attribute to look for | ||
212 | * | ||
213 | * Returns the first attribute in the stream matching the specified type. | ||
214 | */ | ||
215 | struct nlattr *nla_find(struct nlattr *head, int len, int attrtype) | ||
216 | { | ||
217 | struct nlattr *nla; | ||
218 | int rem; | ||
219 | |||
220 | nla_for_each_attr(nla, head, len, rem) | ||
221 | if (nla_type(nla) == attrtype) | ||
222 | return nla; | ||
223 | |||
224 | return NULL; | ||
225 | } | ||
226 | |||
227 | /** | ||
228 | * nla_strlcpy - Copy string attribute payload into a sized buffer | ||
229 | * @dst: where to copy the string to | ||
230 | * @nla: attribute to copy the string from | ||
231 | * @dstsize: size of destination buffer | ||
232 | * | ||
233 | * Copies at most dstsize - 1 bytes into the destination buffer. | ||
234 | * The result is always a valid NUL-terminated string. Unlike | ||
235 | * strlcpy the destination buffer is always padded out. | ||
236 | * | ||
237 | * Returns the length of the source buffer. | ||
238 | */ | ||
239 | size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize) | ||
240 | { | ||
241 | size_t srclen = nla_len(nla); | ||
242 | char *src = nla_data(nla); | ||
243 | |||
244 | if (srclen > 0 && src[srclen - 1] == '\0') | ||
245 | srclen--; | ||
246 | |||
247 | if (dstsize > 0) { | ||
248 | size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen; | ||
249 | |||
250 | memset(dst, 0, dstsize); | ||
251 | memcpy(dst, src, len); | ||
252 | } | ||
253 | |||
254 | return srclen; | ||
255 | } | ||
256 | |||
257 | /** | ||
258 | * nla_memcpy - Copy a netlink attribute into another memory area | ||
259 | * @dest: where to copy to memcpy | ||
260 | * @src: netlink attribute to copy from | ||
261 | * @count: size of the destination area | ||
262 | * | ||
263 | * Note: The number of bytes copied is limited by the length of | ||
264 | * attribute's payload. memcpy | ||
265 | * | ||
266 | * Returns the number of bytes copied. | ||
267 | */ | ||
268 | int nla_memcpy(void *dest, const struct nlattr *src, int count) | ||
269 | { | ||
270 | int minlen = min_t(int, count, nla_len(src)); | ||
271 | |||
272 | memcpy(dest, nla_data(src), minlen); | ||
273 | |||
274 | return minlen; | ||
275 | } | ||
276 | |||
277 | /** | ||
278 | * nla_memcmp - Compare an attribute with sized memory area | ||
279 | * @nla: netlink attribute | ||
280 | * @data: memory area | ||
281 | * @size: size of memory area | ||
282 | */ | ||
283 | int nla_memcmp(const struct nlattr *nla, const void *data, | ||
284 | size_t size) | ||
285 | { | ||
286 | int d = nla_len(nla) - size; | ||
287 | |||
288 | if (d == 0) | ||
289 | d = memcmp(nla_data(nla), data, size); | ||
290 | |||
291 | return d; | ||
292 | } | ||
293 | |||
294 | /** | ||
295 | * nla_strcmp - Compare a string attribute against a string | ||
296 | * @nla: netlink string attribute | ||
297 | * @str: another string | ||
298 | */ | ||
299 | int nla_strcmp(const struct nlattr *nla, const char *str) | ||
300 | { | ||
301 | int len = strlen(str) + 1; | ||
302 | int d = nla_len(nla) - len; | ||
303 | |||
304 | if (d == 0) | ||
305 | d = memcmp(nla_data(nla), str, len); | ||
306 | |||
307 | return d; | ||
308 | } | ||
309 | |||
310 | #ifdef CONFIG_NET | ||
311 | /** | ||
312 | * __nla_reserve - reserve room for attribute on the skb | ||
313 | * @skb: socket buffer to reserve room on | ||
314 | * @attrtype: attribute type | ||
315 | * @attrlen: length of attribute payload | ||
316 | * | ||
317 | * Adds a netlink attribute header to a socket buffer and reserves | ||
318 | * room for the payload but does not copy it. | ||
319 | * | ||
320 | * The caller is responsible to ensure that the skb provides enough | ||
321 | * tailroom for the attribute header and payload. | ||
322 | */ | ||
323 | struct nlattr *__nla_reserve(struct sk_buff *skb, int attrtype, int attrlen) | ||
324 | { | ||
325 | struct nlattr *nla; | ||
326 | |||
327 | nla = (struct nlattr *) skb_put(skb, nla_total_size(attrlen)); | ||
328 | nla->nla_type = attrtype; | ||
329 | nla->nla_len = nla_attr_size(attrlen); | ||
330 | |||
331 | memset((unsigned char *) nla + nla->nla_len, 0, nla_padlen(attrlen)); | ||
332 | |||
333 | return nla; | ||
334 | } | ||
335 | EXPORT_SYMBOL(__nla_reserve); | ||
336 | |||
337 | /** | ||
338 | * __nla_reserve_nohdr - reserve room for attribute without header | ||
339 | * @skb: socket buffer to reserve room on | ||
340 | * @attrlen: length of attribute payload | ||
341 | * | ||
342 | * Reserves room for attribute payload without a header. | ||
343 | * | ||
344 | * The caller is responsible to ensure that the skb provides enough | ||
345 | * tailroom for the payload. | ||
346 | */ | ||
347 | void *__nla_reserve_nohdr(struct sk_buff *skb, int attrlen) | ||
348 | { | ||
349 | void *start; | ||
350 | |||
351 | start = skb_put(skb, NLA_ALIGN(attrlen)); | ||
352 | memset(start, 0, NLA_ALIGN(attrlen)); | ||
353 | |||
354 | return start; | ||
355 | } | ||
356 | EXPORT_SYMBOL(__nla_reserve_nohdr); | ||
357 | |||
358 | /** | ||
359 | * nla_reserve - reserve room for attribute on the skb | ||
360 | * @skb: socket buffer to reserve room on | ||
361 | * @attrtype: attribute type | ||
362 | * @attrlen: length of attribute payload | ||
363 | * | ||
364 | * Adds a netlink attribute header to a socket buffer and reserves | ||
365 | * room for the payload but does not copy it. | ||
366 | * | ||
367 | * Returns NULL if the tailroom of the skb is insufficient to store | ||
368 | * the attribute header and payload. | ||
369 | */ | ||
370 | struct nlattr *nla_reserve(struct sk_buff *skb, int attrtype, int attrlen) | ||
371 | { | ||
372 | if (unlikely(skb_tailroom(skb) < nla_total_size(attrlen))) | ||
373 | return NULL; | ||
374 | |||
375 | return __nla_reserve(skb, attrtype, attrlen); | ||
376 | } | ||
377 | EXPORT_SYMBOL(nla_reserve); | ||
378 | |||
379 | /** | ||
380 | * nla_reserve_nohdr - reserve room for attribute without header | ||
381 | * @skb: socket buffer to reserve room on | ||
382 | * @attrlen: length of attribute payload | ||
383 | * | ||
384 | * Reserves room for attribute payload without a header. | ||
385 | * | ||
386 | * Returns NULL if the tailroom of the skb is insufficient to store | ||
387 | * the attribute payload. | ||
388 | */ | ||
389 | void *nla_reserve_nohdr(struct sk_buff *skb, int attrlen) | ||
390 | { | ||
391 | if (unlikely(skb_tailroom(skb) < NLA_ALIGN(attrlen))) | ||
392 | return NULL; | ||
393 | |||
394 | return __nla_reserve_nohdr(skb, attrlen); | ||
395 | } | ||
396 | EXPORT_SYMBOL(nla_reserve_nohdr); | ||
397 | |||
398 | /** | ||
399 | * __nla_put - Add a netlink attribute to a socket buffer | ||
400 | * @skb: socket buffer to add attribute to | ||
401 | * @attrtype: attribute type | ||
402 | * @attrlen: length of attribute payload | ||
403 | * @data: head of attribute payload | ||
404 | * | ||
405 | * The caller is responsible to ensure that the skb provides enough | ||
406 | * tailroom for the attribute header and payload. | ||
407 | */ | ||
408 | void __nla_put(struct sk_buff *skb, int attrtype, int attrlen, | ||
409 | const void *data) | ||
410 | { | ||
411 | struct nlattr *nla; | ||
412 | |||
413 | nla = __nla_reserve(skb, attrtype, attrlen); | ||
414 | memcpy(nla_data(nla), data, attrlen); | ||
415 | } | ||
416 | EXPORT_SYMBOL(__nla_put); | ||
417 | |||
418 | /** | ||
419 | * __nla_put_nohdr - Add a netlink attribute without header | ||
420 | * @skb: socket buffer to add attribute to | ||
421 | * @attrlen: length of attribute payload | ||
422 | * @data: head of attribute payload | ||
423 | * | ||
424 | * The caller is responsible to ensure that the skb provides enough | ||
425 | * tailroom for the attribute payload. | ||
426 | */ | ||
427 | void __nla_put_nohdr(struct sk_buff *skb, int attrlen, const void *data) | ||
428 | { | ||
429 | void *start; | ||
430 | |||
431 | start = __nla_reserve_nohdr(skb, attrlen); | ||
432 | memcpy(start, data, attrlen); | ||
433 | } | ||
434 | EXPORT_SYMBOL(__nla_put_nohdr); | ||
435 | |||
436 | /** | ||
437 | * nla_put - Add a netlink attribute to a socket buffer | ||
438 | * @skb: socket buffer to add attribute to | ||
439 | * @attrtype: attribute type | ||
440 | * @attrlen: length of attribute payload | ||
441 | * @data: head of attribute payload | ||
442 | * | ||
443 | * Returns -EMSGSIZE if the tailroom of the skb is insufficient to store | ||
444 | * the attribute header and payload. | ||
445 | */ | ||
446 | int nla_put(struct sk_buff *skb, int attrtype, int attrlen, const void *data) | ||
447 | { | ||
448 | if (unlikely(skb_tailroom(skb) < nla_total_size(attrlen))) | ||
449 | return -EMSGSIZE; | ||
450 | |||
451 | __nla_put(skb, attrtype, attrlen, data); | ||
452 | return 0; | ||
453 | } | ||
454 | EXPORT_SYMBOL(nla_put); | ||
455 | |||
456 | /** | ||
457 | * nla_put_nohdr - Add a netlink attribute without header | ||
458 | * @skb: socket buffer to add attribute to | ||
459 | * @attrlen: length of attribute payload | ||
460 | * @data: head of attribute payload | ||
461 | * | ||
462 | * Returns -EMSGSIZE if the tailroom of the skb is insufficient to store | ||
463 | * the attribute payload. | ||
464 | */ | ||
465 | int nla_put_nohdr(struct sk_buff *skb, int attrlen, const void *data) | ||
466 | { | ||
467 | if (unlikely(skb_tailroom(skb) < NLA_ALIGN(attrlen))) | ||
468 | return -EMSGSIZE; | ||
469 | |||
470 | __nla_put_nohdr(skb, attrlen, data); | ||
471 | return 0; | ||
472 | } | ||
473 | EXPORT_SYMBOL(nla_put_nohdr); | ||
474 | |||
475 | /** | ||
476 | * nla_append - Add a netlink attribute without header or padding | ||
477 | * @skb: socket buffer to add attribute to | ||
478 | * @attrlen: length of attribute payload | ||
479 | * @data: head of attribute payload | ||
480 | * | ||
481 | * Returns -EMSGSIZE if the tailroom of the skb is insufficient to store | ||
482 | * the attribute payload. | ||
483 | */ | ||
484 | int nla_append(struct sk_buff *skb, int attrlen, const void *data) | ||
485 | { | ||
486 | if (unlikely(skb_tailroom(skb) < NLA_ALIGN(attrlen))) | ||
487 | return -EMSGSIZE; | ||
488 | |||
489 | memcpy(skb_put(skb, attrlen), data, attrlen); | ||
490 | return 0; | ||
491 | } | ||
492 | EXPORT_SYMBOL(nla_append); | ||
493 | #endif | ||
494 | |||
495 | EXPORT_SYMBOL(nla_validate); | ||
496 | EXPORT_SYMBOL(nla_policy_len); | ||
497 | EXPORT_SYMBOL(nla_parse); | ||
498 | EXPORT_SYMBOL(nla_find); | ||
499 | EXPORT_SYMBOL(nla_strlcpy); | ||
500 | EXPORT_SYMBOL(nla_memcpy); | ||
501 | EXPORT_SYMBOL(nla_memcmp); | ||
502 | EXPORT_SYMBOL(nla_strcmp); | ||
diff --git a/lib/rbtree.c b/lib/rbtree.c index 9956b99649f0..f653659e0bc1 100644 --- a/lib/rbtree.c +++ b/lib/rbtree.c | |||
@@ -163,17 +163,14 @@ static void __rb_erase_color(struct rb_node *node, struct rb_node *parent, | |||
163 | { | 163 | { |
164 | if (!other->rb_right || rb_is_black(other->rb_right)) | 164 | if (!other->rb_right || rb_is_black(other->rb_right)) |
165 | { | 165 | { |
166 | struct rb_node *o_left; | 166 | rb_set_black(other->rb_left); |
167 | if ((o_left = other->rb_left)) | ||
168 | rb_set_black(o_left); | ||
169 | rb_set_red(other); | 167 | rb_set_red(other); |
170 | __rb_rotate_right(other, root); | 168 | __rb_rotate_right(other, root); |
171 | other = parent->rb_right; | 169 | other = parent->rb_right; |
172 | } | 170 | } |
173 | rb_set_color(other, rb_color(parent)); | 171 | rb_set_color(other, rb_color(parent)); |
174 | rb_set_black(parent); | 172 | rb_set_black(parent); |
175 | if (other->rb_right) | 173 | rb_set_black(other->rb_right); |
176 | rb_set_black(other->rb_right); | ||
177 | __rb_rotate_left(parent, root); | 174 | __rb_rotate_left(parent, root); |
178 | node = root->rb_node; | 175 | node = root->rb_node; |
179 | break; | 176 | break; |
@@ -200,17 +197,14 @@ static void __rb_erase_color(struct rb_node *node, struct rb_node *parent, | |||
200 | { | 197 | { |
201 | if (!other->rb_left || rb_is_black(other->rb_left)) | 198 | if (!other->rb_left || rb_is_black(other->rb_left)) |
202 | { | 199 | { |
203 | register struct rb_node *o_right; | 200 | rb_set_black(other->rb_right); |
204 | if ((o_right = other->rb_right)) | ||
205 | rb_set_black(o_right); | ||
206 | rb_set_red(other); | 201 | rb_set_red(other); |
207 | __rb_rotate_left(other, root); | 202 | __rb_rotate_left(other, root); |
208 | other = parent->rb_left; | 203 | other = parent->rb_left; |
209 | } | 204 | } |
210 | rb_set_color(other, rb_color(parent)); | 205 | rb_set_color(other, rb_color(parent)); |
211 | rb_set_black(parent); | 206 | rb_set_black(parent); |
212 | if (other->rb_left) | 207 | rb_set_black(other->rb_left); |
213 | rb_set_black(other->rb_left); | ||
214 | __rb_rotate_right(parent, root); | 208 | __rb_rotate_right(parent, root); |
215 | node = root->rb_node; | 209 | node = root->rb_node; |
216 | break; | 210 | break; |
diff --git a/lib/swiotlb.c b/lib/swiotlb.c index 1f991acc2a05..32e2bd3b1142 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c | |||
@@ -145,7 +145,7 @@ static void *swiotlb_bus_to_virt(dma_addr_t address) | |||
145 | return phys_to_virt(swiotlb_bus_to_phys(address)); | 145 | return phys_to_virt(swiotlb_bus_to_phys(address)); |
146 | } | 146 | } |
147 | 147 | ||
148 | int __weak swiotlb_arch_range_needs_mapping(void *ptr, size_t size) | 148 | int __weak swiotlb_arch_range_needs_mapping(phys_addr_t paddr, size_t size) |
149 | { | 149 | { |
150 | return 0; | 150 | return 0; |
151 | } | 151 | } |
@@ -315,9 +315,9 @@ address_needs_mapping(struct device *hwdev, dma_addr_t addr, size_t size) | |||
315 | return !is_buffer_dma_capable(dma_get_mask(hwdev), addr, size); | 315 | return !is_buffer_dma_capable(dma_get_mask(hwdev), addr, size); |
316 | } | 316 | } |
317 | 317 | ||
318 | static inline int range_needs_mapping(void *ptr, size_t size) | 318 | static inline int range_needs_mapping(phys_addr_t paddr, size_t size) |
319 | { | 319 | { |
320 | return swiotlb_force || swiotlb_arch_range_needs_mapping(ptr, size); | 320 | return swiotlb_force || swiotlb_arch_range_needs_mapping(paddr, size); |
321 | } | 321 | } |
322 | 322 | ||
323 | static int is_swiotlb_buffer(char *addr) | 323 | static int is_swiotlb_buffer(char *addr) |
@@ -636,11 +636,14 @@ swiotlb_full(struct device *dev, size_t size, int dir, int do_panic) | |||
636 | * Once the device is given the dma address, the device owns this memory until | 636 | * Once the device is given the dma address, the device owns this memory until |
637 | * either swiotlb_unmap_single or swiotlb_dma_sync_single is performed. | 637 | * either swiotlb_unmap_single or swiotlb_dma_sync_single is performed. |
638 | */ | 638 | */ |
639 | dma_addr_t | 639 | dma_addr_t swiotlb_map_page(struct device *dev, struct page *page, |
640 | swiotlb_map_single_attrs(struct device *hwdev, void *ptr, size_t size, | 640 | unsigned long offset, size_t size, |
641 | int dir, struct dma_attrs *attrs) | 641 | enum dma_data_direction dir, |
642 | { | 642 | struct dma_attrs *attrs) |
643 | dma_addr_t dev_addr = swiotlb_virt_to_bus(hwdev, ptr); | 643 | { |
644 | phys_addr_t phys = page_to_phys(page) + offset; | ||
645 | void *ptr = page_address(page) + offset; | ||
646 | dma_addr_t dev_addr = swiotlb_phys_to_bus(dev, phys); | ||
644 | void *map; | 647 | void *map; |
645 | 648 | ||
646 | BUG_ON(dir == DMA_NONE); | 649 | BUG_ON(dir == DMA_NONE); |
@@ -649,37 +652,30 @@ swiotlb_map_single_attrs(struct device *hwdev, void *ptr, size_t size, | |||
649 | * we can safely return the device addr and not worry about bounce | 652 | * we can safely return the device addr and not worry about bounce |
650 | * buffering it. | 653 | * buffering it. |
651 | */ | 654 | */ |
652 | if (!address_needs_mapping(hwdev, dev_addr, size) && | 655 | if (!address_needs_mapping(dev, dev_addr, size) && |
653 | !range_needs_mapping(ptr, size)) | 656 | !range_needs_mapping(virt_to_phys(ptr), size)) |
654 | return dev_addr; | 657 | return dev_addr; |
655 | 658 | ||
656 | /* | 659 | /* |
657 | * Oh well, have to allocate and map a bounce buffer. | 660 | * Oh well, have to allocate and map a bounce buffer. |
658 | */ | 661 | */ |
659 | map = map_single(hwdev, virt_to_phys(ptr), size, dir); | 662 | map = map_single(dev, phys, size, dir); |
660 | if (!map) { | 663 | if (!map) { |
661 | swiotlb_full(hwdev, size, dir, 1); | 664 | swiotlb_full(dev, size, dir, 1); |
662 | map = io_tlb_overflow_buffer; | 665 | map = io_tlb_overflow_buffer; |
663 | } | 666 | } |
664 | 667 | ||
665 | dev_addr = swiotlb_virt_to_bus(hwdev, map); | 668 | dev_addr = swiotlb_virt_to_bus(dev, map); |
666 | 669 | ||
667 | /* | 670 | /* |
668 | * Ensure that the address returned is DMA'ble | 671 | * Ensure that the address returned is DMA'ble |
669 | */ | 672 | */ |
670 | if (address_needs_mapping(hwdev, dev_addr, size)) | 673 | if (address_needs_mapping(dev, dev_addr, size)) |
671 | panic("map_single: bounce buffer is not DMA'ble"); | 674 | panic("map_single: bounce buffer is not DMA'ble"); |
672 | 675 | ||
673 | return dev_addr; | 676 | return dev_addr; |
674 | } | 677 | } |
675 | EXPORT_SYMBOL(swiotlb_map_single_attrs); | 678 | EXPORT_SYMBOL_GPL(swiotlb_map_page); |
676 | |||
677 | dma_addr_t | ||
678 | swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir) | ||
679 | { | ||
680 | return swiotlb_map_single_attrs(hwdev, ptr, size, dir, NULL); | ||
681 | } | ||
682 | EXPORT_SYMBOL(swiotlb_map_single); | ||
683 | 679 | ||
684 | /* | 680 | /* |
685 | * Unmap a single streaming mode DMA translation. The dma_addr and size must | 681 | * Unmap a single streaming mode DMA translation. The dma_addr and size must |
@@ -689,9 +685,9 @@ EXPORT_SYMBOL(swiotlb_map_single); | |||
689 | * After this call, reads by the cpu to the buffer are guaranteed to see | 685 | * After this call, reads by the cpu to the buffer are guaranteed to see |
690 | * whatever the device wrote there. | 686 | * whatever the device wrote there. |
691 | */ | 687 | */ |
692 | void | 688 | void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr, |
693 | swiotlb_unmap_single_attrs(struct device *hwdev, dma_addr_t dev_addr, | 689 | size_t size, enum dma_data_direction dir, |
694 | size_t size, int dir, struct dma_attrs *attrs) | 690 | struct dma_attrs *attrs) |
695 | { | 691 | { |
696 | char *dma_addr = swiotlb_bus_to_virt(dev_addr); | 692 | char *dma_addr = swiotlb_bus_to_virt(dev_addr); |
697 | 693 | ||
@@ -701,15 +697,7 @@ swiotlb_unmap_single_attrs(struct device *hwdev, dma_addr_t dev_addr, | |||
701 | else if (dir == DMA_FROM_DEVICE) | 697 | else if (dir == DMA_FROM_DEVICE) |
702 | dma_mark_clean(dma_addr, size); | 698 | dma_mark_clean(dma_addr, size); |
703 | } | 699 | } |
704 | EXPORT_SYMBOL(swiotlb_unmap_single_attrs); | 700 | EXPORT_SYMBOL_GPL(swiotlb_unmap_page); |
705 | |||
706 | void | ||
707 | swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, size_t size, | ||
708 | int dir) | ||
709 | { | ||
710 | return swiotlb_unmap_single_attrs(hwdev, dev_addr, size, dir, NULL); | ||
711 | } | ||
712 | EXPORT_SYMBOL(swiotlb_unmap_single); | ||
713 | 701 | ||
714 | /* | 702 | /* |
715 | * Make physical memory consistent for a single streaming mode DMA translation | 703 | * Make physical memory consistent for a single streaming mode DMA translation |
@@ -736,7 +724,7 @@ swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr, | |||
736 | 724 | ||
737 | void | 725 | void |
738 | swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr, | 726 | swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr, |
739 | size_t size, int dir) | 727 | size_t size, enum dma_data_direction dir) |
740 | { | 728 | { |
741 | swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_CPU); | 729 | swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_CPU); |
742 | } | 730 | } |
@@ -744,7 +732,7 @@ EXPORT_SYMBOL(swiotlb_sync_single_for_cpu); | |||
744 | 732 | ||
745 | void | 733 | void |
746 | swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr, | 734 | swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr, |
747 | size_t size, int dir) | 735 | size_t size, enum dma_data_direction dir) |
748 | { | 736 | { |
749 | swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_DEVICE); | 737 | swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_DEVICE); |
750 | } | 738 | } |
@@ -769,7 +757,8 @@ swiotlb_sync_single_range(struct device *hwdev, dma_addr_t dev_addr, | |||
769 | 757 | ||
770 | void | 758 | void |
771 | swiotlb_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dev_addr, | 759 | swiotlb_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dev_addr, |
772 | unsigned long offset, size_t size, int dir) | 760 | unsigned long offset, size_t size, |
761 | enum dma_data_direction dir) | ||
773 | { | 762 | { |
774 | swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir, | 763 | swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir, |
775 | SYNC_FOR_CPU); | 764 | SYNC_FOR_CPU); |
@@ -778,7 +767,8 @@ EXPORT_SYMBOL_GPL(swiotlb_sync_single_range_for_cpu); | |||
778 | 767 | ||
779 | void | 768 | void |
780 | swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr, | 769 | swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr, |
781 | unsigned long offset, size_t size, int dir) | 770 | unsigned long offset, size_t size, |
771 | enum dma_data_direction dir) | ||
782 | { | 772 | { |
783 | swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir, | 773 | swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir, |
784 | SYNC_FOR_DEVICE); | 774 | SYNC_FOR_DEVICE); |
@@ -803,7 +793,7 @@ EXPORT_SYMBOL_GPL(swiotlb_sync_single_range_for_device); | |||
803 | */ | 793 | */ |
804 | int | 794 | int |
805 | swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems, | 795 | swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems, |
806 | int dir, struct dma_attrs *attrs) | 796 | enum dma_data_direction dir, struct dma_attrs *attrs) |
807 | { | 797 | { |
808 | struct scatterlist *sg; | 798 | struct scatterlist *sg; |
809 | int i; | 799 | int i; |
@@ -811,10 +801,10 @@ swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems, | |||
811 | BUG_ON(dir == DMA_NONE); | 801 | BUG_ON(dir == DMA_NONE); |
812 | 802 | ||
813 | for_each_sg(sgl, sg, nelems, i) { | 803 | for_each_sg(sgl, sg, nelems, i) { |
814 | void *addr = sg_virt(sg); | 804 | phys_addr_t paddr = sg_phys(sg); |
815 | dma_addr_t dev_addr = swiotlb_virt_to_bus(hwdev, addr); | 805 | dma_addr_t dev_addr = swiotlb_phys_to_bus(hwdev, paddr); |
816 | 806 | ||
817 | if (range_needs_mapping(addr, sg->length) || | 807 | if (range_needs_mapping(paddr, sg->length) || |
818 | address_needs_mapping(hwdev, dev_addr, sg->length)) { | 808 | address_needs_mapping(hwdev, dev_addr, sg->length)) { |
819 | void *map = map_single(hwdev, sg_phys(sg), | 809 | void *map = map_single(hwdev, sg_phys(sg), |
820 | sg->length, dir); | 810 | sg->length, dir); |
@@ -850,7 +840,7 @@ EXPORT_SYMBOL(swiotlb_map_sg); | |||
850 | */ | 840 | */ |
851 | void | 841 | void |
852 | swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl, | 842 | swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl, |
853 | int nelems, int dir, struct dma_attrs *attrs) | 843 | int nelems, enum dma_data_direction dir, struct dma_attrs *attrs) |
854 | { | 844 | { |
855 | struct scatterlist *sg; | 845 | struct scatterlist *sg; |
856 | int i; | 846 | int i; |
@@ -858,11 +848,11 @@ swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl, | |||
858 | BUG_ON(dir == DMA_NONE); | 848 | BUG_ON(dir == DMA_NONE); |
859 | 849 | ||
860 | for_each_sg(sgl, sg, nelems, i) { | 850 | for_each_sg(sgl, sg, nelems, i) { |
861 | if (sg->dma_address != swiotlb_virt_to_bus(hwdev, sg_virt(sg))) | 851 | if (sg->dma_address != swiotlb_phys_to_bus(hwdev, sg_phys(sg))) |
862 | unmap_single(hwdev, swiotlb_bus_to_virt(sg->dma_address), | 852 | unmap_single(hwdev, swiotlb_bus_to_virt(sg->dma_address), |
863 | sg->dma_length, dir); | 853 | sg->dma_length, dir); |
864 | else if (dir == DMA_FROM_DEVICE) | 854 | else if (dir == DMA_FROM_DEVICE) |
865 | dma_mark_clean(sg_virt(sg), sg->dma_length); | 855 | dma_mark_clean(swiotlb_bus_to_virt(sg->dma_address), sg->dma_length); |
866 | } | 856 | } |
867 | } | 857 | } |
868 | EXPORT_SYMBOL(swiotlb_unmap_sg_attrs); | 858 | EXPORT_SYMBOL(swiotlb_unmap_sg_attrs); |
@@ -892,17 +882,17 @@ swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sgl, | |||
892 | BUG_ON(dir == DMA_NONE); | 882 | BUG_ON(dir == DMA_NONE); |
893 | 883 | ||
894 | for_each_sg(sgl, sg, nelems, i) { | 884 | for_each_sg(sgl, sg, nelems, i) { |
895 | if (sg->dma_address != swiotlb_virt_to_bus(hwdev, sg_virt(sg))) | 885 | if (sg->dma_address != swiotlb_phys_to_bus(hwdev, sg_phys(sg))) |
896 | sync_single(hwdev, swiotlb_bus_to_virt(sg->dma_address), | 886 | sync_single(hwdev, swiotlb_bus_to_virt(sg->dma_address), |
897 | sg->dma_length, dir, target); | 887 | sg->dma_length, dir, target); |
898 | else if (dir == DMA_FROM_DEVICE) | 888 | else if (dir == DMA_FROM_DEVICE) |
899 | dma_mark_clean(sg_virt(sg), sg->dma_length); | 889 | dma_mark_clean(swiotlb_bus_to_virt(sg->dma_address), sg->dma_length); |
900 | } | 890 | } |
901 | } | 891 | } |
902 | 892 | ||
903 | void | 893 | void |
904 | swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, | 894 | swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, |
905 | int nelems, int dir) | 895 | int nelems, enum dma_data_direction dir) |
906 | { | 896 | { |
907 | swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_CPU); | 897 | swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_CPU); |
908 | } | 898 | } |
@@ -910,7 +900,7 @@ EXPORT_SYMBOL(swiotlb_sync_sg_for_cpu); | |||
910 | 900 | ||
911 | void | 901 | void |
912 | swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, | 902 | swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, |
913 | int nelems, int dir) | 903 | int nelems, enum dma_data_direction dir) |
914 | { | 904 | { |
915 | swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_DEVICE); | 905 | swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_DEVICE); |
916 | } | 906 | } |
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 0fbd0121d91d..be3001f912e4 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
@@ -396,7 +396,38 @@ static noinline char* put_dec(char *buf, unsigned long long num) | |||
396 | #define SMALL 32 /* Must be 32 == 0x20 */ | 396 | #define SMALL 32 /* Must be 32 == 0x20 */ |
397 | #define SPECIAL 64 /* 0x */ | 397 | #define SPECIAL 64 /* 0x */ |
398 | 398 | ||
399 | static char *number(char *buf, char *end, unsigned long long num, int base, int size, int precision, int type) | 399 | enum format_type { |
400 | FORMAT_TYPE_NONE, /* Just a string part */ | ||
401 | FORMAT_TYPE_WIDTH, | ||
402 | FORMAT_TYPE_PRECISION, | ||
403 | FORMAT_TYPE_CHAR, | ||
404 | FORMAT_TYPE_STR, | ||
405 | FORMAT_TYPE_PTR, | ||
406 | FORMAT_TYPE_PERCENT_CHAR, | ||
407 | FORMAT_TYPE_INVALID, | ||
408 | FORMAT_TYPE_LONG_LONG, | ||
409 | FORMAT_TYPE_ULONG, | ||
410 | FORMAT_TYPE_LONG, | ||
411 | FORMAT_TYPE_USHORT, | ||
412 | FORMAT_TYPE_SHORT, | ||
413 | FORMAT_TYPE_UINT, | ||
414 | FORMAT_TYPE_INT, | ||
415 | FORMAT_TYPE_NRCHARS, | ||
416 | FORMAT_TYPE_SIZE_T, | ||
417 | FORMAT_TYPE_PTRDIFF | ||
418 | }; | ||
419 | |||
420 | struct printf_spec { | ||
421 | enum format_type type; | ||
422 | int flags; /* flags to number() */ | ||
423 | int field_width; /* width of output field */ | ||
424 | int base; | ||
425 | int precision; /* # of digits/chars */ | ||
426 | int qualifier; | ||
427 | }; | ||
428 | |||
429 | static char *number(char *buf, char *end, unsigned long long num, | ||
430 | struct printf_spec spec) | ||
400 | { | 431 | { |
401 | /* we are called with base 8, 10 or 16, only, thus don't need "G..." */ | 432 | /* we are called with base 8, 10 or 16, only, thus don't need "G..." */ |
402 | static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */ | 433 | static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */ |
@@ -404,32 +435,32 @@ static char *number(char *buf, char *end, unsigned long long num, int base, int | |||
404 | char tmp[66]; | 435 | char tmp[66]; |
405 | char sign; | 436 | char sign; |
406 | char locase; | 437 | char locase; |
407 | int need_pfx = ((type & SPECIAL) && base != 10); | 438 | int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10); |
408 | int i; | 439 | int i; |
409 | 440 | ||
410 | /* locase = 0 or 0x20. ORing digits or letters with 'locase' | 441 | /* locase = 0 or 0x20. ORing digits or letters with 'locase' |
411 | * produces same digits or (maybe lowercased) letters */ | 442 | * produces same digits or (maybe lowercased) letters */ |
412 | locase = (type & SMALL); | 443 | locase = (spec.flags & SMALL); |
413 | if (type & LEFT) | 444 | if (spec.flags & LEFT) |
414 | type &= ~ZEROPAD; | 445 | spec.flags &= ~ZEROPAD; |
415 | sign = 0; | 446 | sign = 0; |
416 | if (type & SIGN) { | 447 | if (spec.flags & SIGN) { |
417 | if ((signed long long) num < 0) { | 448 | if ((signed long long) num < 0) { |
418 | sign = '-'; | 449 | sign = '-'; |
419 | num = - (signed long long) num; | 450 | num = - (signed long long) num; |
420 | size--; | 451 | spec.field_width--; |
421 | } else if (type & PLUS) { | 452 | } else if (spec.flags & PLUS) { |
422 | sign = '+'; | 453 | sign = '+'; |
423 | size--; | 454 | spec.field_width--; |
424 | } else if (type & SPACE) { | 455 | } else if (spec.flags & SPACE) { |
425 | sign = ' '; | 456 | sign = ' '; |
426 | size--; | 457 | spec.field_width--; |
427 | } | 458 | } |
428 | } | 459 | } |
429 | if (need_pfx) { | 460 | if (need_pfx) { |
430 | size--; | 461 | spec.field_width--; |
431 | if (base == 16) | 462 | if (spec.base == 16) |
432 | size--; | 463 | spec.field_width--; |
433 | } | 464 | } |
434 | 465 | ||
435 | /* generate full string in tmp[], in reverse order */ | 466 | /* generate full string in tmp[], in reverse order */ |
@@ -441,10 +472,10 @@ static char *number(char *buf, char *end, unsigned long long num, int base, int | |||
441 | tmp[i++] = (digits[do_div(num,base)] | locase); | 472 | tmp[i++] = (digits[do_div(num,base)] | locase); |
442 | } while (num != 0); | 473 | } while (num != 0); |
443 | */ | 474 | */ |
444 | else if (base != 10) { /* 8 or 16 */ | 475 | else if (spec.base != 10) { /* 8 or 16 */ |
445 | int mask = base - 1; | 476 | int mask = spec.base - 1; |
446 | int shift = 3; | 477 | int shift = 3; |
447 | if (base == 16) shift = 4; | 478 | if (spec.base == 16) shift = 4; |
448 | do { | 479 | do { |
449 | tmp[i++] = (digits[((unsigned char)num) & mask] | locase); | 480 | tmp[i++] = (digits[((unsigned char)num) & mask] | locase); |
450 | num >>= shift; | 481 | num >>= shift; |
@@ -454,12 +485,12 @@ static char *number(char *buf, char *end, unsigned long long num, int base, int | |||
454 | } | 485 | } |
455 | 486 | ||
456 | /* printing 100 using %2d gives "100", not "00" */ | 487 | /* printing 100 using %2d gives "100", not "00" */ |
457 | if (i > precision) | 488 | if (i > spec.precision) |
458 | precision = i; | 489 | spec.precision = i; |
459 | /* leading space padding */ | 490 | /* leading space padding */ |
460 | size -= precision; | 491 | spec.field_width -= spec.precision; |
461 | if (!(type & (ZEROPAD+LEFT))) { | 492 | if (!(spec.flags & (ZEROPAD+LEFT))) { |
462 | while(--size >= 0) { | 493 | while(--spec.field_width >= 0) { |
463 | if (buf < end) | 494 | if (buf < end) |
464 | *buf = ' '; | 495 | *buf = ' '; |
465 | ++buf; | 496 | ++buf; |
@@ -476,23 +507,23 @@ static char *number(char *buf, char *end, unsigned long long num, int base, int | |||
476 | if (buf < end) | 507 | if (buf < end) |
477 | *buf = '0'; | 508 | *buf = '0'; |
478 | ++buf; | 509 | ++buf; |
479 | if (base == 16) { | 510 | if (spec.base == 16) { |
480 | if (buf < end) | 511 | if (buf < end) |
481 | *buf = ('X' | locase); | 512 | *buf = ('X' | locase); |
482 | ++buf; | 513 | ++buf; |
483 | } | 514 | } |
484 | } | 515 | } |
485 | /* zero or space padding */ | 516 | /* zero or space padding */ |
486 | if (!(type & LEFT)) { | 517 | if (!(spec.flags & LEFT)) { |
487 | char c = (type & ZEROPAD) ? '0' : ' '; | 518 | char c = (spec.flags & ZEROPAD) ? '0' : ' '; |
488 | while (--size >= 0) { | 519 | while (--spec.field_width >= 0) { |
489 | if (buf < end) | 520 | if (buf < end) |
490 | *buf = c; | 521 | *buf = c; |
491 | ++buf; | 522 | ++buf; |
492 | } | 523 | } |
493 | } | 524 | } |
494 | /* hmm even more zero padding? */ | 525 | /* hmm even more zero padding? */ |
495 | while (i <= --precision) { | 526 | while (i <= --spec.precision) { |
496 | if (buf < end) | 527 | if (buf < end) |
497 | *buf = '0'; | 528 | *buf = '0'; |
498 | ++buf; | 529 | ++buf; |
@@ -504,7 +535,7 @@ static char *number(char *buf, char *end, unsigned long long num, int base, int | |||
504 | ++buf; | 535 | ++buf; |
505 | } | 536 | } |
506 | /* trailing space padding */ | 537 | /* trailing space padding */ |
507 | while (--size >= 0) { | 538 | while (--spec.field_width >= 0) { |
508 | if (buf < end) | 539 | if (buf < end) |
509 | *buf = ' '; | 540 | *buf = ' '; |
510 | ++buf; | 541 | ++buf; |
@@ -512,17 +543,17 @@ static char *number(char *buf, char *end, unsigned long long num, int base, int | |||
512 | return buf; | 543 | return buf; |
513 | } | 544 | } |
514 | 545 | ||
515 | static char *string(char *buf, char *end, char *s, int field_width, int precision, int flags) | 546 | static char *string(char *buf, char *end, char *s, struct printf_spec spec) |
516 | { | 547 | { |
517 | int len, i; | 548 | int len, i; |
518 | 549 | ||
519 | if ((unsigned long)s < PAGE_SIZE) | 550 | if ((unsigned long)s < PAGE_SIZE) |
520 | s = "<NULL>"; | 551 | s = "<NULL>"; |
521 | 552 | ||
522 | len = strnlen(s, precision); | 553 | len = strnlen(s, spec.precision); |
523 | 554 | ||
524 | if (!(flags & LEFT)) { | 555 | if (!(spec.flags & LEFT)) { |
525 | while (len < field_width--) { | 556 | while (len < spec.field_width--) { |
526 | if (buf < end) | 557 | if (buf < end) |
527 | *buf = ' '; | 558 | *buf = ' '; |
528 | ++buf; | 559 | ++buf; |
@@ -533,7 +564,7 @@ static char *string(char *buf, char *end, char *s, int field_width, int precisio | |||
533 | *buf = *s; | 564 | *buf = *s; |
534 | ++buf; ++s; | 565 | ++buf; ++s; |
535 | } | 566 | } |
536 | while (len < field_width--) { | 567 | while (len < spec.field_width--) { |
537 | if (buf < end) | 568 | if (buf < end) |
538 | *buf = ' '; | 569 | *buf = ' '; |
539 | ++buf; | 570 | ++buf; |
@@ -541,21 +572,24 @@ static char *string(char *buf, char *end, char *s, int field_width, int precisio | |||
541 | return buf; | 572 | return buf; |
542 | } | 573 | } |
543 | 574 | ||
544 | static char *symbol_string(char *buf, char *end, void *ptr, int field_width, int precision, int flags) | 575 | static char *symbol_string(char *buf, char *end, void *ptr, |
576 | struct printf_spec spec) | ||
545 | { | 577 | { |
546 | unsigned long value = (unsigned long) ptr; | 578 | unsigned long value = (unsigned long) ptr; |
547 | #ifdef CONFIG_KALLSYMS | 579 | #ifdef CONFIG_KALLSYMS |
548 | char sym[KSYM_SYMBOL_LEN]; | 580 | char sym[KSYM_SYMBOL_LEN]; |
549 | sprint_symbol(sym, value); | 581 | sprint_symbol(sym, value); |
550 | return string(buf, end, sym, field_width, precision, flags); | 582 | return string(buf, end, sym, spec); |
551 | #else | 583 | #else |
552 | field_width = 2*sizeof(void *); | 584 | spec.field_width = 2*sizeof(void *); |
553 | flags |= SPECIAL | SMALL | ZEROPAD; | 585 | spec.flags |= SPECIAL | SMALL | ZEROPAD; |
554 | return number(buf, end, value, 16, field_width, precision, flags); | 586 | spec.base = 16; |
587 | return number(buf, end, value, spec); | ||
555 | #endif | 588 | #endif |
556 | } | 589 | } |
557 | 590 | ||
558 | static char *resource_string(char *buf, char *end, struct resource *res, int field_width, int precision, int flags) | 591 | static char *resource_string(char *buf, char *end, struct resource *res, |
592 | struct printf_spec spec) | ||
559 | { | 593 | { |
560 | #ifndef IO_RSRC_PRINTK_SIZE | 594 | #ifndef IO_RSRC_PRINTK_SIZE |
561 | #define IO_RSRC_PRINTK_SIZE 4 | 595 | #define IO_RSRC_PRINTK_SIZE 4 |
@@ -564,7 +598,11 @@ static char *resource_string(char *buf, char *end, struct resource *res, int fie | |||
564 | #ifndef MEM_RSRC_PRINTK_SIZE | 598 | #ifndef MEM_RSRC_PRINTK_SIZE |
565 | #define MEM_RSRC_PRINTK_SIZE 8 | 599 | #define MEM_RSRC_PRINTK_SIZE 8 |
566 | #endif | 600 | #endif |
567 | 601 | struct printf_spec num_spec = { | |
602 | .base = 16, | ||
603 | .precision = -1, | ||
604 | .flags = SPECIAL | SMALL | ZEROPAD, | ||
605 | }; | ||
568 | /* room for the actual numbers, the two "0x", -, [, ] and the final zero */ | 606 | /* room for the actual numbers, the two "0x", -, [, ] and the final zero */ |
569 | char sym[4*sizeof(resource_size_t) + 8]; | 607 | char sym[4*sizeof(resource_size_t) + 8]; |
570 | char *p = sym, *pend = sym + sizeof(sym); | 608 | char *p = sym, *pend = sym + sizeof(sym); |
@@ -576,17 +614,18 @@ static char *resource_string(char *buf, char *end, struct resource *res, int fie | |||
576 | size = MEM_RSRC_PRINTK_SIZE; | 614 | size = MEM_RSRC_PRINTK_SIZE; |
577 | 615 | ||
578 | *p++ = '['; | 616 | *p++ = '['; |
579 | p = number(p, pend, res->start, 16, size, -1, SPECIAL | SMALL | ZEROPAD); | 617 | num_spec.field_width = size; |
618 | p = number(p, pend, res->start, num_spec); | ||
580 | *p++ = '-'; | 619 | *p++ = '-'; |
581 | p = number(p, pend, res->end, 16, size, -1, SPECIAL | SMALL | ZEROPAD); | 620 | p = number(p, pend, res->end, num_spec); |
582 | *p++ = ']'; | 621 | *p++ = ']'; |
583 | *p = 0; | 622 | *p = 0; |
584 | 623 | ||
585 | return string(buf, end, sym, field_width, precision, flags); | 624 | return string(buf, end, sym, spec); |
586 | } | 625 | } |
587 | 626 | ||
588 | static char *mac_address_string(char *buf, char *end, u8 *addr, int field_width, | 627 | static char *mac_address_string(char *buf, char *end, u8 *addr, |
589 | int precision, int flags) | 628 | struct printf_spec spec) |
590 | { | 629 | { |
591 | char mac_addr[6 * 3]; /* (6 * 2 hex digits), 5 colons and trailing zero */ | 630 | char mac_addr[6 * 3]; /* (6 * 2 hex digits), 5 colons and trailing zero */ |
592 | char *p = mac_addr; | 631 | char *p = mac_addr; |
@@ -594,16 +633,17 @@ static char *mac_address_string(char *buf, char *end, u8 *addr, int field_width, | |||
594 | 633 | ||
595 | for (i = 0; i < 6; i++) { | 634 | for (i = 0; i < 6; i++) { |
596 | p = pack_hex_byte(p, addr[i]); | 635 | p = pack_hex_byte(p, addr[i]); |
597 | if (!(flags & SPECIAL) && i != 5) | 636 | if (!(spec.flags & SPECIAL) && i != 5) |
598 | *p++ = ':'; | 637 | *p++ = ':'; |
599 | } | 638 | } |
600 | *p = '\0'; | 639 | *p = '\0'; |
640 | spec.flags &= ~SPECIAL; | ||
601 | 641 | ||
602 | return string(buf, end, mac_addr, field_width, precision, flags & ~SPECIAL); | 642 | return string(buf, end, mac_addr, spec); |
603 | } | 643 | } |
604 | 644 | ||
605 | static char *ip6_addr_string(char *buf, char *end, u8 *addr, int field_width, | 645 | static char *ip6_addr_string(char *buf, char *end, u8 *addr, |
606 | int precision, int flags) | 646 | struct printf_spec spec) |
607 | { | 647 | { |
608 | char ip6_addr[8 * 5]; /* (8 * 4 hex digits), 7 colons and trailing zero */ | 648 | char ip6_addr[8 * 5]; /* (8 * 4 hex digits), 7 colons and trailing zero */ |
609 | char *p = ip6_addr; | 649 | char *p = ip6_addr; |
@@ -612,16 +652,17 @@ static char *ip6_addr_string(char *buf, char *end, u8 *addr, int field_width, | |||
612 | for (i = 0; i < 8; i++) { | 652 | for (i = 0; i < 8; i++) { |
613 | p = pack_hex_byte(p, addr[2 * i]); | 653 | p = pack_hex_byte(p, addr[2 * i]); |
614 | p = pack_hex_byte(p, addr[2 * i + 1]); | 654 | p = pack_hex_byte(p, addr[2 * i + 1]); |
615 | if (!(flags & SPECIAL) && i != 7) | 655 | if (!(spec.flags & SPECIAL) && i != 7) |
616 | *p++ = ':'; | 656 | *p++ = ':'; |
617 | } | 657 | } |
618 | *p = '\0'; | 658 | *p = '\0'; |
659 | spec.flags &= ~SPECIAL; | ||
619 | 660 | ||
620 | return string(buf, end, ip6_addr, field_width, precision, flags & ~SPECIAL); | 661 | return string(buf, end, ip6_addr, spec); |
621 | } | 662 | } |
622 | 663 | ||
623 | static char *ip4_addr_string(char *buf, char *end, u8 *addr, int field_width, | 664 | static char *ip4_addr_string(char *buf, char *end, u8 *addr, |
624 | int precision, int flags) | 665 | struct printf_spec spec) |
625 | { | 666 | { |
626 | char ip4_addr[4 * 4]; /* (4 * 3 decimal digits), 3 dots and trailing zero */ | 667 | char ip4_addr[4 * 4]; /* (4 * 3 decimal digits), 3 dots and trailing zero */ |
627 | char temp[3]; /* hold each IP quad in reverse order */ | 668 | char temp[3]; /* hold each IP quad in reverse order */ |
@@ -637,8 +678,9 @@ static char *ip4_addr_string(char *buf, char *end, u8 *addr, int field_width, | |||
637 | *p++ = '.'; | 678 | *p++ = '.'; |
638 | } | 679 | } |
639 | *p = '\0'; | 680 | *p = '\0'; |
681 | spec.flags &= ~SPECIAL; | ||
640 | 682 | ||
641 | return string(buf, end, ip4_addr, field_width, precision, flags & ~SPECIAL); | 683 | return string(buf, end, ip4_addr, spec); |
642 | } | 684 | } |
643 | 685 | ||
644 | /* | 686 | /* |
@@ -663,41 +705,233 @@ static char *ip4_addr_string(char *buf, char *end, u8 *addr, int field_width, | |||
663 | * function pointers are really function descriptors, which contain a | 705 | * function pointers are really function descriptors, which contain a |
664 | * pointer to the real address. | 706 | * pointer to the real address. |
665 | */ | 707 | */ |
666 | static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field_width, int precision, int flags) | 708 | static char *pointer(const char *fmt, char *buf, char *end, void *ptr, |
709 | struct printf_spec spec) | ||
667 | { | 710 | { |
668 | if (!ptr) | 711 | if (!ptr) |
669 | return string(buf, end, "(null)", field_width, precision, flags); | 712 | return string(buf, end, "(null)", spec); |
670 | 713 | ||
671 | switch (*fmt) { | 714 | switch (*fmt) { |
672 | case 'F': | 715 | case 'F': |
673 | ptr = dereference_function_descriptor(ptr); | 716 | ptr = dereference_function_descriptor(ptr); |
674 | /* Fallthrough */ | 717 | /* Fallthrough */ |
675 | case 'S': | 718 | case 'S': |
676 | return symbol_string(buf, end, ptr, field_width, precision, flags); | 719 | return symbol_string(buf, end, ptr, spec); |
677 | case 'R': | 720 | case 'R': |
678 | return resource_string(buf, end, ptr, field_width, precision, flags); | 721 | return resource_string(buf, end, ptr, spec); |
679 | case 'm': | 722 | case 'm': |
680 | flags |= SPECIAL; | 723 | spec.flags |= SPECIAL; |
681 | /* Fallthrough */ | 724 | /* Fallthrough */ |
682 | case 'M': | 725 | case 'M': |
683 | return mac_address_string(buf, end, ptr, field_width, precision, flags); | 726 | return mac_address_string(buf, end, ptr, spec); |
684 | case 'i': | 727 | case 'i': |
685 | flags |= SPECIAL; | 728 | spec.flags |= SPECIAL; |
686 | /* Fallthrough */ | 729 | /* Fallthrough */ |
687 | case 'I': | 730 | case 'I': |
688 | if (fmt[1] == '6') | 731 | if (fmt[1] == '6') |
689 | return ip6_addr_string(buf, end, ptr, field_width, precision, flags); | 732 | return ip6_addr_string(buf, end, ptr, spec); |
690 | if (fmt[1] == '4') | 733 | if (fmt[1] == '4') |
691 | return ip4_addr_string(buf, end, ptr, field_width, precision, flags); | 734 | return ip4_addr_string(buf, end, ptr, spec); |
692 | flags &= ~SPECIAL; | 735 | spec.flags &= ~SPECIAL; |
736 | break; | ||
737 | } | ||
738 | spec.flags |= SMALL; | ||
739 | if (spec.field_width == -1) { | ||
740 | spec.field_width = 2*sizeof(void *); | ||
741 | spec.flags |= ZEROPAD; | ||
742 | } | ||
743 | spec.base = 16; | ||
744 | |||
745 | return number(buf, end, (unsigned long) ptr, spec); | ||
746 | } | ||
747 | |||
748 | /* | ||
749 | * Helper function to decode printf style format. | ||
750 | * Each call decode a token from the format and return the | ||
751 | * number of characters read (or likely the delta where it wants | ||
752 | * to go on the next call). | ||
753 | * The decoded token is returned through the parameters | ||
754 | * | ||
755 | * 'h', 'l', or 'L' for integer fields | ||
756 | * 'z' support added 23/7/1999 S.H. | ||
757 | * 'z' changed to 'Z' --davidm 1/25/99 | ||
758 | * 't' added for ptrdiff_t | ||
759 | * | ||
760 | * @fmt: the format string | ||
761 | * @type of the token returned | ||
762 | * @flags: various flags such as +, -, # tokens.. | ||
763 | * @field_width: overwritten width | ||
764 | * @base: base of the number (octal, hex, ...) | ||
765 | * @precision: precision of a number | ||
766 | * @qualifier: qualifier of a number (long, size_t, ...) | ||
767 | */ | ||
768 | static int format_decode(const char *fmt, struct printf_spec *spec) | ||
769 | { | ||
770 | const char *start = fmt; | ||
771 | |||
772 | /* we finished early by reading the field width */ | ||
773 | if (spec->type == FORMAT_TYPE_WIDTH) { | ||
774 | if (spec->field_width < 0) { | ||
775 | spec->field_width = -spec->field_width; | ||
776 | spec->flags |= LEFT; | ||
777 | } | ||
778 | spec->type = FORMAT_TYPE_NONE; | ||
779 | goto precision; | ||
780 | } | ||
781 | |||
782 | /* we finished early by reading the precision */ | ||
783 | if (spec->type == FORMAT_TYPE_PRECISION) { | ||
784 | if (spec->precision < 0) | ||
785 | spec->precision = 0; | ||
786 | |||
787 | spec->type = FORMAT_TYPE_NONE; | ||
788 | goto qualifier; | ||
789 | } | ||
790 | |||
791 | /* By default */ | ||
792 | spec->type = FORMAT_TYPE_NONE; | ||
793 | |||
794 | for (; *fmt ; ++fmt) { | ||
795 | if (*fmt == '%') | ||
796 | break; | ||
797 | } | ||
798 | |||
799 | /* Return the current non-format string */ | ||
800 | if (fmt != start || !*fmt) | ||
801 | return fmt - start; | ||
802 | |||
803 | /* Process flags */ | ||
804 | spec->flags = 0; | ||
805 | |||
806 | while (1) { /* this also skips first '%' */ | ||
807 | bool found = true; | ||
808 | |||
809 | ++fmt; | ||
810 | |||
811 | switch (*fmt) { | ||
812 | case '-': spec->flags |= LEFT; break; | ||
813 | case '+': spec->flags |= PLUS; break; | ||
814 | case ' ': spec->flags |= SPACE; break; | ||
815 | case '#': spec->flags |= SPECIAL; break; | ||
816 | case '0': spec->flags |= ZEROPAD; break; | ||
817 | default: found = false; | ||
818 | } | ||
819 | |||
820 | if (!found) | ||
821 | break; | ||
822 | } | ||
823 | |||
824 | /* get field width */ | ||
825 | spec->field_width = -1; | ||
826 | |||
827 | if (isdigit(*fmt)) | ||
828 | spec->field_width = skip_atoi(&fmt); | ||
829 | else if (*fmt == '*') { | ||
830 | /* it's the next argument */ | ||
831 | spec->type = FORMAT_TYPE_WIDTH; | ||
832 | return ++fmt - start; | ||
833 | } | ||
834 | |||
835 | precision: | ||
836 | /* get the precision */ | ||
837 | spec->precision = -1; | ||
838 | if (*fmt == '.') { | ||
839 | ++fmt; | ||
840 | if (isdigit(*fmt)) { | ||
841 | spec->precision = skip_atoi(&fmt); | ||
842 | if (spec->precision < 0) | ||
843 | spec->precision = 0; | ||
844 | } else if (*fmt == '*') { | ||
845 | /* it's the next argument */ | ||
846 | spec->type = FORMAT_TYPE_PRECISION; | ||
847 | return ++fmt - start; | ||
848 | } | ||
849 | } | ||
850 | |||
851 | qualifier: | ||
852 | /* get the conversion qualifier */ | ||
853 | spec->qualifier = -1; | ||
854 | if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || | ||
855 | *fmt == 'Z' || *fmt == 'z' || *fmt == 't') { | ||
856 | spec->qualifier = *fmt; | ||
857 | ++fmt; | ||
858 | if (spec->qualifier == 'l' && *fmt == 'l') { | ||
859 | spec->qualifier = 'L'; | ||
860 | ++fmt; | ||
861 | } | ||
862 | } | ||
863 | |||
864 | /* default base */ | ||
865 | spec->base = 10; | ||
866 | switch (*fmt) { | ||
867 | case 'c': | ||
868 | spec->type = FORMAT_TYPE_CHAR; | ||
869 | return ++fmt - start; | ||
870 | |||
871 | case 's': | ||
872 | spec->type = FORMAT_TYPE_STR; | ||
873 | return ++fmt - start; | ||
874 | |||
875 | case 'p': | ||
876 | spec->type = FORMAT_TYPE_PTR; | ||
877 | return fmt - start; | ||
878 | /* skip alnum */ | ||
879 | |||
880 | case 'n': | ||
881 | spec->type = FORMAT_TYPE_NRCHARS; | ||
882 | return ++fmt - start; | ||
883 | |||
884 | case '%': | ||
885 | spec->type = FORMAT_TYPE_PERCENT_CHAR; | ||
886 | return ++fmt - start; | ||
887 | |||
888 | /* integer number formats - set up the flags and "break" */ | ||
889 | case 'o': | ||
890 | spec->base = 8; | ||
693 | break; | 891 | break; |
892 | |||
893 | case 'x': | ||
894 | spec->flags |= SMALL; | ||
895 | |||
896 | case 'X': | ||
897 | spec->base = 16; | ||
898 | break; | ||
899 | |||
900 | case 'd': | ||
901 | case 'i': | ||
902 | spec->flags |= SIGN; | ||
903 | case 'u': | ||
904 | break; | ||
905 | |||
906 | default: | ||
907 | spec->type = FORMAT_TYPE_INVALID; | ||
908 | return fmt - start; | ||
694 | } | 909 | } |
695 | flags |= SMALL; | 910 | |
696 | if (field_width == -1) { | 911 | if (spec->qualifier == 'L') |
697 | field_width = 2*sizeof(void *); | 912 | spec->type = FORMAT_TYPE_LONG_LONG; |
698 | flags |= ZEROPAD; | 913 | else if (spec->qualifier == 'l') { |
914 | if (spec->flags & SIGN) | ||
915 | spec->type = FORMAT_TYPE_LONG; | ||
916 | else | ||
917 | spec->type = FORMAT_TYPE_ULONG; | ||
918 | } else if (spec->qualifier == 'Z' || spec->qualifier == 'z') { | ||
919 | spec->type = FORMAT_TYPE_SIZE_T; | ||
920 | } else if (spec->qualifier == 't') { | ||
921 | spec->type = FORMAT_TYPE_PTRDIFF; | ||
922 | } else if (spec->qualifier == 'h') { | ||
923 | if (spec->flags & SIGN) | ||
924 | spec->type = FORMAT_TYPE_SHORT; | ||
925 | else | ||
926 | spec->type = FORMAT_TYPE_USHORT; | ||
927 | } else { | ||
928 | if (spec->flags & SIGN) | ||
929 | spec->type = FORMAT_TYPE_INT; | ||
930 | else | ||
931 | spec->type = FORMAT_TYPE_UINT; | ||
699 | } | 932 | } |
700 | return number(buf, end, (unsigned long) ptr, 16, field_width, precision, flags); | 933 | |
934 | return ++fmt - start; | ||
701 | } | 935 | } |
702 | 936 | ||
703 | /** | 937 | /** |
@@ -726,18 +960,9 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field | |||
726 | int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) | 960 | int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) |
727 | { | 961 | { |
728 | unsigned long long num; | 962 | unsigned long long num; |
729 | int base; | ||
730 | char *str, *end, c; | 963 | char *str, *end, c; |
731 | 964 | int read; | |
732 | int flags; /* flags to number() */ | 965 | struct printf_spec spec = {0}; |
733 | |||
734 | int field_width; /* width of output field */ | ||
735 | int precision; /* min. # of digits for integers; max | ||
736 | number of chars for from string */ | ||
737 | int qualifier; /* 'h', 'l', or 'L' for integer fields */ | ||
738 | /* 'z' support added 23/7/1999 S.H. */ | ||
739 | /* 'z' changed to 'Z' --davidm 1/25/99 */ | ||
740 | /* 't' added for ptrdiff_t */ | ||
741 | 966 | ||
742 | /* Reject out-of-range values early. Large positive sizes are | 967 | /* Reject out-of-range values early. Large positive sizes are |
743 | used for unknown buffer sizes. */ | 968 | used for unknown buffer sizes. */ |
@@ -758,184 +983,144 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) | |||
758 | size = end - buf; | 983 | size = end - buf; |
759 | } | 984 | } |
760 | 985 | ||
761 | for (; *fmt ; ++fmt) { | 986 | while (*fmt) { |
762 | if (*fmt != '%') { | 987 | const char *old_fmt = fmt; |
763 | if (str < end) | ||
764 | *str = *fmt; | ||
765 | ++str; | ||
766 | continue; | ||
767 | } | ||
768 | 988 | ||
769 | /* process flags */ | 989 | read = format_decode(fmt, &spec); |
770 | flags = 0; | ||
771 | repeat: | ||
772 | ++fmt; /* this also skips first '%' */ | ||
773 | switch (*fmt) { | ||
774 | case '-': flags |= LEFT; goto repeat; | ||
775 | case '+': flags |= PLUS; goto repeat; | ||
776 | case ' ': flags |= SPACE; goto repeat; | ||
777 | case '#': flags |= SPECIAL; goto repeat; | ||
778 | case '0': flags |= ZEROPAD; goto repeat; | ||
779 | } | ||
780 | 990 | ||
781 | /* get field width */ | 991 | fmt += read; |
782 | field_width = -1; | ||
783 | if (isdigit(*fmt)) | ||
784 | field_width = skip_atoi(&fmt); | ||
785 | else if (*fmt == '*') { | ||
786 | ++fmt; | ||
787 | /* it's the next argument */ | ||
788 | field_width = va_arg(args, int); | ||
789 | if (field_width < 0) { | ||
790 | field_width = -field_width; | ||
791 | flags |= LEFT; | ||
792 | } | ||
793 | } | ||
794 | 992 | ||
795 | /* get the precision */ | 993 | switch (spec.type) { |
796 | precision = -1; | 994 | case FORMAT_TYPE_NONE: { |
797 | if (*fmt == '.') { | 995 | int copy = read; |
798 | ++fmt; | 996 | if (str < end) { |
799 | if (isdigit(*fmt)) | 997 | if (copy > end - str) |
800 | precision = skip_atoi(&fmt); | 998 | copy = end - str; |
801 | else if (*fmt == '*') { | 999 | memcpy(str, old_fmt, copy); |
802 | ++fmt; | ||
803 | /* it's the next argument */ | ||
804 | precision = va_arg(args, int); | ||
805 | } | 1000 | } |
806 | if (precision < 0) | 1001 | str += read; |
807 | precision = 0; | 1002 | break; |
808 | } | 1003 | } |
809 | 1004 | ||
810 | /* get the conversion qualifier */ | 1005 | case FORMAT_TYPE_WIDTH: |
811 | qualifier = -1; | 1006 | spec.field_width = va_arg(args, int); |
812 | if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || | 1007 | break; |
813 | *fmt =='Z' || *fmt == 'z' || *fmt == 't') { | ||
814 | qualifier = *fmt; | ||
815 | ++fmt; | ||
816 | if (qualifier == 'l' && *fmt == 'l') { | ||
817 | qualifier = 'L'; | ||
818 | ++fmt; | ||
819 | } | ||
820 | } | ||
821 | 1008 | ||
822 | /* default base */ | 1009 | case FORMAT_TYPE_PRECISION: |
823 | base = 10; | 1010 | spec.precision = va_arg(args, int); |
1011 | break; | ||
824 | 1012 | ||
825 | switch (*fmt) { | 1013 | case FORMAT_TYPE_CHAR: |
826 | case 'c': | 1014 | if (!(spec.flags & LEFT)) { |
827 | if (!(flags & LEFT)) { | 1015 | while (--spec.field_width > 0) { |
828 | while (--field_width > 0) { | ||
829 | if (str < end) | ||
830 | *str = ' '; | ||
831 | ++str; | ||
832 | } | ||
833 | } | ||
834 | c = (unsigned char) va_arg(args, int); | ||
835 | if (str < end) | ||
836 | *str = c; | ||
837 | ++str; | ||
838 | while (--field_width > 0) { | ||
839 | if (str < end) | 1016 | if (str < end) |
840 | *str = ' '; | 1017 | *str = ' '; |
841 | ++str; | 1018 | ++str; |
842 | } | ||
843 | continue; | ||
844 | |||
845 | case 's': | ||
846 | str = string(str, end, va_arg(args, char *), field_width, precision, flags); | ||
847 | continue; | ||
848 | |||
849 | case 'p': | ||
850 | str = pointer(fmt+1, str, end, | ||
851 | va_arg(args, void *), | ||
852 | field_width, precision, flags); | ||
853 | /* Skip all alphanumeric pointer suffixes */ | ||
854 | while (isalnum(fmt[1])) | ||
855 | fmt++; | ||
856 | continue; | ||
857 | |||
858 | case 'n': | ||
859 | /* FIXME: | ||
860 | * What does C99 say about the overflow case here? */ | ||
861 | if (qualifier == 'l') { | ||
862 | long * ip = va_arg(args, long *); | ||
863 | *ip = (str - buf); | ||
864 | } else if (qualifier == 'Z' || qualifier == 'z') { | ||
865 | size_t * ip = va_arg(args, size_t *); | ||
866 | *ip = (str - buf); | ||
867 | } else { | ||
868 | int * ip = va_arg(args, int *); | ||
869 | *ip = (str - buf); | ||
870 | } | ||
871 | continue; | ||
872 | 1019 | ||
873 | case '%': | 1020 | } |
1021 | } | ||
1022 | c = (unsigned char) va_arg(args, int); | ||
1023 | if (str < end) | ||
1024 | *str = c; | ||
1025 | ++str; | ||
1026 | while (--spec.field_width > 0) { | ||
874 | if (str < end) | 1027 | if (str < end) |
875 | *str = '%'; | 1028 | *str = ' '; |
876 | ++str; | 1029 | ++str; |
877 | continue; | 1030 | } |
1031 | break; | ||
878 | 1032 | ||
879 | /* integer number formats - set up the flags and "break" */ | 1033 | case FORMAT_TYPE_STR: |
880 | case 'o': | 1034 | str = string(str, end, va_arg(args, char *), spec); |
881 | base = 8; | 1035 | break; |
882 | break; | ||
883 | 1036 | ||
884 | case 'x': | 1037 | case FORMAT_TYPE_PTR: |
885 | flags |= SMALL; | 1038 | str = pointer(fmt+1, str, end, va_arg(args, void *), |
886 | case 'X': | 1039 | spec); |
887 | base = 16; | 1040 | while (isalnum(*fmt)) |
888 | break; | 1041 | fmt++; |
1042 | break; | ||
889 | 1043 | ||
890 | case 'd': | 1044 | case FORMAT_TYPE_PERCENT_CHAR: |
891 | case 'i': | 1045 | if (str < end) |
892 | flags |= SIGN; | 1046 | *str = '%'; |
893 | case 'u': | 1047 | ++str; |
894 | break; | 1048 | break; |
895 | 1049 | ||
896 | default: | 1050 | case FORMAT_TYPE_INVALID: |
1051 | if (str < end) | ||
1052 | *str = '%'; | ||
1053 | ++str; | ||
1054 | if (*fmt) { | ||
897 | if (str < end) | 1055 | if (str < end) |
898 | *str = '%'; | 1056 | *str = *fmt; |
899 | ++str; | 1057 | ++str; |
900 | if (*fmt) { | 1058 | } else { |
901 | if (str < end) | 1059 | --fmt; |
902 | *str = *fmt; | 1060 | } |
903 | ++str; | 1061 | break; |
904 | } else { | 1062 | |
905 | --fmt; | 1063 | case FORMAT_TYPE_NRCHARS: { |
906 | } | 1064 | int qualifier = spec.qualifier; |
907 | continue; | 1065 | |
1066 | if (qualifier == 'l') { | ||
1067 | long *ip = va_arg(args, long *); | ||
1068 | *ip = (str - buf); | ||
1069 | } else if (qualifier == 'Z' || | ||
1070 | qualifier == 'z') { | ||
1071 | size_t *ip = va_arg(args, size_t *); | ||
1072 | *ip = (str - buf); | ||
1073 | } else { | ||
1074 | int *ip = va_arg(args, int *); | ||
1075 | *ip = (str - buf); | ||
1076 | } | ||
1077 | break; | ||
908 | } | 1078 | } |
909 | if (qualifier == 'L') | 1079 | |
910 | num = va_arg(args, long long); | 1080 | default: |
911 | else if (qualifier == 'l') { | 1081 | switch (spec.type) { |
912 | num = va_arg(args, unsigned long); | 1082 | case FORMAT_TYPE_LONG_LONG: |
913 | if (flags & SIGN) | 1083 | num = va_arg(args, long long); |
914 | num = (signed long) num; | 1084 | break; |
915 | } else if (qualifier == 'Z' || qualifier == 'z') { | 1085 | case FORMAT_TYPE_ULONG: |
916 | num = va_arg(args, size_t); | 1086 | num = va_arg(args, unsigned long); |
917 | } else if (qualifier == 't') { | 1087 | break; |
918 | num = va_arg(args, ptrdiff_t); | 1088 | case FORMAT_TYPE_LONG: |
919 | } else if (qualifier == 'h') { | 1089 | num = va_arg(args, long); |
920 | num = (unsigned short) va_arg(args, int); | 1090 | break; |
921 | if (flags & SIGN) | 1091 | case FORMAT_TYPE_SIZE_T: |
922 | num = (signed short) num; | 1092 | num = va_arg(args, size_t); |
923 | } else { | 1093 | break; |
924 | num = va_arg(args, unsigned int); | 1094 | case FORMAT_TYPE_PTRDIFF: |
925 | if (flags & SIGN) | 1095 | num = va_arg(args, ptrdiff_t); |
926 | num = (signed int) num; | 1096 | break; |
1097 | case FORMAT_TYPE_USHORT: | ||
1098 | num = (unsigned short) va_arg(args, int); | ||
1099 | break; | ||
1100 | case FORMAT_TYPE_SHORT: | ||
1101 | num = (short) va_arg(args, int); | ||
1102 | break; | ||
1103 | case FORMAT_TYPE_INT: | ||
1104 | num = (int) va_arg(args, int); | ||
1105 | break; | ||
1106 | default: | ||
1107 | num = va_arg(args, unsigned int); | ||
1108 | } | ||
1109 | |||
1110 | str = number(str, end, num, spec); | ||
927 | } | 1111 | } |
928 | str = number(str, end, num, base, | ||
929 | field_width, precision, flags); | ||
930 | } | 1112 | } |
1113 | |||
931 | if (size > 0) { | 1114 | if (size > 0) { |
932 | if (str < end) | 1115 | if (str < end) |
933 | *str = '\0'; | 1116 | *str = '\0'; |
934 | else | 1117 | else |
935 | end[-1] = '\0'; | 1118 | end[-1] = '\0'; |
936 | } | 1119 | } |
1120 | |||
937 | /* the trailing null byte doesn't count towards the total */ | 1121 | /* the trailing null byte doesn't count towards the total */ |
938 | return str-buf; | 1122 | return str-buf; |
1123 | |||
939 | } | 1124 | } |
940 | EXPORT_SYMBOL(vsnprintf); | 1125 | EXPORT_SYMBOL(vsnprintf); |
941 | 1126 | ||
@@ -1058,6 +1243,372 @@ int sprintf(char * buf, const char *fmt, ...) | |||
1058 | } | 1243 | } |
1059 | EXPORT_SYMBOL(sprintf); | 1244 | EXPORT_SYMBOL(sprintf); |
1060 | 1245 | ||
1246 | #ifdef CONFIG_BINARY_PRINTF | ||
1247 | /* | ||
1248 | * bprintf service: | ||
1249 | * vbin_printf() - VA arguments to binary data | ||
1250 | * bstr_printf() - Binary data to text string | ||
1251 | */ | ||
1252 | |||
1253 | /** | ||
1254 | * vbin_printf - Parse a format string and place args' binary value in a buffer | ||
1255 | * @bin_buf: The buffer to place args' binary value | ||
1256 | * @size: The size of the buffer(by words(32bits), not characters) | ||
1257 | * @fmt: The format string to use | ||
1258 | * @args: Arguments for the format string | ||
1259 | * | ||
1260 | * The format follows C99 vsnprintf, except %n is ignored, and its argument | ||
1261 | * is skiped. | ||
1262 | * | ||
1263 | * The return value is the number of words(32bits) which would be generated for | ||
1264 | * the given input. | ||
1265 | * | ||
1266 | * NOTE: | ||
1267 | * If the return value is greater than @size, the resulting bin_buf is NOT | ||
1268 | * valid for bstr_printf(). | ||
1269 | */ | ||
1270 | int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args) | ||
1271 | { | ||
1272 | struct printf_spec spec = {0}; | ||
1273 | char *str, *end; | ||
1274 | int read; | ||
1275 | |||
1276 | str = (char *)bin_buf; | ||
1277 | end = (char *)(bin_buf + size); | ||
1278 | |||
1279 | #define save_arg(type) \ | ||
1280 | do { \ | ||
1281 | if (sizeof(type) == 8) { \ | ||
1282 | unsigned long long value; \ | ||
1283 | str = PTR_ALIGN(str, sizeof(u32)); \ | ||
1284 | value = va_arg(args, unsigned long long); \ | ||
1285 | if (str + sizeof(type) <= end) { \ | ||
1286 | *(u32 *)str = *(u32 *)&value; \ | ||
1287 | *(u32 *)(str + 4) = *((u32 *)&value + 1); \ | ||
1288 | } \ | ||
1289 | } else { \ | ||
1290 | unsigned long value; \ | ||
1291 | str = PTR_ALIGN(str, sizeof(type)); \ | ||
1292 | value = va_arg(args, int); \ | ||
1293 | if (str + sizeof(type) <= end) \ | ||
1294 | *(typeof(type) *)str = (type)value; \ | ||
1295 | } \ | ||
1296 | str += sizeof(type); \ | ||
1297 | } while (0) | ||
1298 | |||
1299 | |||
1300 | while (*fmt) { | ||
1301 | read = format_decode(fmt, &spec); | ||
1302 | |||
1303 | fmt += read; | ||
1304 | |||
1305 | switch (spec.type) { | ||
1306 | case FORMAT_TYPE_NONE: | ||
1307 | break; | ||
1308 | |||
1309 | case FORMAT_TYPE_WIDTH: | ||
1310 | case FORMAT_TYPE_PRECISION: | ||
1311 | save_arg(int); | ||
1312 | break; | ||
1313 | |||
1314 | case FORMAT_TYPE_CHAR: | ||
1315 | save_arg(char); | ||
1316 | break; | ||
1317 | |||
1318 | case FORMAT_TYPE_STR: { | ||
1319 | const char *save_str = va_arg(args, char *); | ||
1320 | size_t len; | ||
1321 | if ((unsigned long)save_str > (unsigned long)-PAGE_SIZE | ||
1322 | || (unsigned long)save_str < PAGE_SIZE) | ||
1323 | save_str = "<NULL>"; | ||
1324 | len = strlen(save_str); | ||
1325 | if (str + len + 1 < end) | ||
1326 | memcpy(str, save_str, len + 1); | ||
1327 | str += len + 1; | ||
1328 | break; | ||
1329 | } | ||
1330 | |||
1331 | case FORMAT_TYPE_PTR: | ||
1332 | save_arg(void *); | ||
1333 | /* skip all alphanumeric pointer suffixes */ | ||
1334 | while (isalnum(*fmt)) | ||
1335 | fmt++; | ||
1336 | break; | ||
1337 | |||
1338 | case FORMAT_TYPE_PERCENT_CHAR: | ||
1339 | break; | ||
1340 | |||
1341 | case FORMAT_TYPE_INVALID: | ||
1342 | if (!*fmt) | ||
1343 | --fmt; | ||
1344 | break; | ||
1345 | |||
1346 | case FORMAT_TYPE_NRCHARS: { | ||
1347 | /* skip %n 's argument */ | ||
1348 | int qualifier = spec.qualifier; | ||
1349 | void *skip_arg; | ||
1350 | if (qualifier == 'l') | ||
1351 | skip_arg = va_arg(args, long *); | ||
1352 | else if (qualifier == 'Z' || qualifier == 'z') | ||
1353 | skip_arg = va_arg(args, size_t *); | ||
1354 | else | ||
1355 | skip_arg = va_arg(args, int *); | ||
1356 | break; | ||
1357 | } | ||
1358 | |||
1359 | default: | ||
1360 | switch (spec.type) { | ||
1361 | |||
1362 | case FORMAT_TYPE_LONG_LONG: | ||
1363 | save_arg(long long); | ||
1364 | break; | ||
1365 | case FORMAT_TYPE_ULONG: | ||
1366 | case FORMAT_TYPE_LONG: | ||
1367 | save_arg(unsigned long); | ||
1368 | break; | ||
1369 | case FORMAT_TYPE_SIZE_T: | ||
1370 | save_arg(size_t); | ||
1371 | break; | ||
1372 | case FORMAT_TYPE_PTRDIFF: | ||
1373 | save_arg(ptrdiff_t); | ||
1374 | break; | ||
1375 | case FORMAT_TYPE_USHORT: | ||
1376 | case FORMAT_TYPE_SHORT: | ||
1377 | save_arg(short); | ||
1378 | break; | ||
1379 | default: | ||
1380 | save_arg(int); | ||
1381 | } | ||
1382 | } | ||
1383 | } | ||
1384 | return (u32 *)(PTR_ALIGN(str, sizeof(u32))) - bin_buf; | ||
1385 | |||
1386 | #undef save_arg | ||
1387 | } | ||
1388 | EXPORT_SYMBOL_GPL(vbin_printf); | ||
1389 | |||
1390 | /** | ||
1391 | * bstr_printf - Format a string from binary arguments and place it in a buffer | ||
1392 | * @buf: The buffer to place the result into | ||
1393 | * @size: The size of the buffer, including the trailing null space | ||
1394 | * @fmt: The format string to use | ||
1395 | * @bin_buf: Binary arguments for the format string | ||
1396 | * | ||
1397 | * This function like C99 vsnprintf, but the difference is that vsnprintf gets | ||
1398 | * arguments from stack, and bstr_printf gets arguments from @bin_buf which is | ||
1399 | * a binary buffer that generated by vbin_printf. | ||
1400 | * | ||
1401 | * The format follows C99 vsnprintf, but has some extensions: | ||
1402 | * %pS output the name of a text symbol | ||
1403 | * %pF output the name of a function pointer | ||
1404 | * %pR output the address range in a struct resource | ||
1405 | * %n is ignored | ||
1406 | * | ||
1407 | * The return value is the number of characters which would | ||
1408 | * be generated for the given input, excluding the trailing | ||
1409 | * '\0', as per ISO C99. If you want to have the exact | ||
1410 | * number of characters written into @buf as return value | ||
1411 | * (not including the trailing '\0'), use vscnprintf(). If the | ||
1412 | * return is greater than or equal to @size, the resulting | ||
1413 | * string is truncated. | ||
1414 | */ | ||
1415 | int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) | ||
1416 | { | ||
1417 | unsigned long long num; | ||
1418 | char *str, *end, c; | ||
1419 | const char *args = (const char *)bin_buf; | ||
1420 | |||
1421 | struct printf_spec spec = {0}; | ||
1422 | |||
1423 | if (unlikely((int) size < 0)) { | ||
1424 | /* There can be only one.. */ | ||
1425 | static char warn = 1; | ||
1426 | WARN_ON(warn); | ||
1427 | warn = 0; | ||
1428 | return 0; | ||
1429 | } | ||
1430 | |||
1431 | str = buf; | ||
1432 | end = buf + size; | ||
1433 | |||
1434 | #define get_arg(type) \ | ||
1435 | ({ \ | ||
1436 | typeof(type) value; \ | ||
1437 | if (sizeof(type) == 8) { \ | ||
1438 | args = PTR_ALIGN(args, sizeof(u32)); \ | ||
1439 | *(u32 *)&value = *(u32 *)args; \ | ||
1440 | *((u32 *)&value + 1) = *(u32 *)(args + 4); \ | ||
1441 | } else { \ | ||
1442 | args = PTR_ALIGN(args, sizeof(type)); \ | ||
1443 | value = *(typeof(type) *)args; \ | ||
1444 | } \ | ||
1445 | args += sizeof(type); \ | ||
1446 | value; \ | ||
1447 | }) | ||
1448 | |||
1449 | /* Make sure end is always >= buf */ | ||
1450 | if (end < buf) { | ||
1451 | end = ((void *)-1); | ||
1452 | size = end - buf; | ||
1453 | } | ||
1454 | |||
1455 | while (*fmt) { | ||
1456 | int read; | ||
1457 | const char *old_fmt = fmt; | ||
1458 | |||
1459 | read = format_decode(fmt, &spec); | ||
1460 | |||
1461 | fmt += read; | ||
1462 | |||
1463 | switch (spec.type) { | ||
1464 | case FORMAT_TYPE_NONE: { | ||
1465 | int copy = read; | ||
1466 | if (str < end) { | ||
1467 | if (copy > end - str) | ||
1468 | copy = end - str; | ||
1469 | memcpy(str, old_fmt, copy); | ||
1470 | } | ||
1471 | str += read; | ||
1472 | break; | ||
1473 | } | ||
1474 | |||
1475 | case FORMAT_TYPE_WIDTH: | ||
1476 | spec.field_width = get_arg(int); | ||
1477 | break; | ||
1478 | |||
1479 | case FORMAT_TYPE_PRECISION: | ||
1480 | spec.precision = get_arg(int); | ||
1481 | break; | ||
1482 | |||
1483 | case FORMAT_TYPE_CHAR: | ||
1484 | if (!(spec.flags & LEFT)) { | ||
1485 | while (--spec.field_width > 0) { | ||
1486 | if (str < end) | ||
1487 | *str = ' '; | ||
1488 | ++str; | ||
1489 | } | ||
1490 | } | ||
1491 | c = (unsigned char) get_arg(char); | ||
1492 | if (str < end) | ||
1493 | *str = c; | ||
1494 | ++str; | ||
1495 | while (--spec.field_width > 0) { | ||
1496 | if (str < end) | ||
1497 | *str = ' '; | ||
1498 | ++str; | ||
1499 | } | ||
1500 | break; | ||
1501 | |||
1502 | case FORMAT_TYPE_STR: { | ||
1503 | const char *str_arg = args; | ||
1504 | size_t len = strlen(str_arg); | ||
1505 | args += len + 1; | ||
1506 | str = string(str, end, (char *)str_arg, spec); | ||
1507 | break; | ||
1508 | } | ||
1509 | |||
1510 | case FORMAT_TYPE_PTR: | ||
1511 | str = pointer(fmt+1, str, end, get_arg(void *), spec); | ||
1512 | while (isalnum(*fmt)) | ||
1513 | fmt++; | ||
1514 | break; | ||
1515 | |||
1516 | case FORMAT_TYPE_PERCENT_CHAR: | ||
1517 | if (str < end) | ||
1518 | *str = '%'; | ||
1519 | ++str; | ||
1520 | break; | ||
1521 | |||
1522 | case FORMAT_TYPE_INVALID: | ||
1523 | if (str < end) | ||
1524 | *str = '%'; | ||
1525 | ++str; | ||
1526 | if (*fmt) { | ||
1527 | if (str < end) | ||
1528 | *str = *fmt; | ||
1529 | ++str; | ||
1530 | } else { | ||
1531 | --fmt; | ||
1532 | } | ||
1533 | break; | ||
1534 | |||
1535 | case FORMAT_TYPE_NRCHARS: | ||
1536 | /* skip */ | ||
1537 | break; | ||
1538 | |||
1539 | default: | ||
1540 | switch (spec.type) { | ||
1541 | |||
1542 | case FORMAT_TYPE_LONG_LONG: | ||
1543 | num = get_arg(long long); | ||
1544 | break; | ||
1545 | case FORMAT_TYPE_ULONG: | ||
1546 | num = get_arg(unsigned long); | ||
1547 | break; | ||
1548 | case FORMAT_TYPE_LONG: | ||
1549 | num = get_arg(unsigned long); | ||
1550 | break; | ||
1551 | case FORMAT_TYPE_SIZE_T: | ||
1552 | num = get_arg(size_t); | ||
1553 | break; | ||
1554 | case FORMAT_TYPE_PTRDIFF: | ||
1555 | num = get_arg(ptrdiff_t); | ||
1556 | break; | ||
1557 | case FORMAT_TYPE_USHORT: | ||
1558 | num = get_arg(unsigned short); | ||
1559 | break; | ||
1560 | case FORMAT_TYPE_SHORT: | ||
1561 | num = get_arg(short); | ||
1562 | break; | ||
1563 | case FORMAT_TYPE_UINT: | ||
1564 | num = get_arg(unsigned int); | ||
1565 | break; | ||
1566 | default: | ||
1567 | num = get_arg(int); | ||
1568 | } | ||
1569 | |||
1570 | str = number(str, end, num, spec); | ||
1571 | } | ||
1572 | } | ||
1573 | |||
1574 | if (size > 0) { | ||
1575 | if (str < end) | ||
1576 | *str = '\0'; | ||
1577 | else | ||
1578 | end[-1] = '\0'; | ||
1579 | } | ||
1580 | |||
1581 | #undef get_arg | ||
1582 | |||
1583 | /* the trailing null byte doesn't count towards the total */ | ||
1584 | return str - buf; | ||
1585 | } | ||
1586 | EXPORT_SYMBOL_GPL(bstr_printf); | ||
1587 | |||
1588 | /** | ||
1589 | * bprintf - Parse a format string and place args' binary value in a buffer | ||
1590 | * @bin_buf: The buffer to place args' binary value | ||
1591 | * @size: The size of the buffer(by words(32bits), not characters) | ||
1592 | * @fmt: The format string to use | ||
1593 | * @...: Arguments for the format string | ||
1594 | * | ||
1595 | * The function returns the number of words(u32) written | ||
1596 | * into @bin_buf. | ||
1597 | */ | ||
1598 | int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...) | ||
1599 | { | ||
1600 | va_list args; | ||
1601 | int ret; | ||
1602 | |||
1603 | va_start(args, fmt); | ||
1604 | ret = vbin_printf(bin_buf, size, fmt, args); | ||
1605 | va_end(args); | ||
1606 | return ret; | ||
1607 | } | ||
1608 | EXPORT_SYMBOL_GPL(bprintf); | ||
1609 | |||
1610 | #endif /* CONFIG_BINARY_PRINTF */ | ||
1611 | |||
1061 | /** | 1612 | /** |
1062 | * vsscanf - Unformat a buffer into a list of arguments | 1613 | * vsscanf - Unformat a buffer into a list of arguments |
1063 | * @buf: input buffer | 1614 | * @buf: input buffer |