diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-17 17:35:02 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-17 17:35:02 -0500 |
commit | e2b74f232e84dfccd0047eb47545b1d028df8ff1 (patch) | |
tree | 86dffe011c9b4049f2adfa7aa78ad92870c4dc9b | |
parent | 9cd77374f0a9cbb7ec35a9aaeb6473755afe0e3e (diff) | |
parent | 580c57f1076872ebc2427f898b927944ce170f2d (diff) |
Merge branch 'akpm' (patches from Andrew)
Merge yet more updates from Andrew Morton:
- a pile of minor fs fixes and cleanups
- kexec updates
- random misc fixes in various places: vmcore, rbtree, eventfd, ipc, seccomp.
- a series of python-based kgdb helper scripts
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (58 commits)
seccomp: cap SECCOMP_RET_ERRNO data to MAX_ERRNO
samples/seccomp: improve label helper
ipc,sem: use current->state helpers
scripts/gdb: disable pagination while printing from breakpoint handler
scripts/gdb: define maintainer
scripts/gdb: convert CpuList to generator function
scripts/gdb: convert ModuleList to generator function
scripts/gdb: use a generator instead of iterator for task list
scripts/gdb: ignore byte-compiled python files
scripts/gdb: port to python3 / gdb7.7
scripts/gdb: add basic documentation
scripts/gdb: add lx-lsmod command
scripts/gdb: add class to iterate over CPU masks
scripts/gdb: add lx_current convenience function
scripts/gdb: add internal helper and convenience function for per-cpu lookup
scripts/gdb: add get_gdbserver_type helper
scripts/gdb: add internal helper and convenience function to retrieve thread_info
scripts/gdb: add is_target_arch helper
scripts/gdb: add helper and convenience function to look up tasks
scripts/gdb: add task iteration class
...
43 files changed, 1185 insertions, 238 deletions
diff --git a/.gitignore b/.gitignore index 9ac91060ea64..acb6afe6b7a3 100644 --- a/.gitignore +++ b/.gitignore | |||
@@ -43,6 +43,7 @@ Module.symvers | |||
43 | /TAGS | 43 | /TAGS |
44 | /linux | 44 | /linux |
45 | /vmlinux | 45 | /vmlinux |
46 | /vmlinux-gdb.py | ||
46 | /vmlinuz | 47 | /vmlinuz |
47 | /System.map | 48 | /System.map |
48 | /Module.markers | 49 | /Module.markers |
diff --git a/Documentation/gdb-kernel-debugging.txt b/Documentation/gdb-kernel-debugging.txt new file mode 100644 index 000000000000..7050ce8794b9 --- /dev/null +++ b/Documentation/gdb-kernel-debugging.txt | |||
@@ -0,0 +1,160 @@ | |||
1 | Debugging kernel and modules via gdb | ||
2 | ==================================== | ||
3 | |||
4 | The kernel debugger kgdb, hypervisors like QEMU or JTAG-based hardware | ||
5 | interfaces allow to debug the Linux kernel and its modules during runtime | ||
6 | using gdb. Gdb comes with a powerful scripting interface for python. The | ||
7 | kernel provides a collection of helper scripts that can simplify typical | ||
8 | kernel debugging steps. This is a short tutorial about how to enable and use | ||
9 | them. It focuses on QEMU/KVM virtual machines as target, but the examples can | ||
10 | be transferred to the other gdb stubs as well. | ||
11 | |||
12 | |||
13 | Requirements | ||
14 | ------------ | ||
15 | |||
16 | o gdb 7.2+ (recommended: 7.4+) with python support enabled (typically true | ||
17 | for distributions) | ||
18 | |||
19 | |||
20 | Setup | ||
21 | ----- | ||
22 | |||
23 | o Create a virtual Linux machine for QEMU/KVM (see www.linux-kvm.org and | ||
24 | www.qemu.org for more details). For cross-development, | ||
25 | http://landley.net/aboriginal/bin keeps a pool of machine images and | ||
26 | toolchains that can be helpful to start from. | ||
27 | |||
28 | o Build the kernel with CONFIG_GDB_SCRIPTS enabled, but leave | ||
29 | CONFIG_DEBUG_INFO_REDUCED off. If your architecture supports | ||
30 | CONFIG_FRAME_POINTER, keep it enabled. | ||
31 | |||
32 | o Install that kernel on the guest. | ||
33 | |||
34 | Alternatively, QEMU allows to boot the kernel directly using -kernel, | ||
35 | -append, -initrd command line switches. This is generally only useful if | ||
36 | you do not depend on modules. See QEMU documentation for more details on | ||
37 | this mode. | ||
38 | |||
39 | o Enable the gdb stub of QEMU/KVM, either | ||
40 | - at VM startup time by appending "-s" to the QEMU command line | ||
41 | or | ||
42 | - during runtime by issuing "gdbserver" from the QEMU monitor | ||
43 | console | ||
44 | |||
45 | o cd /path/to/linux-build | ||
46 | |||
47 | o Start gdb: gdb vmlinux | ||
48 | |||
49 | Note: Some distros may restrict auto-loading of gdb scripts to known safe | ||
50 | directories. In case gdb reports to refuse loading vmlinux-gdb.py, add | ||
51 | |||
52 | add-auto-load-safe-path /path/to/linux-build | ||
53 | |||
54 | to ~/.gdbinit. See gdb help for more details. | ||
55 | |||
56 | o Attach to the booted guest: | ||
57 | (gdb) target remote :1234 | ||
58 | |||
59 | |||
60 | Examples of using the Linux-provided gdb helpers | ||
61 | ------------------------------------------------ | ||
62 | |||
63 | o Load module (and main kernel) symbols: | ||
64 | (gdb) lx-symbols | ||
65 | loading vmlinux | ||
66 | scanning for modules in /home/user/linux/build | ||
67 | loading @0xffffffffa0020000: /home/user/linux/build/net/netfilter/xt_tcpudp.ko | ||
68 | loading @0xffffffffa0016000: /home/user/linux/build/net/netfilter/xt_pkttype.ko | ||
69 | loading @0xffffffffa0002000: /home/user/linux/build/net/netfilter/xt_limit.ko | ||
70 | loading @0xffffffffa00ca000: /home/user/linux/build/net/packet/af_packet.ko | ||
71 | loading @0xffffffffa003c000: /home/user/linux/build/fs/fuse/fuse.ko | ||
72 | ... | ||
73 | loading @0xffffffffa0000000: /home/user/linux/build/drivers/ata/ata_generic.ko | ||
74 | |||
75 | o Set a breakpoint on some not yet loaded module function, e.g.: | ||
76 | (gdb) b btrfs_init_sysfs | ||
77 | Function "btrfs_init_sysfs" not defined. | ||
78 | Make breakpoint pending on future shared library load? (y or [n]) y | ||
79 | Breakpoint 1 (btrfs_init_sysfs) pending. | ||
80 | |||
81 | o Continue the target | ||
82 | (gdb) c | ||
83 | |||
84 | o Load the module on the target and watch the symbols being loaded as well as | ||
85 | the breakpoint hit: | ||
86 | loading @0xffffffffa0034000: /home/user/linux/build/lib/libcrc32c.ko | ||
87 | loading @0xffffffffa0050000: /home/user/linux/build/lib/lzo/lzo_compress.ko | ||
88 | loading @0xffffffffa006e000: /home/user/linux/build/lib/zlib_deflate/zlib_deflate.ko | ||
89 | loading @0xffffffffa01b1000: /home/user/linux/build/fs/btrfs/btrfs.ko | ||
90 | |||
91 | Breakpoint 1, btrfs_init_sysfs () at /home/user/linux/fs/btrfs/sysfs.c:36 | ||
92 | 36 btrfs_kset = kset_create_and_add("btrfs", NULL, fs_kobj); | ||
93 | |||
94 | o Dump the log buffer of the target kernel: | ||
95 | (gdb) lx-dmesg | ||
96 | [ 0.000000] Initializing cgroup subsys cpuset | ||
97 | [ 0.000000] Initializing cgroup subsys cpu | ||
98 | [ 0.000000] Linux version 3.8.0-rc4-dbg+ (... | ||
99 | [ 0.000000] Command line: root=/dev/sda2 resume=/dev/sda1 vga=0x314 | ||
100 | [ 0.000000] e820: BIOS-provided physical RAM map: | ||
101 | [ 0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable | ||
102 | [ 0.000000] BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved | ||
103 | .... | ||
104 | |||
105 | o Examine fields of the current task struct: | ||
106 | (gdb) p $lx_current().pid | ||
107 | $1 = 4998 | ||
108 | (gdb) p $lx_current().comm | ||
109 | $2 = "modprobe\000\000\000\000\000\000\000" | ||
110 | |||
111 | o Make use of the per-cpu function for the current or a specified CPU: | ||
112 | (gdb) p $lx_per_cpu("runqueues").nr_running | ||
113 | $3 = 1 | ||
114 | (gdb) p $lx_per_cpu("runqueues", 2).nr_running | ||
115 | $4 = 0 | ||
116 | |||
117 | o Dig into hrtimers using the container_of helper: | ||
118 | (gdb) set $next = $lx_per_cpu("hrtimer_bases").clock_base[0].active.next | ||
119 | (gdb) p *$container_of($next, "struct hrtimer", "node") | ||
120 | $5 = { | ||
121 | node = { | ||
122 | node = { | ||
123 | __rb_parent_color = 18446612133355256072, | ||
124 | rb_right = 0x0 <irq_stack_union>, | ||
125 | rb_left = 0x0 <irq_stack_union> | ||
126 | }, | ||
127 | expires = { | ||
128 | tv64 = 1835268000000 | ||
129 | } | ||
130 | }, | ||
131 | _softexpires = { | ||
132 | tv64 = 1835268000000 | ||
133 | }, | ||
134 | function = 0xffffffff81078232 <tick_sched_timer>, | ||
135 | base = 0xffff88003fd0d6f0, | ||
136 | state = 1, | ||
137 | start_pid = 0, | ||
138 | start_site = 0xffffffff81055c1f <hrtimer_start_range_ns+20>, | ||
139 | start_comm = "swapper/2\000\000\000\000\000\000" | ||
140 | } | ||
141 | |||
142 | |||
143 | List of commands and functions | ||
144 | ------------------------------ | ||
145 | |||
146 | The number of commands and convenience functions may evolve over the time, | ||
147 | this is just a snapshot of the initial version: | ||
148 | |||
149 | (gdb) apropos lx | ||
150 | function lx_current -- Return current task | ||
151 | function lx_module -- Find module by name and return the module variable | ||
152 | function lx_per_cpu -- Return per-cpu variable | ||
153 | function lx_task_by_pid -- Find Linux task by PID and return the task_struct variable | ||
154 | function lx_thread_info -- Calculate Linux thread_info from task variable | ||
155 | lx-dmesg -- Print Linux kernel log buffer | ||
156 | lx-lsmod -- List currently loaded modules | ||
157 | lx-symbols -- (Re-)load symbols of Linux kernel and currently loaded modules | ||
158 | |||
159 | Detailed help can be obtained via "help <command-name>" for commands and "help | ||
160 | function <function-name>" for convenience functions. | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 3eee4c7739ae..0597c5b3c4ee 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -4232,6 +4232,11 @@ W: http://www.icp-vortex.com/ | |||
4232 | S: Supported | 4232 | S: Supported |
4233 | F: drivers/scsi/gdt* | 4233 | F: drivers/scsi/gdt* |
4234 | 4234 | ||
4235 | GDB KERNEL DEBUGGING HELPER SCRIPTS | ||
4236 | M: Jan Kiszka <jan.kiszka@siemens.com> | ||
4237 | S: Supported | ||
4238 | F: scripts/gdb/ | ||
4239 | |||
4235 | GEMTEK FM RADIO RECEIVER DRIVER | 4240 | GEMTEK FM RADIO RECEIVER DRIVER |
4236 | M: Hans Verkuil <hverkuil@xs4all.nl> | 4241 | M: Hans Verkuil <hverkuil@xs4all.nl> |
4237 | L: linux-media@vger.kernel.org | 4242 | L: linux-media@vger.kernel.org |
@@ -927,6 +927,9 @@ endif | |||
927 | ifdef CONFIG_BUILD_DOCSRC | 927 | ifdef CONFIG_BUILD_DOCSRC |
928 | $(Q)$(MAKE) $(build)=Documentation | 928 | $(Q)$(MAKE) $(build)=Documentation |
929 | endif | 929 | endif |
930 | ifdef CONFIG_GDB_SCRIPTS | ||
931 | $(Q)ln -fsn `cd $(srctree) && /bin/pwd`/scripts/gdb/vmlinux-gdb.py | ||
932 | endif | ||
930 | +$(call if_changed,link-vmlinux) | 933 | +$(call if_changed,link-vmlinux) |
931 | 934 | ||
932 | # The actual objects are generated when descending, | 935 | # The actual objects are generated when descending, |
@@ -1181,7 +1184,7 @@ MRPROPER_FILES += .config .config.old .version .old_version $(version_h) \ | |||
1181 | Module.symvers tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS \ | 1184 | Module.symvers tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS \ |
1182 | signing_key.priv signing_key.x509 x509.genkey \ | 1185 | signing_key.priv signing_key.x509 x509.genkey \ |
1183 | extra_certificates signing_key.x509.keyid \ | 1186 | extra_certificates signing_key.x509.keyid \ |
1184 | signing_key.x509.signer | 1187 | signing_key.x509.signer vmlinux-gdb.py |
1185 | 1188 | ||
1186 | # clean - Delete most, but leave enough to build external modules | 1189 | # clean - Delete most, but leave enough to build external modules |
1187 | # | 1190 | # |
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index f96d1ec24189..1a74446fd9e5 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c | |||
@@ -96,8 +96,6 @@ int default_machine_kexec_prepare(struct kimage *image) | |||
96 | return 0; | 96 | return 0; |
97 | } | 97 | } |
98 | 98 | ||
99 | #define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE) | ||
100 | |||
101 | static void copy_segments(unsigned long ind) | 99 | static void copy_segments(unsigned long ind) |
102 | { | 100 | { |
103 | unsigned long entry; | 101 | unsigned long entry; |
diff --git a/fs/affs/affs.h b/fs/affs/affs.h index ff44ff3ff015..c8764bd7497d 100644 --- a/fs/affs/affs.h +++ b/fs/affs/affs.h | |||
@@ -30,6 +30,8 @@ | |||
30 | #define AFFS_AC_SIZE (AFFS_CACHE_SIZE/sizeof(struct affs_ext_key)/2) | 30 | #define AFFS_AC_SIZE (AFFS_CACHE_SIZE/sizeof(struct affs_ext_key)/2) |
31 | #define AFFS_AC_MASK (AFFS_AC_SIZE-1) | 31 | #define AFFS_AC_MASK (AFFS_AC_SIZE-1) |
32 | 32 | ||
33 | #define AFFSNAMEMAX 30U | ||
34 | |||
33 | struct affs_ext_key { | 35 | struct affs_ext_key { |
34 | u32 ext; /* idx of the extended block */ | 36 | u32 ext; /* idx of the extended block */ |
35 | u32 key; /* block number */ | 37 | u32 key; /* block number */ |
diff --git a/fs/affs/amigaffs.c b/fs/affs/amigaffs.c index c852f2fa1710..388da1ea815d 100644 --- a/fs/affs/amigaffs.c +++ b/fs/affs/amigaffs.c | |||
@@ -30,7 +30,7 @@ affs_insert_hash(struct inode *dir, struct buffer_head *bh) | |||
30 | ino = bh->b_blocknr; | 30 | ino = bh->b_blocknr; |
31 | offset = affs_hash_name(sb, AFFS_TAIL(sb, bh)->name + 1, AFFS_TAIL(sb, bh)->name[0]); | 31 | offset = affs_hash_name(sb, AFFS_TAIL(sb, bh)->name + 1, AFFS_TAIL(sb, bh)->name[0]); |
32 | 32 | ||
33 | pr_debug("%s(dir=%u, ino=%d)\n", __func__, (u32)dir->i_ino, ino); | 33 | pr_debug("%s(dir=%lu, ino=%d)\n", __func__, dir->i_ino, ino); |
34 | 34 | ||
35 | dir_bh = affs_bread(sb, dir->i_ino); | 35 | dir_bh = affs_bread(sb, dir->i_ino); |
36 | if (!dir_bh) | 36 | if (!dir_bh) |
@@ -80,8 +80,8 @@ affs_remove_hash(struct inode *dir, struct buffer_head *rem_bh) | |||
80 | sb = dir->i_sb; | 80 | sb = dir->i_sb; |
81 | rem_ino = rem_bh->b_blocknr; | 81 | rem_ino = rem_bh->b_blocknr; |
82 | offset = affs_hash_name(sb, AFFS_TAIL(sb, rem_bh)->name+1, AFFS_TAIL(sb, rem_bh)->name[0]); | 82 | offset = affs_hash_name(sb, AFFS_TAIL(sb, rem_bh)->name+1, AFFS_TAIL(sb, rem_bh)->name[0]); |
83 | pr_debug("%s(dir=%d, ino=%d, hashval=%d)\n", | 83 | pr_debug("%s(dir=%lu, ino=%d, hashval=%d)\n", __func__, dir->i_ino, |
84 | __func__, (u32)dir->i_ino, rem_ino, offset); | 84 | rem_ino, offset); |
85 | 85 | ||
86 | bh = affs_bread(sb, dir->i_ino); | 86 | bh = affs_bread(sb, dir->i_ino); |
87 | if (!bh) | 87 | if (!bh) |
@@ -483,11 +483,10 @@ affs_check_name(const unsigned char *name, int len, bool notruncate) | |||
483 | { | 483 | { |
484 | int i; | 484 | int i; |
485 | 485 | ||
486 | if (len > 30) { | 486 | if (len > AFFSNAMEMAX) { |
487 | if (notruncate) | 487 | if (notruncate) |
488 | return -ENAMETOOLONG; | 488 | return -ENAMETOOLONG; |
489 | else | 489 | len = AFFSNAMEMAX; |
490 | len = 30; | ||
491 | } | 490 | } |
492 | for (i = 0; i < len; i++) { | 491 | for (i = 0; i < len; i++) { |
493 | if (name[i] < ' ' || name[i] == ':' | 492 | if (name[i] < ' ' || name[i] == ':' |
@@ -508,7 +507,7 @@ affs_check_name(const unsigned char *name, int len, bool notruncate) | |||
508 | int | 507 | int |
509 | affs_copy_name(unsigned char *bstr, struct dentry *dentry) | 508 | affs_copy_name(unsigned char *bstr, struct dentry *dentry) |
510 | { | 509 | { |
511 | int len = min(dentry->d_name.len, 30u); | 510 | u32 len = min(dentry->d_name.len, AFFSNAMEMAX); |
512 | 511 | ||
513 | *bstr++ = len; | 512 | *bstr++ = len; |
514 | memcpy(bstr, dentry->d_name.name, len); | 513 | memcpy(bstr, dentry->d_name.name, len); |
diff --git a/fs/affs/bitmap.c b/fs/affs/bitmap.c index c8de51185c23..675148950fed 100644 --- a/fs/affs/bitmap.c +++ b/fs/affs/bitmap.c | |||
@@ -99,7 +99,6 @@ err_bh_read: | |||
99 | 99 | ||
100 | err_range: | 100 | err_range: |
101 | affs_error(sb, "affs_free_block","Block %u outside partition", block); | 101 | affs_error(sb, "affs_free_block","Block %u outside partition", block); |
102 | return; | ||
103 | } | 102 | } |
104 | 103 | ||
105 | /* | 104 | /* |
diff --git a/fs/affs/dir.c b/fs/affs/dir.c index 59f07bec92a6..ac4f318aafba 100644 --- a/fs/affs/dir.c +++ b/fs/affs/dir.c | |||
@@ -54,8 +54,7 @@ affs_readdir(struct file *file, struct dir_context *ctx) | |||
54 | u32 ino; | 54 | u32 ino; |
55 | int error = 0; | 55 | int error = 0; |
56 | 56 | ||
57 | pr_debug("%s(ino=%lu,f_pos=%lx)\n", | 57 | pr_debug("%s(ino=%lu,f_pos=%llx)\n", __func__, inode->i_ino, ctx->pos); |
58 | __func__, inode->i_ino, (unsigned long)ctx->pos); | ||
59 | 58 | ||
60 | if (ctx->pos < 2) { | 59 | if (ctx->pos < 2) { |
61 | file->private_data = (void *)0; | 60 | file->private_data = (void *)0; |
@@ -115,11 +114,11 @@ inside: | |||
115 | break; | 114 | break; |
116 | } | 115 | } |
117 | 116 | ||
118 | namelen = min(AFFS_TAIL(sb, fh_bh)->name[0], (u8)30); | 117 | namelen = min(AFFS_TAIL(sb, fh_bh)->name[0], |
118 | (u8)AFFSNAMEMAX); | ||
119 | name = AFFS_TAIL(sb, fh_bh)->name + 1; | 119 | name = AFFS_TAIL(sb, fh_bh)->name + 1; |
120 | pr_debug("readdir(): dir_emit(\"%.*s\", " | 120 | pr_debug("readdir(): dir_emit(\"%.*s\", ino=%u), hash=%d, f_pos=%llx\n", |
121 | "ino=%u), hash=%d, f_pos=%x\n", | 121 | namelen, name, ino, hash_pos, ctx->pos); |
122 | namelen, name, ino, hash_pos, (u32)ctx->pos); | ||
123 | 122 | ||
124 | if (!dir_emit(ctx, name, namelen, ino, DT_UNKNOWN)) | 123 | if (!dir_emit(ctx, name, namelen, ino, DT_UNKNOWN)) |
125 | goto done; | 124 | goto done; |
diff --git a/fs/affs/file.c b/fs/affs/file.c index 8faa6593ca6d..d2468bf95669 100644 --- a/fs/affs/file.c +++ b/fs/affs/file.c | |||
@@ -180,8 +180,7 @@ affs_get_extblock_slow(struct inode *inode, u32 ext) | |||
180 | ext_key = be32_to_cpu(AFFS_TAIL(sb, bh)->extension); | 180 | ext_key = be32_to_cpu(AFFS_TAIL(sb, bh)->extension); |
181 | if (ext < AFFS_I(inode)->i_extcnt) | 181 | if (ext < AFFS_I(inode)->i_extcnt) |
182 | goto read_ext; | 182 | goto read_ext; |
183 | if (ext > AFFS_I(inode)->i_extcnt) | 183 | BUG_ON(ext > AFFS_I(inode)->i_extcnt); |
184 | BUG(); | ||
185 | bh = affs_alloc_extblock(inode, bh, ext); | 184 | bh = affs_alloc_extblock(inode, bh, ext); |
186 | if (IS_ERR(bh)) | 185 | if (IS_ERR(bh)) |
187 | return bh; | 186 | return bh; |
@@ -198,8 +197,7 @@ affs_get_extblock_slow(struct inode *inode, u32 ext) | |||
198 | struct buffer_head *prev_bh; | 197 | struct buffer_head *prev_bh; |
199 | 198 | ||
200 | /* allocate a new extended block */ | 199 | /* allocate a new extended block */ |
201 | if (ext > AFFS_I(inode)->i_extcnt) | 200 | BUG_ON(ext > AFFS_I(inode)->i_extcnt); |
202 | BUG(); | ||
203 | 201 | ||
204 | /* get previous extended block */ | 202 | /* get previous extended block */ |
205 | prev_bh = affs_get_extblock(inode, ext - 1); | 203 | prev_bh = affs_get_extblock(inode, ext - 1); |
@@ -299,8 +297,8 @@ affs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_resul | |||
299 | struct buffer_head *ext_bh; | 297 | struct buffer_head *ext_bh; |
300 | u32 ext; | 298 | u32 ext; |
301 | 299 | ||
302 | pr_debug("%s(%u, %lu)\n", | 300 | pr_debug("%s(%lu, %llu)\n", __func__, inode->i_ino, |
303 | __func__, (u32)inode->i_ino, (unsigned long)block); | 301 | (unsigned long long)block); |
304 | 302 | ||
305 | BUG_ON(block > (sector_t)0x7fffffffUL); | 303 | BUG_ON(block > (sector_t)0x7fffffffUL); |
306 | 304 | ||
@@ -330,8 +328,9 @@ affs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_resul | |||
330 | 328 | ||
331 | /* store new block */ | 329 | /* store new block */ |
332 | if (bh_result->b_blocknr) | 330 | if (bh_result->b_blocknr) |
333 | affs_warning(sb, "get_block", "block already set (%lx)", | 331 | affs_warning(sb, "get_block", |
334 | (unsigned long)bh_result->b_blocknr); | 332 | "block already set (%llx)", |
333 | (unsigned long long)bh_result->b_blocknr); | ||
335 | AFFS_BLOCK(sb, ext_bh, block) = cpu_to_be32(blocknr); | 334 | AFFS_BLOCK(sb, ext_bh, block) = cpu_to_be32(blocknr); |
336 | AFFS_HEAD(ext_bh)->block_count = cpu_to_be32(block + 1); | 335 | AFFS_HEAD(ext_bh)->block_count = cpu_to_be32(block + 1); |
337 | affs_adjust_checksum(ext_bh, blocknr - bh_result->b_blocknr + 1); | 336 | affs_adjust_checksum(ext_bh, blocknr - bh_result->b_blocknr + 1); |
@@ -353,8 +352,8 @@ affs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_resul | |||
353 | return 0; | 352 | return 0; |
354 | 353 | ||
355 | err_big: | 354 | err_big: |
356 | affs_error(inode->i_sb, "get_block", "strange block request %d", | 355 | affs_error(inode->i_sb, "get_block", "strange block request %llu", |
357 | (int)block); | 356 | (unsigned long long)block); |
358 | return -EIO; | 357 | return -EIO; |
359 | err_ext: | 358 | err_ext: |
360 | // unlock cache | 359 | // unlock cache |
@@ -399,6 +398,13 @@ affs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, | |||
399 | size_t count = iov_iter_count(iter); | 398 | size_t count = iov_iter_count(iter); |
400 | ssize_t ret; | 399 | ssize_t ret; |
401 | 400 | ||
401 | if (rw == WRITE) { | ||
402 | loff_t size = offset + count; | ||
403 | |||
404 | if (AFFS_I(inode)->mmu_private < size) | ||
405 | return 0; | ||
406 | } | ||
407 | |||
402 | ret = blockdev_direct_IO(rw, iocb, inode, iter, offset, affs_get_block); | 408 | ret = blockdev_direct_IO(rw, iocb, inode, iter, offset, affs_get_block); |
403 | if (ret < 0 && (rw & WRITE)) | 409 | if (ret < 0 && (rw & WRITE)) |
404 | affs_write_failed(mapping, offset + count); | 410 | affs_write_failed(mapping, offset + count); |
@@ -503,7 +509,7 @@ affs_do_readpage_ofs(struct page *page, unsigned to) | |||
503 | u32 bidx, boff, bsize; | 509 | u32 bidx, boff, bsize; |
504 | u32 tmp; | 510 | u32 tmp; |
505 | 511 | ||
506 | pr_debug("%s(%u, %ld, 0, %d)\n", __func__, (u32)inode->i_ino, | 512 | pr_debug("%s(%lu, %ld, 0, %d)\n", __func__, inode->i_ino, |
507 | page->index, to); | 513 | page->index, to); |
508 | BUG_ON(to > PAGE_CACHE_SIZE); | 514 | BUG_ON(to > PAGE_CACHE_SIZE); |
509 | kmap(page); | 515 | kmap(page); |
@@ -539,7 +545,7 @@ affs_extent_file_ofs(struct inode *inode, u32 newsize) | |||
539 | u32 size, bsize; | 545 | u32 size, bsize; |
540 | u32 tmp; | 546 | u32 tmp; |
541 | 547 | ||
542 | pr_debug("%s(%u, %d)\n", __func__, (u32)inode->i_ino, newsize); | 548 | pr_debug("%s(%lu, %d)\n", __func__, inode->i_ino, newsize); |
543 | bsize = AFFS_SB(sb)->s_data_blksize; | 549 | bsize = AFFS_SB(sb)->s_data_blksize; |
544 | bh = NULL; | 550 | bh = NULL; |
545 | size = AFFS_I(inode)->mmu_private; | 551 | size = AFFS_I(inode)->mmu_private; |
@@ -608,7 +614,7 @@ affs_readpage_ofs(struct file *file, struct page *page) | |||
608 | u32 to; | 614 | u32 to; |
609 | int err; | 615 | int err; |
610 | 616 | ||
611 | pr_debug("%s(%u, %ld)\n", __func__, (u32)inode->i_ino, page->index); | 617 | pr_debug("%s(%lu, %ld)\n", __func__, inode->i_ino, page->index); |
612 | to = PAGE_CACHE_SIZE; | 618 | to = PAGE_CACHE_SIZE; |
613 | if (((page->index + 1) << PAGE_CACHE_SHIFT) > inode->i_size) { | 619 | if (((page->index + 1) << PAGE_CACHE_SHIFT) > inode->i_size) { |
614 | to = inode->i_size & ~PAGE_CACHE_MASK; | 620 | to = inode->i_size & ~PAGE_CACHE_MASK; |
@@ -631,8 +637,8 @@ static int affs_write_begin_ofs(struct file *file, struct address_space *mapping | |||
631 | pgoff_t index; | 637 | pgoff_t index; |
632 | int err = 0; | 638 | int err = 0; |
633 | 639 | ||
634 | pr_debug("%s(%u, %llu, %llu)\n", __func__, (u32)inode->i_ino, | 640 | pr_debug("%s(%lu, %llu, %llu)\n", __func__, inode->i_ino, pos, |
635 | (unsigned long long)pos, (unsigned long long)pos + len); | 641 | pos + len); |
636 | if (pos > AFFS_I(inode)->mmu_private) { | 642 | if (pos > AFFS_I(inode)->mmu_private) { |
637 | /* XXX: this probably leaves a too-big i_size in case of | 643 | /* XXX: this probably leaves a too-big i_size in case of |
638 | * failure. Should really be updating i_size at write_end time | 644 | * failure. Should really be updating i_size at write_end time |
@@ -681,9 +687,8 @@ static int affs_write_end_ofs(struct file *file, struct address_space *mapping, | |||
681 | * due to write_begin. | 687 | * due to write_begin. |
682 | */ | 688 | */ |
683 | 689 | ||
684 | pr_debug("%s(%u, %llu, %llu)\n", | 690 | pr_debug("%s(%lu, %llu, %llu)\n", __func__, inode->i_ino, pos, |
685 | __func__, (u32)inode->i_ino, (unsigned long long)pos, | 691 | pos + len); |
686 | (unsigned long long)pos + len); | ||
687 | bsize = AFFS_SB(sb)->s_data_blksize; | 692 | bsize = AFFS_SB(sb)->s_data_blksize; |
688 | data = page_address(page); | 693 | data = page_address(page); |
689 | 694 | ||
@@ -831,8 +836,8 @@ affs_truncate(struct inode *inode) | |||
831 | struct buffer_head *ext_bh; | 836 | struct buffer_head *ext_bh; |
832 | int i; | 837 | int i; |
833 | 838 | ||
834 | pr_debug("truncate(inode=%d, oldsize=%u, newsize=%u)\n", | 839 | pr_debug("truncate(inode=%lu, oldsize=%llu, newsize=%llu)\n", |
835 | (u32)inode->i_ino, (u32)AFFS_I(inode)->mmu_private, (u32)inode->i_size); | 840 | inode->i_ino, AFFS_I(inode)->mmu_private, inode->i_size); |
836 | 841 | ||
837 | last_blk = 0; | 842 | last_blk = 0; |
838 | ext = 0; | 843 | ext = 0; |
@@ -863,7 +868,7 @@ affs_truncate(struct inode *inode) | |||
863 | if (IS_ERR(ext_bh)) { | 868 | if (IS_ERR(ext_bh)) { |
864 | affs_warning(sb, "truncate", | 869 | affs_warning(sb, "truncate", |
865 | "unexpected read error for ext block %u (%ld)", | 870 | "unexpected read error for ext block %u (%ld)", |
866 | (unsigned int)ext, PTR_ERR(ext_bh)); | 871 | ext, PTR_ERR(ext_bh)); |
867 | return; | 872 | return; |
868 | } | 873 | } |
869 | if (AFFS_I(inode)->i_lc) { | 874 | if (AFFS_I(inode)->i_lc) { |
@@ -911,7 +916,7 @@ affs_truncate(struct inode *inode) | |||
911 | if (IS_ERR(bh)) { | 916 | if (IS_ERR(bh)) { |
912 | affs_warning(sb, "truncate", | 917 | affs_warning(sb, "truncate", |
913 | "unexpected read error for last block %u (%ld)", | 918 | "unexpected read error for last block %u (%ld)", |
914 | (unsigned int)ext, PTR_ERR(bh)); | 919 | ext, PTR_ERR(bh)); |
915 | return; | 920 | return; |
916 | } | 921 | } |
917 | tmp = be32_to_cpu(AFFS_DATA_HEAD(bh)->next); | 922 | tmp = be32_to_cpu(AFFS_DATA_HEAD(bh)->next); |
diff --git a/fs/affs/inode.c b/fs/affs/inode.c index d0609a282e1d..6f34510449e8 100644 --- a/fs/affs/inode.c +++ b/fs/affs/inode.c | |||
@@ -13,8 +13,6 @@ | |||
13 | #include <linux/gfp.h> | 13 | #include <linux/gfp.h> |
14 | #include "affs.h" | 14 | #include "affs.h" |
15 | 15 | ||
16 | extern const struct inode_operations affs_symlink_inode_operations; | ||
17 | |||
18 | struct inode *affs_iget(struct super_block *sb, unsigned long ino) | 16 | struct inode *affs_iget(struct super_block *sb, unsigned long ino) |
19 | { | 17 | { |
20 | struct affs_sb_info *sbi = AFFS_SB(sb); | 18 | struct affs_sb_info *sbi = AFFS_SB(sb); |
@@ -348,9 +346,8 @@ affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s3 | |||
348 | u32 block = 0; | 346 | u32 block = 0; |
349 | int retval; | 347 | int retval; |
350 | 348 | ||
351 | pr_debug("%s(dir=%u, inode=%u, \"%pd\", type=%d)\n", | 349 | pr_debug("%s(dir=%lu, inode=%lu, \"%pd\", type=%d)\n", __func__, |
352 | __func__, (u32)dir->i_ino, | 350 | dir->i_ino, inode->i_ino, dentry, type); |
353 | (u32)inode->i_ino, dentry, type); | ||
354 | 351 | ||
355 | retval = -EIO; | 352 | retval = -EIO; |
356 | bh = affs_bread(sb, inode->i_ino); | 353 | bh = affs_bread(sb, inode->i_ino); |
diff --git a/fs/affs/namei.c b/fs/affs/namei.c index bbc38530e924..ffb7bd82c2a5 100644 --- a/fs/affs/namei.c +++ b/fs/affs/namei.c | |||
@@ -64,15 +64,16 @@ __affs_hash_dentry(struct qstr *qstr, toupper_t toupper, bool notruncate) | |||
64 | { | 64 | { |
65 | const u8 *name = qstr->name; | 65 | const u8 *name = qstr->name; |
66 | unsigned long hash; | 66 | unsigned long hash; |
67 | int i; | 67 | int retval; |
68 | u32 len; | ||
68 | 69 | ||
69 | i = affs_check_name(qstr->name, qstr->len, notruncate); | 70 | retval = affs_check_name(qstr->name, qstr->len, notruncate); |
70 | if (i) | 71 | if (retval) |
71 | return i; | 72 | return retval; |
72 | 73 | ||
73 | hash = init_name_hash(); | 74 | hash = init_name_hash(); |
74 | i = min(qstr->len, 30u); | 75 | len = min(qstr->len, AFFSNAMEMAX); |
75 | for (; i > 0; name++, i--) | 76 | for (; len > 0; name++, len--) |
76 | hash = partial_name_hash(toupper(*name), hash); | 77 | hash = partial_name_hash(toupper(*name), hash); |
77 | qstr->hash = end_name_hash(hash); | 78 | qstr->hash = end_name_hash(hash); |
78 | 79 | ||
@@ -114,10 +115,10 @@ static inline int __affs_compare_dentry(unsigned int len, | |||
114 | * If the names are longer than the allowed 30 chars, | 115 | * If the names are longer than the allowed 30 chars, |
115 | * the excess is ignored, so their length may differ. | 116 | * the excess is ignored, so their length may differ. |
116 | */ | 117 | */ |
117 | if (len >= 30) { | 118 | if (len >= AFFSNAMEMAX) { |
118 | if (name->len < 30) | 119 | if (name->len < AFFSNAMEMAX) |
119 | return 1; | 120 | return 1; |
120 | len = 30; | 121 | len = AFFSNAMEMAX; |
121 | } else if (len != name->len) | 122 | } else if (len != name->len) |
122 | return 1; | 123 | return 1; |
123 | 124 | ||
@@ -156,10 +157,10 @@ affs_match(struct dentry *dentry, const u8 *name2, toupper_t toupper) | |||
156 | const u8 *name = dentry->d_name.name; | 157 | const u8 *name = dentry->d_name.name; |
157 | int len = dentry->d_name.len; | 158 | int len = dentry->d_name.len; |
158 | 159 | ||
159 | if (len >= 30) { | 160 | if (len >= AFFSNAMEMAX) { |
160 | if (*name2 < 30) | 161 | if (*name2 < AFFSNAMEMAX) |
161 | return 0; | 162 | return 0; |
162 | len = 30; | 163 | len = AFFSNAMEMAX; |
163 | } else if (len != *name2) | 164 | } else if (len != *name2) |
164 | return 0; | 165 | return 0; |
165 | 166 | ||
@@ -173,9 +174,9 @@ int | |||
173 | affs_hash_name(struct super_block *sb, const u8 *name, unsigned int len) | 174 | affs_hash_name(struct super_block *sb, const u8 *name, unsigned int len) |
174 | { | 175 | { |
175 | toupper_t toupper = affs_get_toupper(sb); | 176 | toupper_t toupper = affs_get_toupper(sb); |
176 | int hash; | 177 | u32 hash; |
177 | 178 | ||
178 | hash = len = min(len, 30u); | 179 | hash = len = min(len, AFFSNAMEMAX); |
179 | for (; len > 0; len--) | 180 | for (; len > 0; len--) |
180 | hash = (hash * 13 + toupper(*name++)) & 0x7ff; | 181 | hash = (hash * 13 + toupper(*name++)) & 0x7ff; |
181 | 182 | ||
@@ -248,9 +249,8 @@ affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) | |||
248 | int | 249 | int |
249 | affs_unlink(struct inode *dir, struct dentry *dentry) | 250 | affs_unlink(struct inode *dir, struct dentry *dentry) |
250 | { | 251 | { |
251 | pr_debug("%s(dir=%d, %lu \"%pd\")\n", | 252 | pr_debug("%s(dir=%lu, %lu \"%pd\")\n", __func__, dir->i_ino, |
252 | __func__, (u32)dir->i_ino, dentry->d_inode->i_ino, | 253 | dentry->d_inode->i_ino, dentry); |
253 | dentry); | ||
254 | 254 | ||
255 | return affs_remove_header(dentry); | 255 | return affs_remove_header(dentry); |
256 | } | 256 | } |
@@ -317,9 +317,8 @@ affs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
317 | int | 317 | int |
318 | affs_rmdir(struct inode *dir, struct dentry *dentry) | 318 | affs_rmdir(struct inode *dir, struct dentry *dentry) |
319 | { | 319 | { |
320 | pr_debug("%s(dir=%u, %lu \"%pd\")\n", | 320 | pr_debug("%s(dir=%lu, %lu \"%pd\")\n", __func__, dir->i_ino, |
321 | __func__, (u32)dir->i_ino, dentry->d_inode->i_ino, | 321 | dentry->d_inode->i_ino, dentry); |
322 | dentry); | ||
323 | 322 | ||
324 | return affs_remove_header(dentry); | 323 | return affs_remove_header(dentry); |
325 | } | 324 | } |
@@ -404,8 +403,7 @@ affs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) | |||
404 | { | 403 | { |
405 | struct inode *inode = old_dentry->d_inode; | 404 | struct inode *inode = old_dentry->d_inode; |
406 | 405 | ||
407 | pr_debug("%s(%u, %u, \"%pd\")\n", | 406 | pr_debug("%s(%lu, %lu, \"%pd\")\n", __func__, inode->i_ino, dir->i_ino, |
408 | __func__, (u32)inode->i_ino, (u32)dir->i_ino, | ||
409 | dentry); | 407 | dentry); |
410 | 408 | ||
411 | return affs_add_entry(dir, inode, dentry, ST_LINKFILE); | 409 | return affs_add_entry(dir, inode, dentry, ST_LINKFILE); |
@@ -419,9 +417,8 @@ affs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
419 | struct buffer_head *bh = NULL; | 417 | struct buffer_head *bh = NULL; |
420 | int retval; | 418 | int retval; |
421 | 419 | ||
422 | pr_debug("%s(old=%u,\"%pd\" to new=%u,\"%pd\")\n", | 420 | pr_debug("%s(old=%lu,\"%pd\" to new=%lu,\"%pd\")\n", __func__, |
423 | __func__, (u32)old_dir->i_ino, old_dentry, | 421 | old_dir->i_ino, old_dentry, new_dir->i_ino, new_dentry); |
424 | (u32)new_dir->i_ino, new_dentry); | ||
425 | 422 | ||
426 | retval = affs_check_name(new_dentry->d_name.name, | 423 | retval = affs_check_name(new_dentry->d_name.name, |
427 | new_dentry->d_name.len, | 424 | new_dentry->d_name.len, |
diff --git a/fs/affs/super.c b/fs/affs/super.c index f754ab68a840..4cf0e9113fb6 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c | |||
@@ -432,39 +432,39 @@ got_root: | |||
432 | sb->s_flags |= MS_RDONLY; | 432 | sb->s_flags |= MS_RDONLY; |
433 | } | 433 | } |
434 | switch (chksum) { | 434 | switch (chksum) { |
435 | case MUFS_FS: | 435 | case MUFS_FS: |
436 | case MUFS_INTLFFS: | 436 | case MUFS_INTLFFS: |
437 | case MUFS_DCFFS: | 437 | case MUFS_DCFFS: |
438 | sbi->s_flags |= SF_MUFS; | 438 | sbi->s_flags |= SF_MUFS; |
439 | /* fall thru */ | 439 | /* fall thru */ |
440 | case FS_INTLFFS: | 440 | case FS_INTLFFS: |
441 | case FS_DCFFS: | 441 | case FS_DCFFS: |
442 | sbi->s_flags |= SF_INTL; | 442 | sbi->s_flags |= SF_INTL; |
443 | break; | 443 | break; |
444 | case MUFS_FFS: | 444 | case MUFS_FFS: |
445 | sbi->s_flags |= SF_MUFS; | 445 | sbi->s_flags |= SF_MUFS; |
446 | break; | 446 | break; |
447 | case FS_FFS: | 447 | case FS_FFS: |
448 | break; | 448 | break; |
449 | case MUFS_OFS: | 449 | case MUFS_OFS: |
450 | sbi->s_flags |= SF_MUFS; | 450 | sbi->s_flags |= SF_MUFS; |
451 | /* fall thru */ | 451 | /* fall thru */ |
452 | case FS_OFS: | 452 | case FS_OFS: |
453 | sbi->s_flags |= SF_OFS; | 453 | sbi->s_flags |= SF_OFS; |
454 | sb->s_flags |= MS_NOEXEC; | 454 | sb->s_flags |= MS_NOEXEC; |
455 | break; | 455 | break; |
456 | case MUFS_DCOFS: | 456 | case MUFS_DCOFS: |
457 | case MUFS_INTLOFS: | 457 | case MUFS_INTLOFS: |
458 | sbi->s_flags |= SF_MUFS; | 458 | sbi->s_flags |= SF_MUFS; |
459 | case FS_DCOFS: | 459 | case FS_DCOFS: |
460 | case FS_INTLOFS: | 460 | case FS_INTLOFS: |
461 | sbi->s_flags |= SF_INTL | SF_OFS; | 461 | sbi->s_flags |= SF_INTL | SF_OFS; |
462 | sb->s_flags |= MS_NOEXEC; | 462 | sb->s_flags |= MS_NOEXEC; |
463 | break; | 463 | break; |
464 | default: | 464 | default: |
465 | pr_err("Unknown filesystem on device %s: %08X\n", | 465 | pr_err("Unknown filesystem on device %s: %08X\n", |
466 | sb->s_id, chksum); | 466 | sb->s_id, chksum); |
467 | return -EINVAL; | 467 | return -EINVAL; |
468 | } | 468 | } |
469 | 469 | ||
470 | if (mount_flags & SF_VERBOSE) { | 470 | if (mount_flags & SF_VERBOSE) { |
@@ -584,7 +584,7 @@ affs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
584 | buf->f_bavail = free; | 584 | buf->f_bavail = free; |
585 | buf->f_fsid.val[0] = (u32)id; | 585 | buf->f_fsid.val[0] = (u32)id; |
586 | buf->f_fsid.val[1] = (u32)(id >> 32); | 586 | buf->f_fsid.val[1] = (u32)(id >> 32); |
587 | buf->f_namelen = 30; | 587 | buf->f_namelen = AFFSNAMEMAX; |
588 | return 0; | 588 | return 0; |
589 | } | 589 | } |
590 | 590 | ||
@@ -602,6 +602,7 @@ static void affs_kill_sb(struct super_block *sb) | |||
602 | affs_free_bitmap(sb); | 602 | affs_free_bitmap(sb); |
603 | affs_brelse(sbi->s_root_bh); | 603 | affs_brelse(sbi->s_root_bh); |
604 | kfree(sbi->s_prefix); | 604 | kfree(sbi->s_prefix); |
605 | mutex_destroy(&sbi->s_bmlock); | ||
605 | kfree(sbi); | 606 | kfree(sbi); |
606 | } | 607 | } |
607 | } | 608 | } |
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index edf47774b03d..e089f1985fca 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c | |||
@@ -274,9 +274,9 @@ more: | |||
274 | static struct inode * | 274 | static struct inode * |
275 | befs_alloc_inode(struct super_block *sb) | 275 | befs_alloc_inode(struct super_block *sb) |
276 | { | 276 | { |
277 | struct befs_inode_info *bi; | 277 | struct befs_inode_info *bi; |
278 | bi = (struct befs_inode_info *)kmem_cache_alloc(befs_inode_cachep, | 278 | |
279 | GFP_KERNEL); | 279 | bi = kmem_cache_alloc(befs_inode_cachep, GFP_KERNEL); |
280 | if (!bi) | 280 | if (!bi) |
281 | return NULL; | 281 | return NULL; |
282 | return &bi->vfs_inode; | 282 | return &bi->vfs_inode; |
diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 86c893884eb9..281ee011bb6a 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c | |||
@@ -28,29 +28,6 @@ | |||
28 | 28 | ||
29 | #include "coda_int.h" | 29 | #include "coda_int.h" |
30 | 30 | ||
31 | /* dir inode-ops */ | ||
32 | static int coda_create(struct inode *dir, struct dentry *new, umode_t mode, bool excl); | ||
33 | static struct dentry *coda_lookup(struct inode *dir, struct dentry *target, unsigned int flags); | ||
34 | static int coda_link(struct dentry *old_dentry, struct inode *dir_inode, | ||
35 | struct dentry *entry); | ||
36 | static int coda_unlink(struct inode *dir_inode, struct dentry *entry); | ||
37 | static int coda_symlink(struct inode *dir_inode, struct dentry *entry, | ||
38 | const char *symname); | ||
39 | static int coda_mkdir(struct inode *dir_inode, struct dentry *entry, umode_t mode); | ||
40 | static int coda_rmdir(struct inode *dir_inode, struct dentry *entry); | ||
41 | static int coda_rename(struct inode *old_inode, struct dentry *old_dentry, | ||
42 | struct inode *new_inode, struct dentry *new_dentry); | ||
43 | |||
44 | /* dir file-ops */ | ||
45 | static int coda_readdir(struct file *file, struct dir_context *ctx); | ||
46 | |||
47 | /* dentry ops */ | ||
48 | static int coda_dentry_revalidate(struct dentry *de, unsigned int flags); | ||
49 | static int coda_dentry_delete(const struct dentry *); | ||
50 | |||
51 | /* support routines */ | ||
52 | static int coda_venus_readdir(struct file *, struct dir_context *); | ||
53 | |||
54 | /* same as fs/bad_inode.c */ | 31 | /* same as fs/bad_inode.c */ |
55 | static int coda_return_EIO(void) | 32 | static int coda_return_EIO(void) |
56 | { | 33 | { |
@@ -58,38 +35,6 @@ static int coda_return_EIO(void) | |||
58 | } | 35 | } |
59 | #define CODA_EIO_ERROR ((void *) (coda_return_EIO)) | 36 | #define CODA_EIO_ERROR ((void *) (coda_return_EIO)) |
60 | 37 | ||
61 | const struct dentry_operations coda_dentry_operations = | ||
62 | { | ||
63 | .d_revalidate = coda_dentry_revalidate, | ||
64 | .d_delete = coda_dentry_delete, | ||
65 | }; | ||
66 | |||
67 | const struct inode_operations coda_dir_inode_operations = | ||
68 | { | ||
69 | .create = coda_create, | ||
70 | .lookup = coda_lookup, | ||
71 | .link = coda_link, | ||
72 | .unlink = coda_unlink, | ||
73 | .symlink = coda_symlink, | ||
74 | .mkdir = coda_mkdir, | ||
75 | .rmdir = coda_rmdir, | ||
76 | .mknod = CODA_EIO_ERROR, | ||
77 | .rename = coda_rename, | ||
78 | .permission = coda_permission, | ||
79 | .getattr = coda_getattr, | ||
80 | .setattr = coda_setattr, | ||
81 | }; | ||
82 | |||
83 | const struct file_operations coda_dir_operations = { | ||
84 | .llseek = generic_file_llseek, | ||
85 | .read = generic_read_dir, | ||
86 | .iterate = coda_readdir, | ||
87 | .open = coda_open, | ||
88 | .release = coda_release, | ||
89 | .fsync = coda_fsync, | ||
90 | }; | ||
91 | |||
92 | |||
93 | /* inode operations for directories */ | 38 | /* inode operations for directories */ |
94 | /* access routines: lookup, readlink, permission */ | 39 | /* access routines: lookup, readlink, permission */ |
95 | static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, unsigned int flags) | 40 | static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, unsigned int flags) |
@@ -374,33 +319,6 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
374 | return error; | 319 | return error; |
375 | } | 320 | } |
376 | 321 | ||
377 | |||
378 | /* file operations for directories */ | ||
379 | static int coda_readdir(struct file *coda_file, struct dir_context *ctx) | ||
380 | { | ||
381 | struct coda_file_info *cfi; | ||
382 | struct file *host_file; | ||
383 | int ret; | ||
384 | |||
385 | cfi = CODA_FTOC(coda_file); | ||
386 | BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); | ||
387 | host_file = cfi->cfi_container; | ||
388 | |||
389 | if (host_file->f_op->iterate) { | ||
390 | struct inode *host_inode = file_inode(host_file); | ||
391 | mutex_lock(&host_inode->i_mutex); | ||
392 | ret = -ENOENT; | ||
393 | if (!IS_DEADDIR(host_inode)) { | ||
394 | ret = host_file->f_op->iterate(host_file, ctx); | ||
395 | file_accessed(host_file); | ||
396 | } | ||
397 | mutex_unlock(&host_inode->i_mutex); | ||
398 | return ret; | ||
399 | } | ||
400 | /* Venus: we must read Venus dirents from a file */ | ||
401 | return coda_venus_readdir(coda_file, ctx); | ||
402 | } | ||
403 | |||
404 | static inline unsigned int CDT2DT(unsigned char cdt) | 322 | static inline unsigned int CDT2DT(unsigned char cdt) |
405 | { | 323 | { |
406 | unsigned int dt; | 324 | unsigned int dt; |
@@ -495,6 +413,33 @@ out: | |||
495 | return 0; | 413 | return 0; |
496 | } | 414 | } |
497 | 415 | ||
416 | /* file operations for directories */ | ||
417 | static int coda_readdir(struct file *coda_file, struct dir_context *ctx) | ||
418 | { | ||
419 | struct coda_file_info *cfi; | ||
420 | struct file *host_file; | ||
421 | int ret; | ||
422 | |||
423 | cfi = CODA_FTOC(coda_file); | ||
424 | BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); | ||
425 | host_file = cfi->cfi_container; | ||
426 | |||
427 | if (host_file->f_op->iterate) { | ||
428 | struct inode *host_inode = file_inode(host_file); | ||
429 | |||
430 | mutex_lock(&host_inode->i_mutex); | ||
431 | ret = -ENOENT; | ||
432 | if (!IS_DEADDIR(host_inode)) { | ||
433 | ret = host_file->f_op->iterate(host_file, ctx); | ||
434 | file_accessed(host_file); | ||
435 | } | ||
436 | mutex_unlock(&host_inode->i_mutex); | ||
437 | return ret; | ||
438 | } | ||
439 | /* Venus: we must read Venus dirents from a file */ | ||
440 | return coda_venus_readdir(coda_file, ctx); | ||
441 | } | ||
442 | |||
498 | /* called when a cache lookup succeeds */ | 443 | /* called when a cache lookup succeeds */ |
499 | static int coda_dentry_revalidate(struct dentry *de, unsigned int flags) | 444 | static int coda_dentry_revalidate(struct dentry *de, unsigned int flags) |
500 | { | 445 | { |
@@ -603,3 +548,32 @@ int coda_revalidate_inode(struct inode *inode) | |||
603 | } | 548 | } |
604 | return 0; | 549 | return 0; |
605 | } | 550 | } |
551 | |||
552 | const struct dentry_operations coda_dentry_operations = { | ||
553 | .d_revalidate = coda_dentry_revalidate, | ||
554 | .d_delete = coda_dentry_delete, | ||
555 | }; | ||
556 | |||
557 | const struct inode_operations coda_dir_inode_operations = { | ||
558 | .create = coda_create, | ||
559 | .lookup = coda_lookup, | ||
560 | .link = coda_link, | ||
561 | .unlink = coda_unlink, | ||
562 | .symlink = coda_symlink, | ||
563 | .mkdir = coda_mkdir, | ||
564 | .rmdir = coda_rmdir, | ||
565 | .mknod = CODA_EIO_ERROR, | ||
566 | .rename = coda_rename, | ||
567 | .permission = coda_permission, | ||
568 | .getattr = coda_getattr, | ||
569 | .setattr = coda_setattr, | ||
570 | }; | ||
571 | |||
572 | const struct file_operations coda_dir_operations = { | ||
573 | .llseek = generic_file_llseek, | ||
574 | .read = generic_read_dir, | ||
575 | .iterate = coda_readdir, | ||
576 | .open = coda_open, | ||
577 | .release = coda_release, | ||
578 | .fsync = coda_fsync, | ||
579 | }; | ||
diff --git a/fs/eventfd.c b/fs/eventfd.c index 4b0a226024fa..8d0c0df01854 100644 --- a/fs/eventfd.c +++ b/fs/eventfd.c | |||
@@ -118,18 +118,18 @@ static unsigned int eventfd_poll(struct file *file, poll_table *wait) | |||
118 | { | 118 | { |
119 | struct eventfd_ctx *ctx = file->private_data; | 119 | struct eventfd_ctx *ctx = file->private_data; |
120 | unsigned int events = 0; | 120 | unsigned int events = 0; |
121 | unsigned long flags; | 121 | u64 count; |
122 | 122 | ||
123 | poll_wait(file, &ctx->wqh, wait); | 123 | poll_wait(file, &ctx->wqh, wait); |
124 | smp_rmb(); | ||
125 | count = ctx->count; | ||
124 | 126 | ||
125 | spin_lock_irqsave(&ctx->wqh.lock, flags); | 127 | if (count > 0) |
126 | if (ctx->count > 0) | ||
127 | events |= POLLIN; | 128 | events |= POLLIN; |
128 | if (ctx->count == ULLONG_MAX) | 129 | if (count == ULLONG_MAX) |
129 | events |= POLLERR; | 130 | events |= POLLERR; |
130 | if (ULLONG_MAX - 1 > ctx->count) | 131 | if (ULLONG_MAX - 1 > count) |
131 | events |= POLLOUT; | 132 | events |= POLLOUT; |
132 | spin_unlock_irqrestore(&ctx->wqh.lock, flags); | ||
133 | 133 | ||
134 | return events; | 134 | return events; |
135 | } | 135 | } |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 7b41a2dcdd76..497c7c5263c7 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -580,7 +580,7 @@ static void fat_set_state(struct super_block *sb, | |||
580 | { | 580 | { |
581 | struct buffer_head *bh; | 581 | struct buffer_head *bh; |
582 | struct fat_boot_sector *b; | 582 | struct fat_boot_sector *b; |
583 | struct msdos_sb_info *sbi = sb->s_fs_info; | 583 | struct msdos_sb_info *sbi = MSDOS_SB(sb); |
584 | 584 | ||
585 | /* do not change any thing if mounted read only */ | 585 | /* do not change any thing if mounted read only */ |
586 | if ((sb->s_flags & MS_RDONLY) && !force) | 586 | if ((sb->s_flags & MS_RDONLY) && !force) |
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index a90d6d354199..4e61388ec03d 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c | |||
@@ -546,8 +546,8 @@ static int __init update_note_header_size_elf64(const Elf64_Ehdr *ehdr_ptr) | |||
546 | nhdr_ptr = notes_section; | 546 | nhdr_ptr = notes_section; |
547 | while (nhdr_ptr->n_namesz != 0) { | 547 | while (nhdr_ptr->n_namesz != 0) { |
548 | sz = sizeof(Elf64_Nhdr) + | 548 | sz = sizeof(Elf64_Nhdr) + |
549 | ((nhdr_ptr->n_namesz + 3) & ~3) + | 549 | (((u64)nhdr_ptr->n_namesz + 3) & ~3) + |
550 | ((nhdr_ptr->n_descsz + 3) & ~3); | 550 | (((u64)nhdr_ptr->n_descsz + 3) & ~3); |
551 | if ((real_sz + sz) > max_sz) { | 551 | if ((real_sz + sz) > max_sz) { |
552 | pr_warn("Warning: Exceeded p_memsz, dropping PT_NOTE entry n_namesz=0x%x, n_descsz=0x%x\n", | 552 | pr_warn("Warning: Exceeded p_memsz, dropping PT_NOTE entry n_namesz=0x%x, n_descsz=0x%x\n", |
553 | nhdr_ptr->n_namesz, nhdr_ptr->n_descsz); | 553 | nhdr_ptr->n_namesz, nhdr_ptr->n_descsz); |
@@ -732,8 +732,8 @@ static int __init update_note_header_size_elf32(const Elf32_Ehdr *ehdr_ptr) | |||
732 | nhdr_ptr = notes_section; | 732 | nhdr_ptr = notes_section; |
733 | while (nhdr_ptr->n_namesz != 0) { | 733 | while (nhdr_ptr->n_namesz != 0) { |
734 | sz = sizeof(Elf32_Nhdr) + | 734 | sz = sizeof(Elf32_Nhdr) + |
735 | ((nhdr_ptr->n_namesz + 3) & ~3) + | 735 | (((u64)nhdr_ptr->n_namesz + 3) & ~3) + |
736 | ((nhdr_ptr->n_descsz + 3) & ~3); | 736 | (((u64)nhdr_ptr->n_descsz + 3) & ~3); |
737 | if ((real_sz + sz) > max_sz) { | 737 | if ((real_sz + sz) > max_sz) { |
738 | pr_warn("Warning: Exceeded p_memsz, dropping PT_NOTE entry n_namesz=0x%x, n_descsz=0x%x\n", | 738 | pr_warn("Warning: Exceeded p_memsz, dropping PT_NOTE entry n_namesz=0x%x, n_descsz=0x%x\n", |
739 | nhdr_ptr->n_namesz, nhdr_ptr->n_descsz); | 739 | nhdr_ptr->n_namesz, nhdr_ptr->n_descsz); |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index a7eec9888f10..e72401e1f995 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -2766,7 +2766,7 @@ static int reiserfs_write_begin(struct file *file, | |||
2766 | int old_ref = 0; | 2766 | int old_ref = 0; |
2767 | 2767 | ||
2768 | inode = mapping->host; | 2768 | inode = mapping->host; |
2769 | *fsdata = 0; | 2769 | *fsdata = NULL; |
2770 | if (flags & AOP_FLAG_CONT_EXPAND && | 2770 | if (flags & AOP_FLAG_CONT_EXPAND && |
2771 | (pos & (inode->i_sb->s_blocksize - 1)) == 0) { | 2771 | (pos & (inode->i_sb->s_blocksize - 1)) == 0) { |
2772 | pos ++; | 2772 | pos ++; |
diff --git a/fs/ufs/super.c b/fs/ufs/super.c index da73801301d5..8092d3759a5e 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c | |||
@@ -95,22 +95,18 @@ | |||
95 | 95 | ||
96 | void lock_ufs(struct super_block *sb) | 96 | void lock_ufs(struct super_block *sb) |
97 | { | 97 | { |
98 | #if defined(CONFIG_SMP) || defined (CONFIG_PREEMPT) | ||
99 | struct ufs_sb_info *sbi = UFS_SB(sb); | 98 | struct ufs_sb_info *sbi = UFS_SB(sb); |
100 | 99 | ||
101 | mutex_lock(&sbi->mutex); | 100 | mutex_lock(&sbi->mutex); |
102 | sbi->mutex_owner = current; | 101 | sbi->mutex_owner = current; |
103 | #endif | ||
104 | } | 102 | } |
105 | 103 | ||
106 | void unlock_ufs(struct super_block *sb) | 104 | void unlock_ufs(struct super_block *sb) |
107 | { | 105 | { |
108 | #if defined(CONFIG_SMP) || defined (CONFIG_PREEMPT) | ||
109 | struct ufs_sb_info *sbi = UFS_SB(sb); | 106 | struct ufs_sb_info *sbi = UFS_SB(sb); |
110 | 107 | ||
111 | sbi->mutex_owner = NULL; | 108 | sbi->mutex_owner = NULL; |
112 | mutex_unlock(&sbi->mutex); | 109 | mutex_unlock(&sbi->mutex); |
113 | #endif | ||
114 | } | 110 | } |
115 | 111 | ||
116 | static struct inode *ufs_nfs_get_inode(struct super_block *sb, u64 ino, u32 generation) | 112 | static struct inode *ufs_nfs_get_inode(struct super_block *sb, u64 ino, u32 generation) |
@@ -1415,9 +1411,11 @@ static struct kmem_cache * ufs_inode_cachep; | |||
1415 | static struct inode *ufs_alloc_inode(struct super_block *sb) | 1411 | static struct inode *ufs_alloc_inode(struct super_block *sb) |
1416 | { | 1412 | { |
1417 | struct ufs_inode_info *ei; | 1413 | struct ufs_inode_info *ei; |
1418 | ei = (struct ufs_inode_info *)kmem_cache_alloc(ufs_inode_cachep, GFP_NOFS); | 1414 | |
1415 | ei = kmem_cache_alloc(ufs_inode_cachep, GFP_NOFS); | ||
1419 | if (!ei) | 1416 | if (!ei) |
1420 | return NULL; | 1417 | return NULL; |
1418 | |||
1421 | ei->vfs_inode.i_version = 1; | 1419 | ei->vfs_inode.i_version = 1; |
1422 | return &ei->vfs_inode; | 1420 | return &ei->vfs_inode; |
1423 | } | 1421 | } |
diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 9d957b7ae095..e60a745ac198 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h | |||
@@ -1,6 +1,19 @@ | |||
1 | #ifndef LINUX_KEXEC_H | 1 | #ifndef LINUX_KEXEC_H |
2 | #define LINUX_KEXEC_H | 2 | #define LINUX_KEXEC_H |
3 | 3 | ||
4 | #define IND_DESTINATION_BIT 0 | ||
5 | #define IND_INDIRECTION_BIT 1 | ||
6 | #define IND_DONE_BIT 2 | ||
7 | #define IND_SOURCE_BIT 3 | ||
8 | |||
9 | #define IND_DESTINATION (1 << IND_DESTINATION_BIT) | ||
10 | #define IND_INDIRECTION (1 << IND_INDIRECTION_BIT) | ||
11 | #define IND_DONE (1 << IND_DONE_BIT) | ||
12 | #define IND_SOURCE (1 << IND_SOURCE_BIT) | ||
13 | #define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE) | ||
14 | |||
15 | #if !defined(__ASSEMBLY__) | ||
16 | |||
4 | #include <uapi/linux/kexec.h> | 17 | #include <uapi/linux/kexec.h> |
5 | 18 | ||
6 | #ifdef CONFIG_KEXEC | 19 | #ifdef CONFIG_KEXEC |
@@ -64,10 +77,6 @@ | |||
64 | */ | 77 | */ |
65 | 78 | ||
66 | typedef unsigned long kimage_entry_t; | 79 | typedef unsigned long kimage_entry_t; |
67 | #define IND_DESTINATION 0x1 | ||
68 | #define IND_INDIRECTION 0x2 | ||
69 | #define IND_DONE 0x4 | ||
70 | #define IND_SOURCE 0x8 | ||
71 | 80 | ||
72 | struct kexec_segment { | 81 | struct kexec_segment { |
73 | /* | 82 | /* |
@@ -122,8 +131,6 @@ struct kimage { | |||
122 | kimage_entry_t *entry; | 131 | kimage_entry_t *entry; |
123 | kimage_entry_t *last_entry; | 132 | kimage_entry_t *last_entry; |
124 | 133 | ||
125 | unsigned long destination; | ||
126 | |||
127 | unsigned long start; | 134 | unsigned long start; |
128 | struct page *control_code_page; | 135 | struct page *control_code_page; |
129 | struct page *swap_page; | 136 | struct page *swap_page; |
@@ -313,4 +320,7 @@ struct task_struct; | |||
313 | static inline void crash_kexec(struct pt_regs *regs) { } | 320 | static inline void crash_kexec(struct pt_regs *regs) { } |
314 | static inline int kexec_should_crash(struct task_struct *p) { return 0; } | 321 | static inline int kexec_should_crash(struct task_struct *p) { return 0; } |
315 | #endif /* CONFIG_KEXEC */ | 322 | #endif /* CONFIG_KEXEC */ |
323 | |||
324 | #endif /* !defined(__ASSEBMLY__) */ | ||
325 | |||
316 | #endif /* LINUX_KEXEC_H */ | 326 | #endif /* LINUX_KEXEC_H */ |
diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h index 57e75ae9910f..fb31765e935a 100644 --- a/include/linux/rbtree.h +++ b/include/linux/rbtree.h | |||
@@ -51,7 +51,7 @@ struct rb_root { | |||
51 | 51 | ||
52 | #define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL) | 52 | #define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL) |
53 | 53 | ||
54 | /* 'empty' nodes are nodes that are known not to be inserted in an rbree */ | 54 | /* 'empty' nodes are nodes that are known not to be inserted in an rbtree */ |
55 | #define RB_EMPTY_NODE(node) \ | 55 | #define RB_EMPTY_NODE(node) \ |
56 | ((node)->__rb_parent_color == (unsigned long)(node)) | 56 | ((node)->__rb_parent_color == (unsigned long)(node)) |
57 | #define RB_CLEAR_NODE(node) \ | 57 | #define RB_CLEAR_NODE(node) \ |
diff --git a/include/uapi/linux/kexec.h b/include/uapi/linux/kexec.h index 6925f5b42f89..99048e501b88 100644 --- a/include/uapi/linux/kexec.h +++ b/include/uapi/linux/kexec.h | |||
@@ -55,12 +55,6 @@ struct kexec_segment { | |||
55 | size_t memsz; | 55 | size_t memsz; |
56 | }; | 56 | }; |
57 | 57 | ||
58 | /* Load a new kernel image as described by the kexec_segment array | ||
59 | * consisting of passed number of segments at the entry-point address. | ||
60 | * The flags allow different useage types. | ||
61 | */ | ||
62 | extern int kexec_load(void *, size_t, struct kexec_segment *, | ||
63 | unsigned long int); | ||
64 | #endif /* __KERNEL__ */ | 58 | #endif /* __KERNEL__ */ |
65 | 59 | ||
66 | #endif /* _UAPILINUX_KEXEC_H */ | 60 | #endif /* _UAPILINUX_KEXEC_H */ |
@@ -1941,7 +1941,7 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, | |||
1941 | queue.sleeper = current; | 1941 | queue.sleeper = current; |
1942 | 1942 | ||
1943 | sleep_again: | 1943 | sleep_again: |
1944 | current->state = TASK_INTERRUPTIBLE; | 1944 | __set_current_state(TASK_INTERRUPTIBLE); |
1945 | sem_unlock(sma, locknum); | 1945 | sem_unlock(sma, locknum); |
1946 | rcu_read_unlock(); | 1946 | rcu_read_unlock(); |
1947 | 1947 | ||
diff --git a/kernel/kexec.c b/kernel/kexec.c index c85277639b34..38c25b1f2fd5 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c | |||
@@ -444,7 +444,7 @@ arch_kexec_apply_relocations(const Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, | |||
444 | } | 444 | } |
445 | 445 | ||
446 | /* | 446 | /* |
447 | * Free up memory used by kernel, initrd, and comand line. This is temporary | 447 | * Free up memory used by kernel, initrd, and command line. This is temporary |
448 | * memory allocation which is not needed any more after these buffers have | 448 | * memory allocation which is not needed any more after these buffers have |
449 | * been loaded into separate segments and have been copied elsewhere. | 449 | * been loaded into separate segments and have been copied elsewhere. |
450 | */ | 450 | */ |
@@ -856,8 +856,6 @@ static int kimage_set_destination(struct kimage *image, | |||
856 | 856 | ||
857 | destination &= PAGE_MASK; | 857 | destination &= PAGE_MASK; |
858 | result = kimage_add_entry(image, destination | IND_DESTINATION); | 858 | result = kimage_add_entry(image, destination | IND_DESTINATION); |
859 | if (result == 0) | ||
860 | image->destination = destination; | ||
861 | 859 | ||
862 | return result; | 860 | return result; |
863 | } | 861 | } |
@@ -869,8 +867,6 @@ static int kimage_add_page(struct kimage *image, unsigned long page) | |||
869 | 867 | ||
870 | page &= PAGE_MASK; | 868 | page &= PAGE_MASK; |
871 | result = kimage_add_entry(image, page | IND_SOURCE); | 869 | result = kimage_add_entry(image, page | IND_SOURCE); |
872 | if (result == 0) | ||
873 | image->destination += PAGE_SIZE; | ||
874 | 870 | ||
875 | return result; | 871 | return result; |
876 | } | 872 | } |
@@ -1288,19 +1284,22 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments, | |||
1288 | if (nr_segments > 0) { | 1284 | if (nr_segments > 0) { |
1289 | unsigned long i; | 1285 | unsigned long i; |
1290 | 1286 | ||
1291 | /* Loading another kernel to reboot into */ | 1287 | if (flags & KEXEC_ON_CRASH) { |
1292 | if ((flags & KEXEC_ON_CRASH) == 0) | 1288 | /* |
1293 | result = kimage_alloc_init(&image, entry, nr_segments, | 1289 | * Loading another kernel to switch to if this one |
1294 | segments, flags); | 1290 | * crashes. Free any current crash dump kernel before |
1295 | /* Loading another kernel to switch to if this one crashes */ | ||
1296 | else if (flags & KEXEC_ON_CRASH) { | ||
1297 | /* Free any current crash dump kernel before | ||
1298 | * we corrupt it. | 1291 | * we corrupt it. |
1299 | */ | 1292 | */ |
1293 | |||
1300 | kimage_free(xchg(&kexec_crash_image, NULL)); | 1294 | kimage_free(xchg(&kexec_crash_image, NULL)); |
1301 | result = kimage_alloc_init(&image, entry, nr_segments, | 1295 | result = kimage_alloc_init(&image, entry, nr_segments, |
1302 | segments, flags); | 1296 | segments, flags); |
1303 | crash_map_reserved_pages(); | 1297 | crash_map_reserved_pages(); |
1298 | } else { | ||
1299 | /* Loading another kernel to reboot into. */ | ||
1300 | |||
1301 | result = kimage_alloc_init(&image, entry, nr_segments, | ||
1302 | segments, flags); | ||
1304 | } | 1303 | } |
1305 | if (result) | 1304 | if (result) |
1306 | goto out; | 1305 | goto out; |
diff --git a/kernel/module.c b/kernel/module.c index 8426ad48362c..b34813f725e9 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -3025,8 +3025,13 @@ static void do_free_init(struct rcu_head *head) | |||
3025 | kfree(m); | 3025 | kfree(m); |
3026 | } | 3026 | } |
3027 | 3027 | ||
3028 | /* This is where the real work happens */ | 3028 | /* |
3029 | static int do_init_module(struct module *mod) | 3029 | * This is where the real work happens. |
3030 | * | ||
3031 | * Keep it uninlined to provide a reliable breakpoint target, e.g. for the gdb | ||
3032 | * helper command 'lx-symbols'. | ||
3033 | */ | ||
3034 | static noinline int do_init_module(struct module *mod) | ||
3030 | { | 3035 | { |
3031 | int ret = 0; | 3036 | int ret = 0; |
3032 | struct mod_initfree *freeinit; | 3037 | struct mod_initfree *freeinit; |
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 1eb9d90c3af9..227fec36b12a 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
@@ -1077,7 +1077,6 @@ int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr, | |||
1077 | } | 1077 | } |
1078 | 1078 | ||
1079 | #if defined CONFIG_COMPAT | 1079 | #if defined CONFIG_COMPAT |
1080 | #include <linux/compat.h> | ||
1081 | 1080 | ||
1082 | int compat_ptrace_request(struct task_struct *child, compat_long_t request, | 1081 | int compat_ptrace_request(struct task_struct *child, compat_long_t request, |
1083 | compat_ulong_t addr, compat_ulong_t data) | 1082 | compat_ulong_t addr, compat_ulong_t data) |
diff --git a/kernel/seccomp.c b/kernel/seccomp.c index 4ef9687ac115..4f44028943e6 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c | |||
@@ -629,7 +629,9 @@ static u32 __seccomp_phase1_filter(int this_syscall, struct seccomp_data *sd) | |||
629 | 629 | ||
630 | switch (action) { | 630 | switch (action) { |
631 | case SECCOMP_RET_ERRNO: | 631 | case SECCOMP_RET_ERRNO: |
632 | /* Set the low-order 16-bits as a errno. */ | 632 | /* Set low-order bits as an errno, capped at MAX_ERRNO. */ |
633 | if (data > MAX_ERRNO) | ||
634 | data = MAX_ERRNO; | ||
633 | syscall_set_return_value(current, task_pt_regs(current), | 635 | syscall_set_return_value(current, task_pt_regs(current), |
634 | -data, 0); | 636 | -data, 0); |
635 | goto skip; | 637 | goto skip; |
diff --git a/kernel/signal.c b/kernel/signal.c index 33a52759cc0e..a390499943e4 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -3550,7 +3550,7 @@ SYSCALL_DEFINE2(signal, int, sig, __sighandler_t, handler) | |||
3550 | SYSCALL_DEFINE0(pause) | 3550 | SYSCALL_DEFINE0(pause) |
3551 | { | 3551 | { |
3552 | while (!signal_pending(current)) { | 3552 | while (!signal_pending(current)) { |
3553 | current->state = TASK_INTERRUPTIBLE; | 3553 | __set_current_state(TASK_INTERRUPTIBLE); |
3554 | schedule(); | 3554 | schedule(); |
3555 | } | 3555 | } |
3556 | return -ERESTARTNOHAND; | 3556 | return -ERESTARTNOHAND; |
@@ -3563,7 +3563,7 @@ int sigsuspend(sigset_t *set) | |||
3563 | current->saved_sigmask = current->blocked; | 3563 | current->saved_sigmask = current->blocked; |
3564 | set_current_blocked(set); | 3564 | set_current_blocked(set); |
3565 | 3565 | ||
3566 | current->state = TASK_INTERRUPTIBLE; | 3566 | __set_current_state(TASK_INTERRUPTIBLE); |
3567 | schedule(); | 3567 | schedule(); |
3568 | set_restore_sigmask(); | 3568 | set_restore_sigmask(); |
3569 | return -ERESTARTNOHAND; | 3569 | return -ERESTARTNOHAND; |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index ecb3516f6546..c5cefb3c009c 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -167,6 +167,17 @@ config DEBUG_INFO_DWARF4 | |||
167 | But it significantly improves the success of resolving | 167 | But it significantly improves the success of resolving |
168 | variables in gdb on optimized code. | 168 | variables in gdb on optimized code. |
169 | 169 | ||
170 | config GDB_SCRIPTS | ||
171 | bool "Provide GDB scripts for kernel debugging" | ||
172 | depends on DEBUG_INFO | ||
173 | help | ||
174 | This creates the required links to GDB helper scripts in the | ||
175 | build directory. If you load vmlinux into gdb, the helper | ||
176 | scripts will be automatically imported by gdb as well, and | ||
177 | additional functions are available to analyze a Linux kernel | ||
178 | instance. See Documentation/gdb-kernel-debugging.txt for further | ||
179 | details. | ||
180 | |||
170 | config ENABLE_WARN_DEPRECATED | 181 | config ENABLE_WARN_DEPRECATED |
171 | bool "Enable __deprecated logic" | 182 | bool "Enable __deprecated logic" |
172 | default y | 183 | default y |
diff --git a/samples/seccomp/bpf-fancy.c b/samples/seccomp/bpf-fancy.c index 8eb483aaec46..e8b24f443709 100644 --- a/samples/seccomp/bpf-fancy.c +++ b/samples/seccomp/bpf-fancy.c | |||
@@ -25,7 +25,9 @@ | |||
25 | 25 | ||
26 | int main(int argc, char **argv) | 26 | int main(int argc, char **argv) |
27 | { | 27 | { |
28 | struct bpf_labels l; | 28 | struct bpf_labels l = { |
29 | .count = 0, | ||
30 | }; | ||
29 | static const char msg1[] = "Please type something: "; | 31 | static const char msg1[] = "Please type something: "; |
30 | static const char msg2[] = "You typed: "; | 32 | static const char msg2[] = "You typed: "; |
31 | char buf[256]; | 33 | char buf[256]; |
diff --git a/samples/seccomp/bpf-helper.c b/samples/seccomp/bpf-helper.c index 579cfe331886..05cb4d5ff9f5 100644 --- a/samples/seccomp/bpf-helper.c +++ b/samples/seccomp/bpf-helper.c | |||
@@ -10,6 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <stdio.h> | 12 | #include <stdio.h> |
13 | #include <stdlib.h> | ||
13 | #include <string.h> | 14 | #include <string.h> |
14 | 15 | ||
15 | #include "bpf-helper.h" | 16 | #include "bpf-helper.h" |
@@ -63,6 +64,11 @@ __u32 seccomp_bpf_label(struct bpf_labels *labels, const char *label) | |||
63 | { | 64 | { |
64 | struct __bpf_label *begin = labels->labels, *end; | 65 | struct __bpf_label *begin = labels->labels, *end; |
65 | int id; | 66 | int id; |
67 | |||
68 | if (labels->count == BPF_LABELS_MAX) { | ||
69 | fprintf(stderr, "Too many labels\n"); | ||
70 | exit(1); | ||
71 | } | ||
66 | if (labels->count == 0) { | 72 | if (labels->count == 0) { |
67 | begin->label = label; | 73 | begin->label = label; |
68 | begin->location = 0xffffffff; | 74 | begin->location = 0xffffffff; |
diff --git a/scripts/Makefile b/scripts/Makefile index 72902b5f2721..2016a64497ab 100644 --- a/scripts/Makefile +++ b/scripts/Makefile | |||
@@ -36,6 +36,7 @@ subdir-$(CONFIG_MODVERSIONS) += genksyms | |||
36 | subdir-y += mod | 36 | subdir-y += mod |
37 | subdir-$(CONFIG_SECURITY_SELINUX) += selinux | 37 | subdir-$(CONFIG_SECURITY_SELINUX) += selinux |
38 | subdir-$(CONFIG_DTC) += dtc | 38 | subdir-$(CONFIG_DTC) += dtc |
39 | subdir-$(CONFIG_GDB_SCRIPTS) += gdb | ||
39 | 40 | ||
40 | # Let clean descend into subdirs | 41 | # Let clean descend into subdirs |
41 | subdir- += basic kconfig package | 42 | subdir- += basic kconfig package |
diff --git a/scripts/gdb/Makefile b/scripts/gdb/Makefile new file mode 100644 index 000000000000..62f5f65becfd --- /dev/null +++ b/scripts/gdb/Makefile | |||
@@ -0,0 +1 @@ | |||
subdir-y := linux | |||
diff --git a/scripts/gdb/linux/.gitignore b/scripts/gdb/linux/.gitignore new file mode 100644 index 000000000000..52e4e61140d1 --- /dev/null +++ b/scripts/gdb/linux/.gitignore | |||
@@ -0,0 +1,2 @@ | |||
1 | *.pyc | ||
2 | *.pyo | ||
diff --git a/scripts/gdb/linux/Makefile b/scripts/gdb/linux/Makefile new file mode 100644 index 000000000000..6cf1ecf61057 --- /dev/null +++ b/scripts/gdb/linux/Makefile | |||
@@ -0,0 +1,11 @@ | |||
1 | always := gdb-scripts | ||
2 | |||
3 | SRCTREE := $(shell cd $(srctree) && /bin/pwd) | ||
4 | |||
5 | $(obj)/gdb-scripts: | ||
6 | ifneq ($(KBUILD_SRC),) | ||
7 | $(Q)ln -fsn $(SRCTREE)/$(obj)/*.py $(objtree)/$(obj) | ||
8 | endif | ||
9 | @: | ||
10 | |||
11 | clean-files := *.pyc *.pyo $(if $(KBUILD_SRC),*.py) | ||
diff --git a/scripts/gdb/linux/cpus.py b/scripts/gdb/linux/cpus.py new file mode 100644 index 000000000000..4297b83fedef --- /dev/null +++ b/scripts/gdb/linux/cpus.py | |||
@@ -0,0 +1,135 @@ | |||
1 | # | ||
2 | # gdb helper commands and functions for Linux kernel debugging | ||
3 | # | ||
4 | # per-cpu tools | ||
5 | # | ||
6 | # Copyright (c) Siemens AG, 2011-2013 | ||
7 | # | ||
8 | # Authors: | ||
9 | # Jan Kiszka <jan.kiszka@siemens.com> | ||
10 | # | ||
11 | # This work is licensed under the terms of the GNU GPL version 2. | ||
12 | # | ||
13 | |||
14 | import gdb | ||
15 | |||
16 | from linux import tasks, utils | ||
17 | |||
18 | |||
19 | MAX_CPUS = 4096 | ||
20 | |||
21 | |||
22 | def get_current_cpu(): | ||
23 | if utils.get_gdbserver_type() == utils.GDBSERVER_QEMU: | ||
24 | return gdb.selected_thread().num - 1 | ||
25 | elif utils.get_gdbserver_type() == utils.GDBSERVER_KGDB: | ||
26 | tid = gdb.selected_thread().ptid[2] | ||
27 | if tid > (0x100000000 - MAX_CPUS - 2): | ||
28 | return 0x100000000 - tid - 2 | ||
29 | else: | ||
30 | return tasks.get_thread_info(tasks.get_task_by_pid(tid))['cpu'] | ||
31 | else: | ||
32 | raise gdb.GdbError("Sorry, obtaining the current CPU is not yet " | ||
33 | "supported with this gdb server.") | ||
34 | |||
35 | |||
36 | def per_cpu(var_ptr, cpu): | ||
37 | if cpu == -1: | ||
38 | cpu = get_current_cpu() | ||
39 | if utils.is_target_arch("sparc:v9"): | ||
40 | offset = gdb.parse_and_eval( | ||
41 | "trap_block[{0}].__per_cpu_base".format(str(cpu))) | ||
42 | else: | ||
43 | try: | ||
44 | offset = gdb.parse_and_eval( | ||
45 | "__per_cpu_offset[{0}]".format(str(cpu))) | ||
46 | except gdb.error: | ||
47 | # !CONFIG_SMP case | ||
48 | offset = 0 | ||
49 | pointer = var_ptr.cast(utils.get_long_type()) + offset | ||
50 | return pointer.cast(var_ptr.type).dereference() | ||
51 | |||
52 | |||
53 | cpu_mask = {} | ||
54 | |||
55 | |||
56 | def cpu_mask_invalidate(event): | ||
57 | global cpu_mask | ||
58 | cpu_mask = {} | ||
59 | gdb.events.stop.disconnect(cpu_mask_invalidate) | ||
60 | if hasattr(gdb.events, 'new_objfile'): | ||
61 | gdb.events.new_objfile.disconnect(cpu_mask_invalidate) | ||
62 | |||
63 | |||
64 | def cpu_list(mask_name): | ||
65 | global cpu_mask | ||
66 | mask = None | ||
67 | if mask_name in cpu_mask: | ||
68 | mask = cpu_mask[mask_name] | ||
69 | if mask is None: | ||
70 | mask = gdb.parse_and_eval(mask_name + ".bits") | ||
71 | if hasattr(gdb, 'events'): | ||
72 | cpu_mask[mask_name] = mask | ||
73 | gdb.events.stop.connect(cpu_mask_invalidate) | ||
74 | if hasattr(gdb.events, 'new_objfile'): | ||
75 | gdb.events.new_objfile.connect(cpu_mask_invalidate) | ||
76 | bits_per_entry = mask[0].type.sizeof * 8 | ||
77 | num_entries = mask.type.sizeof * 8 / bits_per_entry | ||
78 | entry = -1 | ||
79 | bits = 0 | ||
80 | |||
81 | while True: | ||
82 | while bits == 0: | ||
83 | entry += 1 | ||
84 | if entry == num_entries: | ||
85 | return | ||
86 | bits = mask[entry] | ||
87 | if bits != 0: | ||
88 | bit = 0 | ||
89 | break | ||
90 | |||
91 | while bits & 1 == 0: | ||
92 | bits >>= 1 | ||
93 | bit += 1 | ||
94 | |||
95 | cpu = entry * bits_per_entry + bit | ||
96 | |||
97 | bits >>= 1 | ||
98 | bit += 1 | ||
99 | |||
100 | yield cpu | ||
101 | |||
102 | |||
103 | class PerCpu(gdb.Function): | ||
104 | """Return per-cpu variable. | ||
105 | |||
106 | $lx_per_cpu("VAR"[, CPU]): Return the per-cpu variable called VAR for the | ||
107 | given CPU number. If CPU is omitted, the CPU of the current context is used. | ||
108 | Note that VAR has to be quoted as string.""" | ||
109 | |||
110 | def __init__(self): | ||
111 | super(PerCpu, self).__init__("lx_per_cpu") | ||
112 | |||
113 | def invoke(self, var_name, cpu=-1): | ||
114 | var_ptr = gdb.parse_and_eval("&" + var_name.string()) | ||
115 | return per_cpu(var_ptr, cpu) | ||
116 | |||
117 | |||
118 | PerCpu() | ||
119 | |||
120 | |||
121 | class LxCurrentFunc(gdb.Function): | ||
122 | """Return current task. | ||
123 | |||
124 | $lx_current([CPU]): Return the per-cpu task variable for the given CPU | ||
125 | number. If CPU is omitted, the CPU of the current context is used.""" | ||
126 | |||
127 | def __init__(self): | ||
128 | super(LxCurrentFunc, self).__init__("lx_current") | ||
129 | |||
130 | def invoke(self, cpu=-1): | ||
131 | var_ptr = gdb.parse_and_eval("¤t_task") | ||
132 | return per_cpu(var_ptr, cpu).dereference() | ||
133 | |||
134 | |||
135 | LxCurrentFunc() | ||
diff --git a/scripts/gdb/linux/dmesg.py b/scripts/gdb/linux/dmesg.py new file mode 100644 index 000000000000..3c947f0c5dad --- /dev/null +++ b/scripts/gdb/linux/dmesg.py | |||
@@ -0,0 +1,65 @@ | |||
1 | # | ||
2 | # gdb helper commands and functions for Linux kernel debugging | ||
3 | # | ||
4 | # kernel log buffer dump | ||
5 | # | ||
6 | # Copyright (c) Siemens AG, 2011, 2012 | ||
7 | # | ||
8 | # Authors: | ||
9 | # Jan Kiszka <jan.kiszka@siemens.com> | ||
10 | # | ||
11 | # This work is licensed under the terms of the GNU GPL version 2. | ||
12 | # | ||
13 | |||
14 | import gdb | ||
15 | import string | ||
16 | |||
17 | from linux import utils | ||
18 | |||
19 | |||
20 | class LxDmesg(gdb.Command): | ||
21 | """Print Linux kernel log buffer.""" | ||
22 | |||
23 | def __init__(self): | ||
24 | super(LxDmesg, self).__init__("lx-dmesg", gdb.COMMAND_DATA) | ||
25 | |||
26 | def invoke(self, arg, from_tty): | ||
27 | log_buf_addr = int(str(gdb.parse_and_eval("log_buf")).split()[0], 16) | ||
28 | log_first_idx = int(gdb.parse_and_eval("log_first_idx")) | ||
29 | log_next_idx = int(gdb.parse_and_eval("log_next_idx")) | ||
30 | log_buf_len = int(gdb.parse_and_eval("log_buf_len")) | ||
31 | |||
32 | inf = gdb.inferiors()[0] | ||
33 | start = log_buf_addr + log_first_idx | ||
34 | if log_first_idx < log_next_idx: | ||
35 | log_buf_2nd_half = -1 | ||
36 | length = log_next_idx - log_first_idx | ||
37 | log_buf = inf.read_memory(start, length) | ||
38 | else: | ||
39 | log_buf_2nd_half = log_buf_len - log_first_idx | ||
40 | log_buf = inf.read_memory(start, log_buf_2nd_half) + \ | ||
41 | inf.read_memory(log_buf_addr, log_next_idx) | ||
42 | |||
43 | pos = 0 | ||
44 | while pos < log_buf.__len__(): | ||
45 | length = utils.read_u16(log_buf[pos + 8:pos + 10]) | ||
46 | if length == 0: | ||
47 | if log_buf_2nd_half == -1: | ||
48 | gdb.write("Corrupted log buffer!\n") | ||
49 | break | ||
50 | pos = log_buf_2nd_half | ||
51 | continue | ||
52 | |||
53 | text_len = utils.read_u16(log_buf[pos + 10:pos + 12]) | ||
54 | text = log_buf[pos + 16:pos + 16 + text_len] | ||
55 | time_stamp = utils.read_u64(log_buf[pos:pos + 8]) | ||
56 | |||
57 | for line in memoryview(text).tobytes().splitlines(): | ||
58 | gdb.write("[{time:12.6f}] {line}\n".format( | ||
59 | time=time_stamp / 1000000000.0, | ||
60 | line=line)) | ||
61 | |||
62 | pos += length | ||
63 | |||
64 | |||
65 | LxDmesg() | ||
diff --git a/scripts/gdb/linux/modules.py b/scripts/gdb/linux/modules.py new file mode 100644 index 000000000000..a1504c4f1900 --- /dev/null +++ b/scripts/gdb/linux/modules.py | |||
@@ -0,0 +1,103 @@ | |||
1 | # | ||
2 | # gdb helper commands and functions for Linux kernel debugging | ||
3 | # | ||
4 | # module tools | ||
5 | # | ||
6 | # Copyright (c) Siemens AG, 2013 | ||
7 | # | ||
8 | # Authors: | ||
9 | # Jan Kiszka <jan.kiszka@siemens.com> | ||
10 | # | ||
11 | # This work is licensed under the terms of the GNU GPL version 2. | ||
12 | # | ||
13 | |||
14 | import gdb | ||
15 | |||
16 | from linux import cpus, utils | ||
17 | |||
18 | |||
19 | module_type = utils.CachedType("struct module") | ||
20 | |||
21 | |||
22 | def module_list(): | ||
23 | global module_type | ||
24 | module_ptr_type = module_type.get_type().pointer() | ||
25 | modules = gdb.parse_and_eval("modules") | ||
26 | entry = modules['next'] | ||
27 | end_of_list = modules.address | ||
28 | |||
29 | while entry != end_of_list: | ||
30 | yield utils.container_of(entry, module_ptr_type, "list") | ||
31 | entry = entry['next'] | ||
32 | |||
33 | |||
34 | def find_module_by_name(name): | ||
35 | for module in module_list(): | ||
36 | if module['name'].string() == name: | ||
37 | return module | ||
38 | return None | ||
39 | |||
40 | |||
41 | class LxModule(gdb.Function): | ||
42 | """Find module by name and return the module variable. | ||
43 | |||
44 | $lx_module("MODULE"): Given the name MODULE, iterate over all loaded modules | ||
45 | of the target and return that module variable which MODULE matches.""" | ||
46 | |||
47 | def __init__(self): | ||
48 | super(LxModule, self).__init__("lx_module") | ||
49 | |||
50 | def invoke(self, mod_name): | ||
51 | mod_name = mod_name.string() | ||
52 | module = find_module_by_name(mod_name) | ||
53 | if module: | ||
54 | return module.dereference() | ||
55 | else: | ||
56 | raise gdb.GdbError("Unable to find MODULE " + mod_name) | ||
57 | |||
58 | |||
59 | LxModule() | ||
60 | |||
61 | |||
62 | class LxLsmod(gdb.Command): | ||
63 | """List currently loaded modules.""" | ||
64 | |||
65 | _module_use_type = utils.CachedType("struct module_use") | ||
66 | |||
67 | def __init__(self): | ||
68 | super(LxLsmod, self).__init__("lx-lsmod", gdb.COMMAND_DATA) | ||
69 | |||
70 | def invoke(self, arg, from_tty): | ||
71 | gdb.write( | ||
72 | "Address{0} Module Size Used by\n".format( | ||
73 | " " if utils.get_long_type().sizeof == 8 else "")) | ||
74 | |||
75 | for module in module_list(): | ||
76 | ref = 0 | ||
77 | module_refptr = module['refptr'] | ||
78 | for cpu in cpus.cpu_list("cpu_possible_mask"): | ||
79 | refptr = cpus.per_cpu(module_refptr, cpu) | ||
80 | ref += refptr['incs'] | ||
81 | ref -= refptr['decs'] | ||
82 | |||
83 | gdb.write("{address} {name:<19} {size:>8} {ref}".format( | ||
84 | address=str(module['module_core']).split()[0], | ||
85 | name=module['name'].string(), | ||
86 | size=str(module['core_size']), | ||
87 | ref=str(ref))) | ||
88 | |||
89 | source_list = module['source_list'] | ||
90 | t = self._module_use_type.get_type().pointer() | ||
91 | entry = source_list['next'] | ||
92 | first = True | ||
93 | while entry != source_list.address: | ||
94 | use = utils.container_of(entry, t, "source_list") | ||
95 | gdb.write("{separator}{name}".format( | ||
96 | separator=" " if first else ",", | ||
97 | name=use['source']['name'].string())) | ||
98 | first = False | ||
99 | entry = entry['next'] | ||
100 | gdb.write("\n") | ||
101 | |||
102 | |||
103 | LxLsmod() | ||
diff --git a/scripts/gdb/linux/symbols.py b/scripts/gdb/linux/symbols.py new file mode 100644 index 000000000000..cd5bea965d4e --- /dev/null +++ b/scripts/gdb/linux/symbols.py | |||
@@ -0,0 +1,177 @@ | |||
1 | # | ||
2 | # gdb helper commands and functions for Linux kernel debugging | ||
3 | # | ||
4 | # load kernel and module symbols | ||
5 | # | ||
6 | # Copyright (c) Siemens AG, 2011-2013 | ||
7 | # | ||
8 | # Authors: | ||
9 | # Jan Kiszka <jan.kiszka@siemens.com> | ||
10 | # | ||
11 | # This work is licensed under the terms of the GNU GPL version 2. | ||
12 | # | ||
13 | |||
14 | import gdb | ||
15 | import os | ||
16 | import re | ||
17 | import string | ||
18 | |||
19 | from linux import modules, utils | ||
20 | |||
21 | |||
22 | if hasattr(gdb, 'Breakpoint'): | ||
23 | class LoadModuleBreakpoint(gdb.Breakpoint): | ||
24 | def __init__(self, spec, gdb_command): | ||
25 | super(LoadModuleBreakpoint, self).__init__(spec, internal=True) | ||
26 | self.silent = True | ||
27 | self.gdb_command = gdb_command | ||
28 | |||
29 | def stop(self): | ||
30 | module = gdb.parse_and_eval("mod") | ||
31 | module_name = module['name'].string() | ||
32 | cmd = self.gdb_command | ||
33 | |||
34 | # enforce update if object file is not found | ||
35 | cmd.module_files_updated = False | ||
36 | |||
37 | # Disable pagination while reporting symbol (re-)loading. | ||
38 | # The console input is blocked in this context so that we would | ||
39 | # get stuck waiting for the user to acknowledge paged output. | ||
40 | show_pagination = gdb.execute("show pagination", to_string=True) | ||
41 | pagination = show_pagination.endswith("on.\n") | ||
42 | gdb.execute("set pagination off") | ||
43 | |||
44 | if module_name in cmd.loaded_modules: | ||
45 | gdb.write("refreshing all symbols to reload module " | ||
46 | "'{0}'\n".format(module_name)) | ||
47 | cmd.load_all_symbols() | ||
48 | else: | ||
49 | cmd.load_module_symbols(module) | ||
50 | |||
51 | # restore pagination state | ||
52 | gdb.execute("set pagination %s" % ("on" if pagination else "off")) | ||
53 | |||
54 | return False | ||
55 | |||
56 | |||
57 | class LxSymbols(gdb.Command): | ||
58 | """(Re-)load symbols of Linux kernel and currently loaded modules. | ||
59 | |||
60 | The kernel (vmlinux) is taken from the current working directly. Modules (.ko) | ||
61 | are scanned recursively, starting in the same directory. Optionally, the module | ||
62 | search path can be extended by a space separated list of paths passed to the | ||
63 | lx-symbols command.""" | ||
64 | |||
65 | module_paths = [] | ||
66 | module_files = [] | ||
67 | module_files_updated = False | ||
68 | loaded_modules = [] | ||
69 | breakpoint = None | ||
70 | |||
71 | def __init__(self): | ||
72 | super(LxSymbols, self).__init__("lx-symbols", gdb.COMMAND_FILES, | ||
73 | gdb.COMPLETE_FILENAME) | ||
74 | |||
75 | def _update_module_files(self): | ||
76 | self.module_files = [] | ||
77 | for path in self.module_paths: | ||
78 | gdb.write("scanning for modules in {0}\n".format(path)) | ||
79 | for root, dirs, files in os.walk(path): | ||
80 | for name in files: | ||
81 | if name.endswith(".ko"): | ||
82 | self.module_files.append(root + "/" + name) | ||
83 | self.module_files_updated = True | ||
84 | |||
85 | def _get_module_file(self, module_name): | ||
86 | module_pattern = ".*/{0}\.ko$".format( | ||
87 | module_name.replace("_", r"[_\-]")) | ||
88 | for name in self.module_files: | ||
89 | if re.match(module_pattern, name) and os.path.exists(name): | ||
90 | return name | ||
91 | return None | ||
92 | |||
93 | def _section_arguments(self, module): | ||
94 | try: | ||
95 | sect_attrs = module['sect_attrs'].dereference() | ||
96 | except gdb.error: | ||
97 | return "" | ||
98 | attrs = sect_attrs['attrs'] | ||
99 | section_name_to_address = { | ||
100 | attrs[n]['name'].string() : attrs[n]['address'] | ||
101 | for n in range(int(sect_attrs['nsections']))} | ||
102 | args = [] | ||
103 | for section_name in [".data", ".data..read_mostly", ".rodata", ".bss"]: | ||
104 | address = section_name_to_address.get(section_name) | ||
105 | if address: | ||
106 | args.append(" -s {name} {addr}".format( | ||
107 | name=section_name, addr=str(address))) | ||
108 | return "".join(args) | ||
109 | |||
110 | def load_module_symbols(self, module): | ||
111 | module_name = module['name'].string() | ||
112 | module_addr = str(module['module_core']).split()[0] | ||
113 | |||
114 | module_file = self._get_module_file(module_name) | ||
115 | if not module_file and not self.module_files_updated: | ||
116 | self._update_module_files() | ||
117 | module_file = self._get_module_file(module_name) | ||
118 | |||
119 | if module_file: | ||
120 | gdb.write("loading @{addr}: {filename}\n".format( | ||
121 | addr=module_addr, filename=module_file)) | ||
122 | cmdline = "add-symbol-file {filename} {addr}{sections}".format( | ||
123 | filename=module_file, | ||
124 | addr=module_addr, | ||
125 | sections=self._section_arguments(module)) | ||
126 | gdb.execute(cmdline, to_string=True) | ||
127 | if not module_name in self.loaded_modules: | ||
128 | self.loaded_modules.append(module_name) | ||
129 | else: | ||
130 | gdb.write("no module object found for '{0}'\n".format(module_name)) | ||
131 | |||
132 | def load_all_symbols(self): | ||
133 | gdb.write("loading vmlinux\n") | ||
134 | |||
135 | # Dropping symbols will disable all breakpoints. So save their states | ||
136 | # and restore them afterward. | ||
137 | saved_states = [] | ||
138 | if hasattr(gdb, 'breakpoints') and not gdb.breakpoints() is None: | ||
139 | for bp in gdb.breakpoints(): | ||
140 | saved_states.append({'breakpoint': bp, 'enabled': bp.enabled}) | ||
141 | |||
142 | # drop all current symbols and reload vmlinux | ||
143 | gdb.execute("symbol-file", to_string=True) | ||
144 | gdb.execute("symbol-file vmlinux") | ||
145 | |||
146 | self.loaded_modules = [] | ||
147 | module_list = modules.module_list() | ||
148 | if not module_list: | ||
149 | gdb.write("no modules found\n") | ||
150 | else: | ||
151 | [self.load_module_symbols(module) for module in module_list] | ||
152 | |||
153 | for saved_state in saved_states: | ||
154 | saved_state['breakpoint'].enabled = saved_state['enabled'] | ||
155 | |||
156 | def invoke(self, arg, from_tty): | ||
157 | self.module_paths = arg.split() | ||
158 | self.module_paths.append(os.getcwd()) | ||
159 | |||
160 | # enforce update | ||
161 | self.module_files = [] | ||
162 | self.module_files_updated = False | ||
163 | |||
164 | self.load_all_symbols() | ||
165 | |||
166 | if hasattr(gdb, 'Breakpoint'): | ||
167 | if not self.breakpoint is None: | ||
168 | self.breakpoint.delete() | ||
169 | self.breakpoint = None | ||
170 | self.breakpoint = LoadModuleBreakpoint( | ||
171 | "kernel/module.c:do_init_module", self) | ||
172 | else: | ||
173 | gdb.write("Note: symbol update on module loading not supported " | ||
174 | "with this gdb version\n") | ||
175 | |||
176 | |||
177 | LxSymbols() | ||
diff --git a/scripts/gdb/linux/tasks.py b/scripts/gdb/linux/tasks.py new file mode 100644 index 000000000000..e2037d9bb7eb --- /dev/null +++ b/scripts/gdb/linux/tasks.py | |||
@@ -0,0 +1,100 @@ | |||
1 | # | ||
2 | # gdb helper commands and functions for Linux kernel debugging | ||
3 | # | ||
4 | # task & thread tools | ||
5 | # | ||
6 | # Copyright (c) Siemens AG, 2011-2013 | ||
7 | # | ||
8 | # Authors: | ||
9 | # Jan Kiszka <jan.kiszka@siemens.com> | ||
10 | # | ||
11 | # This work is licensed under the terms of the GNU GPL version 2. | ||
12 | # | ||
13 | |||
14 | import gdb | ||
15 | |||
16 | from linux import utils | ||
17 | |||
18 | |||
19 | task_type = utils.CachedType("struct task_struct") | ||
20 | |||
21 | def task_lists(): | ||
22 | global task_type | ||
23 | task_ptr_type = task_type.get_type().pointer() | ||
24 | init_task = gdb.parse_and_eval("init_task").address | ||
25 | t = g = init_task | ||
26 | |||
27 | while True: | ||
28 | while True: | ||
29 | yield t | ||
30 | |||
31 | t = utils.container_of(t['thread_group']['next'], | ||
32 | task_ptr_type, "thread_group") | ||
33 | if t == g: | ||
34 | break | ||
35 | |||
36 | t = g = utils.container_of(g['tasks']['next'], | ||
37 | task_ptr_type, "tasks") | ||
38 | if t == init_task: | ||
39 | return | ||
40 | |||
41 | def get_task_by_pid(pid): | ||
42 | for task in task_lists(): | ||
43 | if int(task['pid']) == pid: | ||
44 | return task | ||
45 | return None | ||
46 | |||
47 | |||
48 | class LxTaskByPidFunc(gdb.Function): | ||
49 | """Find Linux task by PID and return the task_struct variable. | ||
50 | |||
51 | $lx_task_by_pid(PID): Given PID, iterate over all tasks of the target and | ||
52 | return that task_struct variable which PID matches.""" | ||
53 | |||
54 | def __init__(self): | ||
55 | super(LxTaskByPidFunc, self).__init__("lx_task_by_pid") | ||
56 | |||
57 | def invoke(self, pid): | ||
58 | task = get_task_by_pid(pid) | ||
59 | if task: | ||
60 | return task.dereference() | ||
61 | else: | ||
62 | raise gdb.GdbError("No task of PID " + str(pid)) | ||
63 | |||
64 | |||
65 | LxTaskByPidFunc() | ||
66 | |||
67 | |||
68 | thread_info_type = utils.CachedType("struct thread_info") | ||
69 | |||
70 | ia64_task_size = None | ||
71 | |||
72 | |||
73 | def get_thread_info(task): | ||
74 | global thread_info_type | ||
75 | thread_info_ptr_type = thread_info_type.get_type().pointer() | ||
76 | if utils.is_target_arch("ia64"): | ||
77 | global ia64_task_size | ||
78 | if ia64_task_size is None: | ||
79 | ia64_task_size = gdb.parse_and_eval("sizeof(struct task_struct)") | ||
80 | thread_info_addr = task.address + ia64_task_size | ||
81 | thread_info = thread_info_addr.cast(thread_info_ptr_type) | ||
82 | else: | ||
83 | thread_info = task['stack'].cast(thread_info_ptr_type) | ||
84 | return thread_info.dereference() | ||
85 | |||
86 | |||
87 | class LxThreadInfoFunc (gdb.Function): | ||
88 | """Calculate Linux thread_info from task variable. | ||
89 | |||
90 | $lx_thread_info(TASK): Given TASK, return the corresponding thread_info | ||
91 | variable.""" | ||
92 | |||
93 | def __init__(self): | ||
94 | super(LxThreadInfoFunc, self).__init__("lx_thread_info") | ||
95 | |||
96 | def invoke(self, task): | ||
97 | return get_thread_info(task) | ||
98 | |||
99 | |||
100 | LxThreadInfoFunc() | ||
diff --git a/scripts/gdb/linux/utils.py b/scripts/gdb/linux/utils.py new file mode 100644 index 000000000000..128c306db3ee --- /dev/null +++ b/scripts/gdb/linux/utils.py | |||
@@ -0,0 +1,156 @@ | |||
1 | # | ||
2 | # gdb helper commands and functions for Linux kernel debugging | ||
3 | # | ||
4 | # common utilities | ||
5 | # | ||
6 | # Copyright (c) Siemens AG, 2011-2013 | ||
7 | # | ||
8 | # Authors: | ||
9 | # Jan Kiszka <jan.kiszka@siemens.com> | ||
10 | # | ||
11 | # This work is licensed under the terms of the GNU GPL version 2. | ||
12 | # | ||
13 | |||
14 | import gdb | ||
15 | |||
16 | |||
17 | class CachedType: | ||
18 | def __init__(self, name): | ||
19 | self._type = None | ||
20 | self._name = name | ||
21 | |||
22 | def _new_objfile_handler(self, event): | ||
23 | self._type = None | ||
24 | gdb.events.new_objfile.disconnect(self._new_objfile_handler) | ||
25 | |||
26 | def get_type(self): | ||
27 | if self._type is None: | ||
28 | self._type = gdb.lookup_type(self._name) | ||
29 | if self._type is None: | ||
30 | raise gdb.GdbError( | ||
31 | "cannot resolve type '{0}'".format(self._name)) | ||
32 | if hasattr(gdb, 'events') and hasattr(gdb.events, 'new_objfile'): | ||
33 | gdb.events.new_objfile.connect(self._new_objfile_handler) | ||
34 | return self._type | ||
35 | |||
36 | |||
37 | long_type = CachedType("long") | ||
38 | |||
39 | |||
40 | def get_long_type(): | ||
41 | global long_type | ||
42 | return long_type.get_type() | ||
43 | |||
44 | |||
45 | def offset_of(typeobj, field): | ||
46 | element = gdb.Value(0).cast(typeobj) | ||
47 | return int(str(element[field].address).split()[0], 16) | ||
48 | |||
49 | |||
50 | def container_of(ptr, typeobj, member): | ||
51 | return (ptr.cast(get_long_type()) - | ||
52 | offset_of(typeobj, member)).cast(typeobj) | ||
53 | |||
54 | |||
55 | class ContainerOf(gdb.Function): | ||
56 | """Return pointer to containing data structure. | ||
57 | |||
58 | $container_of(PTR, "TYPE", "ELEMENT"): Given PTR, return a pointer to the | ||
59 | data structure of the type TYPE in which PTR is the address of ELEMENT. | ||
60 | Note that TYPE and ELEMENT have to be quoted as strings.""" | ||
61 | |||
62 | def __init__(self): | ||
63 | super(ContainerOf, self).__init__("container_of") | ||
64 | |||
65 | def invoke(self, ptr, typename, elementname): | ||
66 | return container_of(ptr, gdb.lookup_type(typename.string()).pointer(), | ||
67 | elementname.string()) | ||
68 | |||
69 | ContainerOf() | ||
70 | |||
71 | |||
72 | BIG_ENDIAN = 0 | ||
73 | LITTLE_ENDIAN = 1 | ||
74 | target_endianness = None | ||
75 | |||
76 | |||
77 | def get_target_endianness(): | ||
78 | global target_endianness | ||
79 | if target_endianness is None: | ||
80 | endian = gdb.execute("show endian", to_string=True) | ||
81 | if "little endian" in endian: | ||
82 | target_endianness = LITTLE_ENDIAN | ||
83 | elif "big endian" in endian: | ||
84 | target_endianness = BIG_ENDIAN | ||
85 | else: | ||
86 | raise gdb.GdgError("unknown endianness '{0}'".format(str(endian))) | ||
87 | return target_endianness | ||
88 | |||
89 | |||
90 | def read_u16(buffer): | ||
91 | if get_target_endianness() == LITTLE_ENDIAN: | ||
92 | return ord(buffer[0]) + (ord(buffer[1]) << 8) | ||
93 | else: | ||
94 | return ord(buffer[1]) + (ord(buffer[0]) << 8) | ||
95 | |||
96 | |||
97 | def read_u32(buffer): | ||
98 | if get_target_endianness() == LITTLE_ENDIAN: | ||
99 | return read_u16(buffer[0:2]) + (read_u16(buffer[2:4]) << 16) | ||
100 | else: | ||
101 | return read_u16(buffer[2:4]) + (read_u16(buffer[0:2]) << 16) | ||
102 | |||
103 | |||
104 | def read_u64(buffer): | ||
105 | if get_target_endianness() == LITTLE_ENDIAN: | ||
106 | return read_u32(buffer[0:4]) + (read_u32(buffer[4:8]) << 32) | ||
107 | else: | ||
108 | return read_u32(buffer[4:8]) + (read_u32(buffer[0:4]) << 32) | ||
109 | |||
110 | |||
111 | target_arch = None | ||
112 | |||
113 | |||
114 | def is_target_arch(arch): | ||
115 | if hasattr(gdb.Frame, 'architecture'): | ||
116 | return arch in gdb.newest_frame().architecture().name() | ||
117 | else: | ||
118 | global target_arch | ||
119 | if target_arch is None: | ||
120 | target_arch = gdb.execute("show architecture", to_string=True) | ||
121 | return arch in target_arch | ||
122 | |||
123 | |||
124 | GDBSERVER_QEMU = 0 | ||
125 | GDBSERVER_KGDB = 1 | ||
126 | gdbserver_type = None | ||
127 | |||
128 | |||
129 | def get_gdbserver_type(): | ||
130 | def exit_handler(event): | ||
131 | global gdbserver_type | ||
132 | gdbserver_type = None | ||
133 | gdb.events.exited.disconnect(exit_handler) | ||
134 | |||
135 | def probe_qemu(): | ||
136 | try: | ||
137 | return gdb.execute("monitor info version", to_string=True) != "" | ||
138 | except: | ||
139 | return False | ||
140 | |||
141 | def probe_kgdb(): | ||
142 | try: | ||
143 | thread_info = gdb.execute("info thread 2", to_string=True) | ||
144 | return "shadowCPU0" in thread_info | ||
145 | except: | ||
146 | return False | ||
147 | |||
148 | global gdbserver_type | ||
149 | if gdbserver_type is None: | ||
150 | if probe_qemu(): | ||
151 | gdbserver_type = GDBSERVER_QEMU | ||
152 | elif probe_kgdb(): | ||
153 | gdbserver_type = GDBSERVER_KGDB | ||
154 | if not gdbserver_type is None and hasattr(gdb, 'events'): | ||
155 | gdb.events.exited.connect(exit_handler) | ||
156 | return gdbserver_type | ||
diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py new file mode 100644 index 000000000000..48489285f119 --- /dev/null +++ b/scripts/gdb/vmlinux-gdb.py | |||
@@ -0,0 +1,30 @@ | |||
1 | # | ||
2 | # gdb helper commands and functions for Linux kernel debugging | ||
3 | # | ||
4 | # loader module | ||
5 | # | ||
6 | # Copyright (c) Siemens AG, 2012, 2013 | ||
7 | # | ||
8 | # Authors: | ||
9 | # Jan Kiszka <jan.kiszka@siemens.com> | ||
10 | # | ||
11 | # This work is licensed under the terms of the GNU GPL version 2. | ||
12 | # | ||
13 | |||
14 | import os | ||
15 | |||
16 | sys.path.insert(0, os.path.dirname(__file__) + "/scripts/gdb") | ||
17 | |||
18 | try: | ||
19 | gdb.parse_and_eval("0") | ||
20 | gdb.execute("", to_string=True) | ||
21 | except: | ||
22 | gdb.write("NOTE: gdb 7.2 or later required for Linux helper scripts to " | ||
23 | "work.\n") | ||
24 | else: | ||
25 | import linux.utils | ||
26 | import linux.symbols | ||
27 | import linux.modules | ||
28 | import linux.dmesg | ||
29 | import linux.tasks | ||
30 | import linux.cpus | ||