Re: d_lookup: Unable to handle kernel paging request

Vicente Bergas
2019-06-19T12:42:29Z

On Tuesday, June 18, 2019 8:35:48 PM CEST, Al Viro wrote:
> On Tue, May 28, 2019 at 11:38:43AM +0200, Vicente Bergas wrote:
>> On Wednesday, May 22, 2019 6:29:46 PM CEST, Al Viro wrote: ...
>
> __d_lookup() running into &dentry->d_hash == 0x01000000 at some
> point in hash chain
> and trying to look at ->d_name.hash:
>
>> pc : __d_lookup+0x58/0x198
>> lr : d_lookup+0x38/0x68
>> sp : ffff000012663b90
>> x29: ffff000012663b90 x28: ffff000012663d58 x27: 0000000000000000 x26:
>> ffff8000ae7cc900 x25: 0000000000000001 x24: ffffffffffffffff x23: ...
>
> __d_lookup_rcu() running into &dentry->d_hash == 0x01000000 at
> some point in hash
> chain and trying to look at ->d_seq:
>
>> pc : __d_lookup_rcu+0x68/0x198
>> lr : lookup_fast+0x44/0x2e8
>> sp : ffff0000130b3b60
>> x29: ffff0000130b3b60 x28: 00000000ce99d070 x27: ffffffffffffffff x26:
>> 0000000000000026 x25: ffff8000ecec6030 x24: ffff0000130b3c2c x23: ...
>
> __d_lookup_rcu() running into &dentry->d_hash ==
> 0x0000880001000000 at some point
> in hash chain and trying to look at ->d_seq:
>
>> pc : __d_lookup_rcu+0x68/0x198
>> lr : lookup_fast+0x44/0x2e8
>> sp : ffff00001325ba90
>> x29: ffff00001325ba90 x28: 00000000ce99f075 x27: ffffffffffffffff x26:
>> 0000000000000007 x25: ffff8000ecec402a x24: ffff00001325bb5c x23: ...
>
> ditto
>
>> pc : __d_lookup_rcu+0x68/0x198
>> lr : lookup_fast+0x44/0x2e8
>> sp : ffff000012a3ba90
>> x29: ffff000012a3ba90 x28: 00000000ce99f075 x27: ffffffffffffffff x26:
>> 0000000000000007 x25: ffff8000ecec702a x24: ffff000012a3bb5c x23: ...
>
> ditto
>
>> pc : __d_lookup_rcu+0x68/0x198
>> lr : lookup_fast+0x44/0x2e8
>> sp : ffff0000132bba90
>> x29: ffff0000132bba90 x28: 00000000ce99e1a6 x27: ffffffffffffffff x26:
>> 000000000000000c x25: ffff8000f21dd036 x24: ffff0000132bbb5c x23: ...
>
> ... and ditto:
>
>> pc : __d_lookup_rcu+0x68/0x198
>> lr : lookup_fast+0x44/0x2e8
>> sp : ffff000013263a90
>> x29: ffff000013263a90 x28: 00000000ce99e1a6 x27: ffffffffffffffff x26:
>> 000000000000000c x25: ffff8000f0a6f036 x24: ffff000013263b5c x23: ...
>
>
> All of those run under rcu_read_lock() and no dentry with DCACHE_NORCU has
> ever been inserted into a hash chain, so it doesn't look like a plain
> use-after-free. Could you try something like the following to see a bit
> more about where it comes from?
>
> So far it looks like something is buggering a forward reference
> in hash chain in a fairly specific way - the values seen had been
> 00000000010000000 and
> 00008800010000000. Does that smell like anything from arm64-specific
> data structures (PTE, etc.)?
>
> Alternatively, we might've gone off rails a step (or more) before,
> with the previous iteration going through bogus, but at least mapped
> address - the one that has never been a dentry in the first place.
>
>
> diff --git a/fs/dcache.c b/fs/dcache.c
> index c435398f2c81..cb555edb5b55 100644
> --- a/fs/dcache.c
> +++ b/fs/dcache.c
> @@ -2114,6 +2114,22 @@ static inline bool d_same_name(const
> struct dentry *dentry,
> name) == 0;
> }
>
> +static void dump(struct dentry *dentry)
> +{
> + int i;
> + if (!dentry) {
> + printk(KERN_ERR "list fucked in head");
> + return;
> + }
> + printk(KERN_ERR "fucked dentry[%p]: d_hash.next = %p, flags =
> %x, count = %d",
> + dentry, dentry->d_hash.next, dentry->d_flags,
> + dentry->d_lockref.count
> + );
> + for (i = 0; i < sizeof(struct dentry); i++)
> + printk(KERN_CONT "%c%02x", i & 31 ? ' ' : '\n',
> + ((unsigned char *)dentry)[i]);
> +}
> +
> /**
> * __d_lookup_rcu - search for a dentry (racy, store-free)
> * @parent: parent dentry
> @@ -2151,7 +2167,7 @@ struct dentry *__d_lookup_rcu(const
> struct dentry *parent,
> const unsigned char *str = name->name;
> struct hlist_bl_head *b = d_hash(hashlen_hash(hashlen));
> struct hlist_bl_node *node;
> - struct dentry *dentry;
> + struct dentry *dentry, *last = NULL;
>
> /*
> * Note: There is significant duplication with __d_lookup_rcu which is
> @@ -2176,6 +2192,10 @@ struct dentry *__d_lookup_rcu(const
> struct dentry *parent,
> hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) {
> unsigned seq;
>
> + if (unlikely((u32)(unsigned long)&dentry->d_hash == 0x01000000))
> + dump(last);
> + last = dentry;
> +
> seqretry:
> /*
> * The dentry sequence count protects us from concurrent
> @@ -2274,7 +2294,7 @@ struct dentry *__d_lookup(const struct
> dentry *parent, const struct qstr *name)
> struct hlist_bl_head *b = d_hash(hash);
> struct hlist_bl_node *node;
> struct dentry *found = NULL;
> - struct dentry *dentry;
> + struct dentry *dentry, *last = NULL;
>
> /*
> * Note: There is significant duplication with __d_lookup_rcu which is
> @@ -2300,6 +2320,10 @@ struct dentry *__d_lookup(const struct
> dentry *parent, const struct qstr *name)
>
> hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) {
>
> + if (unlikely((u32)(unsigned long)&dentry->d_hash == 0x01000000))
> + dump(last);
> + last = dentry;
> +
> if (dentry->d_name.hash != hash)
> continue;

Hi Al,
i have been running the distro-provided kernel the last few weeks
and had no issues at all.
https://archlinuxarm.org/packages/aarch64/linux-aarch64
It is from the v5.1 branch and is compiled with gcc 8.3.

IIRC, i also tested
https://archlinuxarm.org/packages/aarch64/linux-aarch64-rc
v5.2-rc1 and v5.2-rc2 (which at that time where compiled with
gcc 8.2) with no issues.

This week tested v5.2-rc4 and v5.2-rc5 from archlinuxarm but
there are regressions unrelated to d_lookup.

At this point i was convinced it was a gcc 9.1 issue and had
nothing to do with the kernel, but anyways i gave your patch a try.
The tested kernel is v5.2-rc5-224-gbed3c0d84e7e and
it has been compiled with gcc 8.3.
The sentinel you put there has triggered!
So, it is not a gcc 9.1 issue.

In any case, i have no idea if those addresses are arm64-specific
in any way.

Regards,
Vicenç.

list fucked in head
Unable to handle kernel paging request at virtual address 0000000000fffffc
Mem abort info:
ESR = 0x96000004
Exception class = DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
Data abort info:
ISV = 0, ISS = 0x00000004
CM = 0, WnR = 0
user pgtable: 4k pages, 48-bit VAs, pgdp=000000005c989000
[0000000000fffffc] pgd=0000000000000000
Internal error: Oops: 96000004 [#1] SMP
CPU: 4 PID: 2427 Comm: git Not tainted 5.2.0-rc5 #1
Hardware name: Sapphire-RK3399 Board (DT)
pstate: 60000005 (nZCv daif -PAN -UAO)
pc : __d_lookup_rcu+0x90/0x1e8
lr : __d_lookup_rcu+0x84/0x1e8
sp : ffff000013413a90
x29: ffff000013413a90 x28: ffff000013413b5c
x27: 0000000000000002 x26: ffff000013413c78
x25: 0000001ac1084259 x24: 0000000000fffff8
x23: 0000000001000000 x22: ffff8000586ed9c0
x21: ffff8000586ed9c0 x20: 0000000000fffff8
x19: 0000000001000000 x18: 0000000000000000
x17: 0000000000000000 x16: 0000000000000000
x15: 0000000000000000 x14: 0000000000000000
x13: 0000000000000000 x12: 0000000000000000
x11: 0000000000000000 x10: ffffffffffffffff
x9 : 00000000c1084259 x8 : ffff800054f31032
x7 : 000000000000001a x6 : ffff00001090454b
x5 : 0000000000000013 x4 : 0000000000000000
x3 : 0000000000000000 x2 : 00000000ffffffff
x1 : 00008000e6f46000 x0 : 0000000000000013
Call trace:
__d_lookup_rcu+0x90/0x1e8
lookup_fast+0x44/0x300
walk_component+0x34/0x2e0
path_lookupat.isra.13+0x5c/0x1e0
filename_lookup.part.19+0x6c/0xe8
user_path_at_empty+0x4c/0x60
vfs_statx+0x78/0xd8
__se_sys_newfstatat+0x24/0x48
__arm64_sys_newfstatat+0x18/0x20
el0_svc_handler+0x94/0x138
el0_svc+0x8/0xc
Code: 94000753 294c1fe9 9280000a f94037e8 (b85fc263)
---[ end trace 93a444e9b6bc67e8 ]---
list fucked in head
Unable to handle kernel paging request at virtual address 0000000000fffffc
Mem abort info:
ESR = 0x96000004
Exception class = DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
Data abort info:
ISV = 0, ISS = 0x00000004
CM = 0, WnR = 0
user pgtable: 4k pages, 48-bit VAs, pgdp=000000005c989000
[0000000000fffffc] pgd=0000000000000000
Internal error: Oops: 96000004 [#2] SMP
CPU: 5 PID: 2424 Comm: git Tainted: G D 5.2.0-rc5 #1
Hardware name: Sapphire-RK3399 Board (DT)
pstate: 60000005 (nZCv daif -PAN -UAO)
pc : __d_lookup_rcu+0x90/0x1e8
lr : __d_lookup_rcu+0x84/0x1e8
sp : ffff0000133fba90
x29: ffff0000133fba90 x28: ffff0000133fbb5c
x27: 0000000000000002 x26: ffff0000133fbc78
x25: 0000001ac1084259 x24: 0000000000fffff8
x23: 0000000001000000 x22: ffff8000586ed9c0
x21: ffff8000586ed9c0 x20: 0000000000fffff8
x19: 0000000001000000 x18: 0000000000000000
x17: 0000000000000000 x16: 0000000000000000
x15: 0000000000000000 x14: 0000000000000000
x13: 0000000000000000 x12: 0000000000000000
x11: 0000000000000000 x10: ffffffffffffffff
x9 : 00000000c1084259 x8 : ffff800079d7b032
x7 : 000000000000001a x6 : ffff00001090454b
x5 : 0000000000000013 x4 : 0000000000000000
x3 : 0000000000000000 x2 : 00000000ffffffff
x1 : 00008000e6f5a000 x0 : 0000000000000013
Call trace:
__d_lookup_rcu+0x90/0x1e8
lookup_fast+0x44/0x300
walk_component+0x34/0x2e0
path_lookupat.isra.13+0x5c/0x1e0
filename_lookup.part.19+0x6c/0xe8
user_path_at_empty+0x4c/0x60
vfs_statx+0x78/0xd8
__se_sys_newfstatat+0x24/0x48
__arm64_sys_newfstatat+0x18/0x20
el0_svc_handler+0x94/0x138
el0_svc+0x8/0xc
Code: 94000753 294c1fe9 9280000a f94037e8 (b85fc263)
---[ end trace 93a444e9b6bc67e9 ]---
list fucked in head
Unable to handle kernel paging request at virtual address 0000880000fffffc
Mem abort info:
ESR = 0x96000004
Exception class = DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
Data abort info:
ISV = 0, ISS = 0x00000004
CM = 0, WnR = 0
user pgtable: 4k pages, 48-bit VAs, pgdp=000000003ba5d000
[0000880000fffffc] pgd=0000000000000000
Internal error: Oops: 96000004 [#3] SMP
CPU: 2 PID: 2659 Comm: git Tainted: G D 5.2.0-rc5 #1
Hardware name: Sapphire-RK3399 Board (DT)
pstate: 60000005 (nZCv daif -PAN -UAO)
pc : __d_lookup_rcu+0x90/0x1e8
lr : __d_lookup_rcu+0x84/0x1e8
sp : ffff0000135cba90
x29: ffff0000135cba90 x28: ffff0000135cbb5c
x27: 0000000000000000 x26: ffff0000135cbc78
x25: 00000010cb63a9bb x24: 0000880000fffff8
x23: 0000000001000000 x22: ffff80003be53180
x21: ffff80003be53180 x20: 0000880000fffff8
x19: 0000880001000000 x18: 0000000000000000
x17: 0000000000000000 x16: 0000000000000000
x15: 0000000000000000 x14: 0000000000000000
x13: 0000000000000000 x12: 0000000000000000
x11: 0000000000000000 x10: ffffffffffffffff
x9 : 00000000cb63a9bb x8 : ffff8000f094102e
x7 : 0000000000000010 x6 : ffff00001090454b
x5 : 0000000000000013 x4 : 0000000000000000
x3 : 0000000000000000 x2 : 00000000ffffffff
x1 : 00008000e6f1e000 x0 : 0000000000000013
Call trace:
__d_lookup_rcu+0x90/0x1e8
lookup_fast+0x44/0x300
walk_component+0x34/0x2e0
path_lookupat.isra.13+0x5c/0x1e0
filename_lookup.part.19+0x6c/0xe8
user_path_at_empty+0x4c/0x60
vfs_statx+0x78/0xd8
__se_sys_newfstatat+0x24/0x48
__arm64_sys_newfstatat+0x18/0x20
el0_svc_handler+0x94/0x138
el0_svc+0x8/0xc
Code: 94000753 294c1fe9 9280000a f94037e8 (b85fc263)
---[ end trace 93a444e9b6bc67ea ]---
list fucked in head
Unable to handle kernel paging request at virtual address 0000880000fffffc
Mem abort info:
ESR = 0x96000004
Exception class = DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
Data abort info:
ISV = 0, ISS = 0x00000004
CM = 0, WnR = 0
user pgtable: 4k pages, 48-bit VAs, pgdp=000000003ba5d000
[0000880000fffffc] pgd=0000000000000000
Internal error: Oops: 96000004 [#4] SMP
CPU: 4 PID: 2658 Comm: git Tainted: G D 5.2.0-rc5 #1
Hardware name: Sapphire-RK3399 Board (DT)
pstate: 60000005 (nZCv daif -PAN -UAO)
pc : __d_lookup_rcu+0x90/0x1e8
lr : __d_lookup_rcu+0x84/0x1e8
sp : ffff00001363ba90
x29: ffff00001363ba90 x28: ffff00001363bb5c
x27: 0000000000000000 x26: ffff00001363bc78
x25: 00000010cb63a9bb x24: 0000880000fffff8
x23: 0000000001000000 x22: ffff80003be53180
x21: ffff80003be53180 x20: 0000880000fffff8
x19: 0000880001000000 x18: 0000000000000000
x17: 0000000000000000 x16: 0000000000000000
x15: 0000000000000000 x14: 0000000000000000
x13: 0000000000000000 x12: 0000000000000000
x11: 0000000000000000 x10: ffffffffffffffff
x9 : 00000000cb63a9bb x8 : ffff80004b94d02e
x7 : 0000000000000010 x6 : ffff00001090454b
x5 : 0000000000000013 x4 : 0000000000000000
x3 : 0000000000000000 x2 : 00000000ffffffff
x1 : 00008000e6f46000 x0 : 0000000000000013
Call trace:
__d_lookup_rcu+0x90/0x1e8
lookup_fast+0x44/0x300
walk_component+0x34/0x2e0
path_lookupat.isra.13+0x5c/0x1e0
filename_lookup.part.19+0x6c/0xe8
user_path_at_empty+0x4c/0x60
vfs_statx+0x78/0xd8
__se_sys_newfstatat+0x24/0x48
__arm64_sys_newfstatat+0x18/0x20
el0_svc_handler+0x94/0x138
el0_svc+0x8/0xc
Code: 94000753 294c1fe9 9280000a f94037e8 (b85fc263)
---[ end trace 93a444e9b6bc67eb ]---
list fucked in head
Unable to handle kernel paging request at virtual address 0000000001000018
Mem abort info:
ESR = 0x96000004
Exception class = DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
Data abort info:
ISV = 0, ISS = 0x00000004
CM = 0, WnR = 0
user pgtable: 4k pages, 48-bit VAs, pgdp=000000002091a000
[0000000001000018] pgd=0000000000000000
Internal error: Oops: 96000004 [#5] SMP
CPU: 4 PID: 3205 Comm: update_all_gits Tainted: G D
5.2.0-rc5 #1
Hardware name: Sapphire-RK3399 Board (DT)
pstate: 60000005 (nZCv daif -PAN -UAO)
pc : __d_lookup+0x88/0x1d8
lr : __d_lookup+0x7c/0x1d8
sp : ffff000013dabaa0
x29: ffff000013dabaa0 x28: ffff000013dabbd8
x27: ffff00001076f0f8 x26: ffff8000f2808780
x25: 0000000000fffff8 x24: 0000000001000000
x23: 00000000cb639d51 x22: 0000000000000000
x21: 0000000000000001 x20: 0000000000fffff8
x19: 0000000001000000 x18: 0000000000000000
x17: 0000000000000000 x16: 0000000000000000
x15: ffffffffffffffff x14: ffff000010898508
x13: ffff000013dabbf8 x12: ffff000013dabbed
x11: 0000000000000001 x10: ffff000013daba60
x9 : ffff000013daba60 x8 : ffff000013daba60
x7 : ffff000013daba60 x6 : ffffffffffffffff
x5 : 0000000000000000 x4 : 0000000000000000
x3 : 0000000000000000 x2 : 00000000ffffffff
x1 : 00008000e6f46000 x0 : 0000000000000013
Call trace:
__d_lookup+0x88/0x1d8
d_lookup+0x34/0x68
d_hash_and_lookup+0x50/0x68
proc_flush_task+0x9c/0x198
release_task.part.3+0x68/0x4b8
wait_consider_task+0x91c/0x9b0
do_wait+0x120/0x1e0
kernel_wait4+0x7c/0x140
__se_sys_wait4+0x68/0xa8
__arm64_sys_wait4+0x18/0x20
el0_svc_handler+0x94/0x138
el0_svc+0x8/0xc
Code: 940006db b9406fe5 92800006 d503201f (b9402282)
---[ end trace 93a444e9b6bc67ec ]---
list fucked in head
Unable to handle kernel paging request at virtual address 0000880101000018
Mem abort info:
ESR = 0x96000004
Exception class = DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
Data abort info:
ISV = 0, ISS = 0x00000004
CM = 0, WnR = 0
user pgtable: 4k pages, 48-bit VAs, pgdp=000000009bddd000
[0000880101000018] pgd=0000000000000000
Internal error: Oops: 96000004 [#6] SMP
CPU: 5 PID: 3978 Comm: tar Tainted: G D 5.2.0-rc5 #1
Hardware name: Sapphire-RK3399 Board (DT)
pstate: 60000005 (nZCv daif -PAN -UAO)
pc : __d_lookup+0x88/0x1d8
lr : __d_lookup+0x7c/0x1d8
sp : ffff000014dc3b90
x29: ffff000014dc3b90 x28: ffff000014dc3d58
x27: ffff000014dc3d48 x26: ffff8000a77becc0
x25: 0000880100fffff8 x24: 0000000001000000
x23: 00000000c1086fd8 x22: 0000000000000000
x21: 0000000000000001 x20: 0000880100fffff8
x19: 0000880101000000 x18: 0000000000000000
x17: 0000000000000000 x16: 0000000000000000
x15: 0000000000000000 x14: 0000000000000000
x13: 0000000000000000 x12: 0000000000000000
x11: 0000000000000000 x10: ffff000014dc3b50
x9 : ffff000014dc3b50 x8 : ffff000014dc3b50
x7 : ffff000014dc3b50 x6 : ffffffffffffffff
x5 : 0000000000000000 x4 : 0000000000000000
x3 : 0000000000000000 x2 : 00000000ffffffff
x1 : 00008000e6f5a000 x0 : 0000000000000013
Call trace:
__d_lookup+0x88/0x1d8
d_lookup+0x34/0x68
path_openat+0x528/0xfd0
do_filp_open+0x60/0xc0
do_sys_open+0x164/0x200
__arm64_sys_openat+0x20/0x28
el0_svc_handler+0x94/0x138
el0_svc+0x8/0xc
Code: 940006db b9406fe5 92800006 d503201f (b9402282)
---[ end trace 93a444e9b6bc67ed ]---

0000000000002d10 <__d_lookup_rcu>:
{
2d10: a9b97bfd stp x29, x30, [sp, #-112]!
return dentry_hashtable + (hash >> d_hash_shift);
2d14: 90000003 adrp x3, 0 <d_shrink_del>
2d18: 91000065 add x5, x3, #0x0
{
2d1c: 910003fd mov x29, sp
2d20: a90153f3 stp x19, x20, [sp, #16]
2d24: a90363f7 stp x23, x24, [sp, #48]
2d28: a9046bf9 stp x25, x26, [sp, #64]
const unsigned char *str = name->name;
2d2c: a9402039 ldp x25, x8, [x1]
return dentry_hashtable + (hash >> d_hash_shift);
2d30: f9400064 ldr x4, [x3]
2d34: b94008a3 ldr w3, [x5, #8]
2d38: 1ac32723 lsr w3, w25, w3
__READ_ONCE_SIZE;
2d3c: f8637893 ldr x19, [x4, x3, lsl #3]
hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) {
2d40: f27ffa73 ands x19, x19, #0xfffffffffffffffe
2d44: 54000420 b.eq 2dc8 <__d_lookup_rcu+0xb8> // b.none
if (dentry_cmp(dentry, str, hashlen_len(hashlen)) != 0)
2d48: d360ff27 lsr x7, x25, #32
2d4c: 2a1903e9 mov w9, w25
2d50: aa0103fa mov x26, x1
2d54: a90573fb stp x27, x28, [sp, #80]
2d58: aa0203fc mov x28, x2
2d5c: 120008fb and w27, w7, #0x7
if (unlikely((u32)(unsigned long)&dentry->d_hash == 0x01000000))
2d60: 52a02017 mov w23, #0x1000000 // #16777216
mask = bytemask_from_count(tcount);
2d64: 9280000a mov x10, #0xffffffffffffffff // #-1
2d68: a9025bf5 stp x21, x22, [sp, #32]
2d6c: aa0003f5 mov x21, x0
struct dentry *dentry, *last = NULL;
2d70: d2800000 mov x0, #0x0 // #0
2d74: d503201f nop
hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) {
2d78: d1002274 sub x20, x19, #0x8
if (unlikely((u32)(unsigned long)&dentry->d_hash == 0x01000000))
2d7c: 6b17027f cmp w19, w23
hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) {
2d80: aa1403f8 mov x24, x20
if (unlikely((u32)(unsigned long)&dentry->d_hash == 0x01000000))
2d84: 540000e1 b.ne 2da0 <__d_lookup_rcu+0x90> // b.any
2d88: 290c1fe9 stp w9, w7, [sp, #96]
2d8c: f90037e8 str x8, [sp, #104]
dump(last);
2d90: 94000000 bl 0 <d_shrink_del>
2d94: 294c1fe9 ldp w9, w7, [sp, #96]
2d98: 9280000a mov x10, #0xffffffffffffffff // #-1
2d9c: f94037e8 ldr x8, [sp, #104]
2da0: b85fc263 ldur w3, [x19, #-4]
smp_rmb();
2da4: d50339bf dmb ishld
if (dentry->d_parent != parent)
2da8: f9400e80 ldr x0, [x20, #24]
2dac: eb15001f cmp x0, x21
2db0: 540001a0 b.eq 2de4 <__d_lookup_rcu+0xd4> // b.none
2db4: f9400273 ldr x19, [x19]
hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) {
2db8: aa1403e0 mov x0, x20
2dbc: b5fffdf3 cbnz x19, 2d78 <__d_lookup_rcu+0x68>
2dc0: a9425bf5 ldp x21, x22, [sp, #32]
2dc4: a94573fb ldp x27, x28, [sp, #80]
return NULL;
2dc8: d2800018 mov x24, #0x0 // #0
}
2dcc: aa1803e0 mov x0, x24
2dd0: a94153f3 ldp x19, x20, [sp, #16]
2dd4: a94363f7 ldp x23, x24, [sp, #48]
2dd8: a9446bf9 ldp x25, x26, [sp, #64]
2ddc: a8c77bfd ldp x29, x30, [sp], #112
2de0: d65f03c0 ret
if (d_unhashed(dentry))
2de4: f9400660 ldr x0, [x19, #8]
2de8: b4fffe60 cbz x0, 2db4 <__d_lookup_rcu+0xa4>
if (unlikely(parent->d_flags & DCACHE_OP_COMPARE)) {
2dec: b94002a0 ldr w0, [x21]
return ret & ~1;
2df0: 121f7876 and w22, w3, #0xfffffffe
2df4: 370804a0 tbnz w0, #1, 2e88 <__d_lookup_rcu+0x178>
if (dentry->d_name.hash_len != hashlen)
2df8: f9401280 ldr x0, [x20, #32]
2dfc: eb19001f cmp x0, x25
2e00: 54fffda1 b.ne 2db4 <__d_lookup_rcu+0xa4> // b.any
2e04: f9401264 ldr x4, [x19, #32]
const unsigned char *cs = READ_ONCE(dentry->d_name.name);
2e08: 2a0703e5 mov w5, w7
2e0c: cb040101 sub x1, x8, x4
2e10: 14000006 b 2e28 <__d_lookup_rcu+0x118>
cs += sizeof(unsigned long);
2e14: 91002084 add x4, x4, #0x8
if (unlikely(a != b))
2e18: eb06001f cmp x0, x6
2e1c: 54fffcc1 b.ne 2db4 <__d_lookup_rcu+0xa4> // b.any
if (!tcount)
2e20: 710020a5 subs w5, w5, #0x8
2e24: 54000160 b.eq 2e50 <__d_lookup_rcu+0x140> // b.none
cs += sizeof(unsigned long);
2e28: 8b010083 add x3, x4, x1
if (tcount < sizeof(unsigned long))
2e2c: 6b1b00bf cmp w5, w27
static inline unsigned long load_unaligned_zeropad(const void *addr)
{
unsigned long ret, offset;

/* Load word from unaligned pointer addr */
asm(
2e30: f9400066 ldr x6, [x3]

static __no_kasan_or_inline
unsigned long read_word_at_a_time(const void *addr)
{
kasan_check_read(addr, 1);
return *(unsigned long *)addr;
2e34: f9400080 ldr x0, [x4]
2e38: 54fffee1 b.ne 2e14 <__d_lookup_rcu+0x104> // b.any
mask = bytemask_from_count(tcount);
2e3c: 531d7361 lsl w1, w27, #3
return unlikely(!!((a ^ b) & mask));
2e40: ca060000 eor x0, x0, x6
mask = bytemask_from_count(tcount);
2e44: 9ac12141 lsl x1, x10, x1
if (dentry_cmp(dentry, str, hashlen_len(hashlen)) != 0)
2e48: ea21001f bics xzr, x0, x1
2e4c: 54fffb41 b.ne 2db4 <__d_lookup_rcu+0xa4> // b.any
*seqp = seq;
2e50: b9000396 str w22, [x28]
}
2e54: aa1803e0 mov x0, x24
2e58: a94153f3 ldp x19, x20, [sp, #16]
return dentry;
2e5c: a9425bf5 ldp x21, x22, [sp, #32]
}
2e60: a94363f7 ldp x23, x24, [sp, #48]
2e64: a9446bf9 ldp x25, x26, [sp, #64]
return dentry;
2e68: a94573fb ldp x27, x28, [sp, #80]
}
2e6c: a8c77bfd ldp x29, x30, [sp], #112
2e70: d65f03c0 ret
if (d_unhashed(dentry))
2e74: f9400660 ldr x0, [x19, #8]
2e78: 121f7876 and w22, w3, #0xfffffffe
2e7c: b4fff9c0 cbz x0, 2db4 <__d_lookup_rcu+0xa4>
if (unlikely(parent->d_flags & DCACHE_OP_COMPARE)) {
2e80: b94002a0 ldr w0, [x21]
2e84: 360ffba0 tbz w0, #1, 2df8 <__d_lookup_rcu+0xe8>
if (dentry->d_name.hash != hashlen_hash(hashlen))
2e88: b9402280 ldr w0, [x20, #32]
2e8c: 6b00013f cmp w9, w0
2e90: 54fff921 b.ne 2db4 <__d_lookup_rcu+0xa4> // b.any
tlen = dentry->d_name.len;
2e94: b9402681 ldr w1, [x20, #36]
tname = dentry->d_name.name;
2e98: f9401682 ldr x2, [x20, #40]
smp_rmb();
2e9c: d50339bf dmb ishld
return unlikely(s->sequence != start);
2ea0: b85fc260 ldur w0, [x19, #-4]
if (read_seqcount_retry(&dentry->d_seq, seq)) {
2ea4: 6b0002df cmp w22, w0
2ea8: 54000100 b.eq 2ec8 <__d_lookup_rcu+0x1b8> // b.none
2eac: d503203f yield
__READ_ONCE_SIZE;
2eb0: b85fc263 ldur w3, [x19, #-4]
smp_rmb();
2eb4: d50339bf dmb ishld
if (dentry->d_parent != parent)
2eb8: f9400e80 ldr x0, [x20, #24]
2ebc: eb15001f cmp x0, x21
2ec0: 54fff7a1 b.ne 2db4 <__d_lookup_rcu+0xa4> // b.any
2ec4: 17ffffec b 2e74 <__d_lookup_rcu+0x164>
if (parent->d_op->d_compare(dentry,
2ec8: f94032a4 ldr x4, [x21, #96]
2ecc: aa1a03e3 mov x3, x26
2ed0: aa1403e0 mov x0, x20
2ed4: 290c1fe9 stp w9, w7, [sp, #96]
2ed8: f90037e8 str x8, [sp, #104]
2edc: f9400c84 ldr x4, [x4, #24]
2ee0: d63f0080 blr x4
2ee4: 9280000a mov x10, #0xffffffffffffffff // #-1
2ee8: 294c1fe9 ldp w9, w7, [sp, #96]
2eec: f94037e8 ldr x8, [sp, #104]
2ef0: 34fffb00 cbz w0, 2e50 <__d_lookup_rcu+0x140>
2ef4: 17ffffb0 b 2db4 <__d_lookup_rcu+0xa4>

0000000000002ef8 <__d_lookup>:
{
2ef8: a9b97bfd stp x29, x30, [sp, #-112]!
return dentry_hashtable + (hash >> d_hash_shift);
2efc: 90000002 adrp x2, 0 <d_shrink_del>
2f00: 91000044 add x4, x2, #0x0
{
2f04: 910003fd mov x29, sp
2f08: a90153f3 stp x19, x20, [sp, #16]
2f0c: a90363f7 stp x23, x24, [sp, #48]
2f10: a9046bf9 stp x25, x26, [sp, #64]
return dentry_hashtable + (hash >> d_hash_shift);
2f14: f9400043 ldr x3, [x2]
unsigned int hash = name->hash;
2f18: b9400037 ldr w23, [x1]
return dentry_hashtable + (hash >> d_hash_shift);
2f1c: b9400882 ldr w2, [x4, #8]
2f20: 1ac226e2 lsr w2, w23, w2
2f24: f8627873 ldr x19, [x3, x2, lsl #3]
hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) {
2f28: f27ffa73 ands x19, x19, #0xfffffffffffffffe
2f2c: 54000520 b.eq 2fd0 <__d_lookup+0xd8> // b.none
2f30: aa0003fa mov x26, x0
2f34: a90573fb stp x27, x28, [sp, #80]
2f38: aa0103fc mov x28, x1
2f3c: d2800002 mov x2, #0x0 // #0
if (unlikely((u32)(unsigned long)&dentry->d_hash == 0x01000000))
2f40: 52a02018 mov w24, #0x1000000 // #16777216
smp_store_release(&lock->locked, 0);
2f44: 52800005 mov w5, #0x0 // #0
mask = bytemask_from_count(tcount);
2f48: 92800006 mov x6, #0xffffffffffffffff // #-1
2f4c: a9025bf5 stp x21, x22, [sp, #32]
2f50: d2800016 mov x22, #0x0 // #0
2f54: 52800035 mov w21, #0x1 // #1
hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) {
2f58: d1002274 sub x20, x19, #0x8
if (unlikely((u32)(unsigned long)&dentry->d_hash == 0x01000000))
2f5c: 6b18027f cmp w19, w24
hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) {
2f60: aa1403f9 mov x25, x20
if (unlikely((u32)(unsigned long)&dentry->d_hash == 0x01000000))
2f64: 540000e1 b.ne 2f80 <__d_lookup+0x88> // b.any
dump(last);
2f68: aa0203e0 mov x0, x2
2f6c: b9006fe5 str w5, [sp, #108]
2f70: 94000000 bl 0 <d_shrink_del>
2f74: b9406fe5 ldr w5, [sp, #108]
2f78: 92800006 mov x6, #0xffffffffffffffff // #-1
2f7c: d503201f nop
if (dentry->d_name.hash != hash)
2f80: b9402282 ldr w2, [x20, #32]
2f84: 6b17005f cmp w2, w23
2f88: 540001a1 b.ne 2fbc <__d_lookup+0xc4> // b.any
2f8c: 9101427b add x27, x19, #0x50
2f90: f9800371 prfm pstl1strm, [x27]
2f94: 885fff61 ldaxr w1, [x27]
2f98: 4a160020 eor w0, w1, w22
2f9c: 35000060 cbnz w0, 2fa8 <__d_lookup+0xb0>
2fa0: 88007f75 stxr w0, w21, [x27]
2fa4: 35ffff80 cbnz w0, 2f94 <__d_lookup+0x9c>
2fa8: 35000521 cbnz w1, 304c <__d_lookup+0x154>
if (dentry->d_parent != parent)
2fac: f9400e80 ldr x0, [x20, #24]
2fb0: eb1a001f cmp x0, x26
2fb4: 540001c0 b.eq 2fec <__d_lookup+0xf4> // b.none
2fb8: 089fff65 stlrb w5, [x27]
2fbc: f9400273 ldr x19, [x19]
hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) {
2fc0: aa1403e2 mov x2, x20
2fc4: b5fffcb3 cbnz x19, 2f58 <__d_lookup+0x60>
2fc8: a9425bf5 ldp x21, x22, [sp, #32]
2fcc: a94573fb ldp x27, x28, [sp, #80]
struct dentry *found = NULL;
2fd0: d2800019 mov x25, #0x0 // #0
}
2fd4: aa1903e0 mov x0, x25
2fd8: a94153f3 ldp x19, x20, [sp, #16]
2fdc: a94363f7 ldp x23, x24, [sp, #48]
2fe0: a9446bf9 ldp x25, x26, [sp, #64]
2fe4: a8c77bfd ldp x29, x30, [sp], #112
2fe8: d65f03c0 ret
if (d_unhashed(dentry))
2fec: f9400660 ldr x0, [x19, #8]
2ff0: b4fffe40 cbz x0, 2fb8 <__d_lookup+0xc0>
if (likely(!(parent->d_flags & DCACHE_OP_COMPARE))) {
2ff4: b9400340 ldr w0, [x26]
2ff8: b9402681 ldr w1, [x20, #36]
2ffc: 37080340 tbnz w0, #1, 3064 <__d_lookup+0x16c>
if (dentry->d_name.len != name->len)
3000: b9400783 ldr w3, [x28, #4]
3004: 6b01007f cmp w3, w1
3008: 54fffd81 b.ne 2fb8 <__d_lookup+0xc0> // b.any
return dentry_cmp(dentry, name->name, name->len) == 0;
300c: f9400787 ldr x7, [x28, #8]
static inline int dentry_string_cmp(const unsigned char *cs, const unsigned
char *ct, unsigned tcount)
3010: 12000868 and w8, w3, #0x7
3014: f9401264 ldr x4, [x19, #32]
3018: cb0400e7 sub x7, x7, x4
301c: 14000003 b 3028 <__d_lookup+0x130>
if (!tcount)
3020: 71002063 subs w3, w3, #0x8
3024: 54000380 b.eq 3094 <__d_lookup+0x19c> // b.none
cs += sizeof(unsigned long);
3028: 8b070082 add x2, x4, x7
if (tcount < sizeof(unsigned long))
302c: 6b08007f cmp w3, w8
3030: f9400041 ldr x1, [x2]
return *(unsigned long *)addr;
3034: f9400080 ldr x0, [x4]
3038: 540003e0 b.eq 30b4 <__d_lookup+0x1bc> // b.none
cs += sizeof(unsigned long);
303c: 91002084 add x4, x4, #0x8
if (unlikely(a != b))
3040: eb01001f cmp x0, x1
3044: 54fffee0 b.eq 3020 <__d_lookup+0x128> // b.none
3048: 17ffffdc b 2fb8 <__d_lookup+0xc0>
queued_spin_lock_slowpath(lock, val);
304c: aa1b03e0 mov x0, x27
3050: b9006fe5 str w5, [sp, #108]
3054: 94000000 bl 0 <queued_spin_lock_slowpath>
3058: b9406fe5 ldr w5, [sp, #108]
305c: 92800006 mov x6, #0xffffffffffffffff // #-1
3060: 17ffffd3 b 2fac <__d_lookup+0xb4>
return parent->d_op->d_compare(dentry,
3064: f9403340 ldr x0, [x26, #96]
3068: aa1c03e3 mov x3, x28
306c: f9401682 ldr x2, [x20, #40]
3070: b9006fe5 str w5, [sp, #108]
3074: f9400c04 ldr x4, [x0, #24]
3078: aa1403e0 mov x0, x20
307c: d63f0080 blr x4
name) == 0;
3080: 7100001f cmp w0, #0x0
3084: 1a9f17e0 cset w0, eq // eq = none
3088: 92800006 mov x6, #0xffffffffffffffff // #-1
308c: b9406fe5 ldr w5, [sp, #108]
if (!d_same_name(dentry, parent, name))
3090: 34fff940 cbz w0, 2fb8 <__d_lookup+0xc0>
dentry->d_lockref.count++;
3094: b9405e80 ldr w0, [x20, #92]
smp_store_release(&lock->locked, 0);
3098: 52800001 mov w1, #0x0 // #0
309c: 11000400 add w0, w0, #0x1
30a0: b9005e80 str w0, [x20, #92]
30a4: 089fff61 stlrb w1, [x27]
preempt_enable();
30a8: a9425bf5 ldp x21, x22, [sp, #32]
30ac: a94573fb ldp x27, x28, [sp, #80]
30b0: 17ffffc9 b 2fd4 <__d_lookup+0xdc>
mask = bytemask_from_count(tcount);
30b4: 531d7062 lsl w2, w3, #3
return unlikely(!!((a ^ b) & mask));
30b8: ca010000 eor x0, x0, x1
mask = bytemask_from_count(tcount);
30bc: 9ac220c2 lsl x2, x6, x2
30c0: ea22001f bics xzr, x0, x2
30c4: 1a9f17e0 cset w0, eq // eq = none
if (!d_same_name(dentry, parent, name))
30c8: 34fff780 cbz w0, 2fb8 <__d_lookup+0xc0>
30cc: 17fffff2 b 3094 <__d_lookup+0x19c>

00000000000030d0 <d_lookup>:
{
30d0: a9bd7bfd stp x29, x30, [sp, #-48]!
30d4: 910003fd mov x29, sp
30d8: a90153f3 stp x19, x20, [sp, #16]
30dc: 90000014 adrp x20, 0 <d_shrink_del>
30e0: 91000294 add x20, x20, #0x0
30e4: a9025bf5 stp x21, x22, [sp, #32]
30e8: aa0003f6 mov x22, x0
30ec: aa0103f5 mov x21, x1
30f0: 1400000a b 3118 <d_lookup+0x48>
smp_rmb();
30f4: d50339bf dmb ishld
dentry = __d_lookup(parent, name);
30f8: aa1503e1 mov x1, x21
30fc: aa1603e0 mov x0, x22
3100: 94000000 bl 2ef8 <__d_lookup>
if (dentry)
3104: b5000120 cbnz x0, 3128 <d_lookup+0x58>
smp_rmb();
3108: d50339bf dmb ishld
} while (read_seqretry(&rename_lock, seq));
310c: b9400281 ldr w1, [x20]
3110: 6b13003f cmp w1, w19
3114: 540000a0 b.eq 3128 <d_lookup+0x58> // b.none
__READ_ONCE_SIZE;
3118: b9400293 ldr w19, [x20]
if (unlikely(ret & 1)) {
311c: 3607fed3 tbz w19, #0, 30f4 <d_lookup+0x24>
3120: d503203f yield
3124: 17fffffd b 3118 <d_lookup+0x48>
}
3128: a94153f3 ldp x19, x20, [sp, #16]
312c: a9425bf5 ldp x21, x22, [sp, #32]
3130: a8c37bfd ldp x29, x30, [sp], #48
3134: d65f03c0 ret

0000000000003138 <d_hash_and_lookup>:
{
3138: a9be7bfd stp x29, x30, [sp, #-32]!
313c: 910003fd mov x29, sp
3140: a90153f3 stp x19, x20, [sp, #16]
3144: aa0103f3 mov x19, x1
3148: aa0003f4 mov x20, x0
name->hash = full_name_hash(dir, name->name, name->len);
314c: b9400422 ldr w2, [x1, #4]
3150: f9400421 ldr x1, [x1, #8]
3154: 94000000 bl 0 <full_name_hash>
3158: b9000260 str w0, [x19]
if (dir->d_flags & DCACHE_OP_HASH) {
315c: b9400280 ldr w0, [x20]
3160: 360000e0 tbz w0, #0, 317c <d_hash_and_lookup+0x44>
int err = dir->d_op->d_hash(dir, name);
3164: f9403282 ldr x2, [x20, #96]
3168: aa1303e1 mov x1, x19
316c: aa1403e0 mov x0, x20
3170: f9400842 ldr x2, [x2, #16]
3174: d63f0040 blr x2
if (unlikely(err < 0))
3178: 37f800e0 tbnz w0, #31, 3194 <d_hash_and_lookup+0x5c>
return d_lookup(dir, name);
317c: aa1303e1 mov x1, x19
3180: aa1403e0 mov x0, x20
3184: 94000000 bl 30d0 <d_lookup>
}
3188: a94153f3 ldp x19, x20, [sp, #16]
318c: a8c27bfd ldp x29, x30, [sp], #32
3190: d65f03c0 ret
return ERR_PTR(err);
3194: 93407c00 sxtw x0, w0
3198: 17fffffc b 3188 <d_hash_and_lookup+0x50>
319c: d503201f nop

Disassembly of section .text.unlikely:

0000000000000000 <dump>:
{
0: a9bc7bfd stp x29, x30, [sp, #-64]!
4: 910003fd mov x29, sp
8: a90153f3 stp x19, x20, [sp, #16]
c: a9025bf5 stp x21, x22, [sp, #32]
10: f9001bf7 str x23, [sp, #48]
if (!dentry) {
14: b50000a0 cbnz x0, 28 <dump+0x28>
printk(KERN_ERR "list fucked in head");
18: 90000000 adrp x0, 0 <dump>
1c: 91000000 add x0, x0, #0x0
20: 94000000 bl 0 <printk>
return;
24: 14000016 b 7c <dump+0x7c>
printk(KERN_ERR "fucked dentry[%p]: d_hash.next = %p, flags = %x, count =
%d",
28: aa0003f3 mov x19, x0
printk(KERN_CONT "%c%02x", i & 31 ? ' ' : '\n',
2c: 90000015 adrp x21, 0 <dump>
printk(KERN_ERR "fucked dentry[%p]: d_hash.next = %p, flags = %x, count =
%d",
30: 90000000 adrp x0, 0 <dump>
34: aa1303e1 mov x1, x19
38: 91000000 add x0, x0, #0x0
3c: d2800014 mov x20, #0x0 // #0
40: b9400263 ldr w3, [x19]
printk(KERN_CONT "%c%02x", i & 31 ? ' ' : '\n',
44: 52800157 mov w23, #0xa // #10
printk(KERN_ERR "fucked dentry[%p]: d_hash.next = %p, flags = %x, count =
%d",
48: b9405e64 ldr w4, [x19, #92]
printk(KERN_CONT "%c%02x", i & 31 ? ' ' : '\n',
4c: 52800416 mov w22, #0x20 // #32
printk(KERN_ERR "fucked dentry[%p]: d_hash.next = %p, flags = %x, count =
%d",
50: f9400662 ldr x2, [x19, #8]
printk(KERN_CONT "%c%02x", i & 31 ? ' ' : '\n',
54: 910002b5 add x21, x21, #0x0
printk(KERN_ERR "fucked dentry[%p]: d_hash.next = %p, flags = %x, count =
%d",
58: 94000000 bl 0 <printk>
printk(KERN_CONT "%c%02x", i & 31 ? ' ' : '\n',
5c: 38746a62 ldrb w2, [x19, x20]
60: f240129f tst x20, #0x1f
64: 1a9602e1 csel w1, w23, w22, eq // eq = none
68: 91000694 add x20, x20, #0x1
6c: aa1503e0 mov x0, x21
70: 94000000 bl 0 <printk>
for (i = 0; i < sizeof(struct dentry); i++)
74: f103029f cmp x20, #0xc0
78: 54ffff21 b.ne 5c <dump+0x5c> // b.any
}
7c: a94153f3 ldp x19, x20, [sp, #16]
80: a9425bf5 ldp x21, x22, [sp, #32]
84: f9401bf7 ldr x23, [sp, #48]
88: a8c47bfd ldp x29, x30, [sp], #64
8c: d65f03c0 ret