* Re: [PATCH net] nexthop: use nlmsg_parse_deprecated()
From: David Ahern @ 2019-08-12 12:44 UTC (permalink / raw)
To: Eric Dumazet, David S . Miller; +Cc: netdev, Eric Dumazet, syzbot
In-Reply-To: <20190812113616.51725-1-edumazet@google.com>
On 8/12/19 5:36 AM, Eric Dumazet wrote:
> David missed that commit 8cb081746c03 ("netlink: make validation
> more configurable for future strictness") has renamed nlmsg_parse()
Thanks for the report, Eric. It is quite likely I overlooked something
with that rename given the timing. However, the nexthop code being a new
feature is expected to use all of the strict parsing and checking. I can
take a look at this later today.
^ permalink raw reply
* Re: [PATCH 2/3] ocelot_ace: fix ingress ports setting for rule
From: Allan W. Nielsen @ 2019-08-12 12:38 UTC (permalink / raw)
To: Yangbo Lu
Cc: netdev, David S . Miller, Alexandre Belloni,
Microchip Linux Driver Support
In-Reply-To: <20190812104827.5935-3-yangbo.lu@nxp.com>
The 08/12/2019 18:48, Yangbo Lu wrote:
> The ingress ports setting of rule should support covering all ports.
> This patch is to use u16 ingress_port for ingress port mask setting
> for ace rule. One bit corresponds one port.
That is how the HW is working, and it would be nice if we could operate on a
port masks/lists instead. But how can this be used?
Can you please explain how/when this will make a difference?
> Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
> ---
> drivers/net/ethernet/mscc/ocelot_ace.c | 2 +-
> drivers/net/ethernet/mscc/ocelot_ace.h | 2 +-
> drivers/net/ethernet/mscc/ocelot_flower.c | 2 +-
> 3 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c b/drivers/net/ethernet/mscc/ocelot_ace.c
> index 5580a58..91250f3 100644
> --- a/drivers/net/ethernet/mscc/ocelot_ace.c
> +++ b/drivers/net/ethernet/mscc/ocelot_ace.c
> @@ -352,7 +352,7 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
> data.type = IS2_ACTION_TYPE_NORMAL;
>
> VCAP_KEY_ANY_SET(PAG);
> - VCAP_KEY_SET(IGR_PORT_MASK, 0, ~BIT(ace->chip_port));
> + VCAP_KEY_SET(IGR_PORT_MASK, 0, ~ace->ingress_port);
> VCAP_KEY_BIT_SET(FIRST, OCELOT_VCAP_BIT_1);
> VCAP_KEY_BIT_SET(HOST_MATCH, OCELOT_VCAP_BIT_ANY);
> VCAP_KEY_BIT_SET(L2_MC, ace->dmac_mc);
> diff --git a/drivers/net/ethernet/mscc/ocelot_ace.h b/drivers/net/ethernet/mscc/ocelot_ace.h
> index ce72f02..0fe23e0 100644
> --- a/drivers/net/ethernet/mscc/ocelot_ace.h
> +++ b/drivers/net/ethernet/mscc/ocelot_ace.h
> @@ -193,7 +193,7 @@ struct ocelot_ace_rule {
>
> enum ocelot_ace_action action;
> struct ocelot_ace_stats stats;
> - int chip_port;
> + u16 ingress_port;
>
> enum ocelot_vcap_bit dmac_mc;
> enum ocelot_vcap_bit dmac_bc;
> diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c b/drivers/net/ethernet/mscc/ocelot_flower.c
> index 7c60e8c..bfddc50 100644
> --- a/drivers/net/ethernet/mscc/ocelot_flower.c
> +++ b/drivers/net/ethernet/mscc/ocelot_flower.c
> @@ -184,7 +184,7 @@ struct ocelot_ace_rule *ocelot_ace_rule_create(struct flow_cls_offload *f,
> return NULL;
>
> rule->ocelot = block->port->ocelot;
> - rule->chip_port = block->port->chip_port;
> + rule->ingress_port = BIT(block->port->chip_port);
> return rule;
> }
-- Allan
^ permalink raw reply
* INFO: rcu detected stall in inet6_sendmsg
From: syzbot @ 2019-08-12 12:32 UTC (permalink / raw)
To: davem, edumazet, linux-kernel, netdev, soheil, syzkaller-bugs
Hello,
syzbot found the following crash on:
HEAD commit: b1645c0c Add linux-next specific files for 20190805
git tree: linux-next
console output: https://syzkaller.appspot.com/x/log.txt?x=116e598a600000
kernel config: https://syzkaller.appspot.com/x/.config?x=b837e78be990c60a
dashboard link: https://syzkaller.appspot.com/bug?extid=2461d4a2bb70325dcdab
compiler: gcc (GCC) 9.0.0 20181231 (experimental)
Unfortunately, I don't have any reproducer for this crash yet.
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+2461d4a2bb70325dcdab@syzkaller.appspotmail.com
rcu: INFO: rcu_preempt detected stalls on CPUs/tasks:
(detected by 0, t=10502 jiffies, g=33389, q=24)
rcu: All QSes seen, last rcu_preempt kthread activity 10503
(4294976899-4294966396), jiffies_till_next_fqs=1, root ->qsmask 0x0
syz-executor.0 R running task 25096 17466 10161 0x0000400e
Call Trace:
<IRQ>
sched_show_task kernel/sched/core.c:5814 [inline]
sched_show_task.cold+0x2ed/0x34e kernel/sched/core.c:5789
print_other_cpu_stall kernel/rcu/tree_stall.h:410 [inline]
check_cpu_stall kernel/rcu/tree_stall.h:536 [inline]
rcu_pending kernel/rcu/tree.c:2736 [inline]
rcu_sched_clock_irq.cold+0xac8/0xc13 kernel/rcu/tree.c:2183
update_process_times+0x32/0x80 kernel/time/timer.c:1724
tick_sched_handle+0xa2/0x190 kernel/time/tick-sched.c:167
tick_sched_timer+0x53/0x140 kernel/time/tick-sched.c:1299
__run_hrtimer kernel/time/hrtimer.c:1493 [inline]
__hrtimer_run_queues+0x364/0xe40 kernel/time/hrtimer.c:1555
hrtimer_interrupt+0x314/0x770 kernel/time/hrtimer.c:1617
local_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1068 [inline]
smp_apic_timer_interrupt+0x160/0x610 arch/x86/kernel/apic/apic.c:1093
apic_timer_interrupt+0xf/0x20 arch/x86/entry/entry_64.S:828
</IRQ>
RIP: 0010:check_memory_region+0x1f/0x1a0 mm/kasan/generic.c:191
Code: 00 66 2e 0f 1f 84 00 00 00 00 00 48 85 f6 0f 84 34 01 00 00 48 b8 ff
ff ff ff ff 7f ff ff 55 0f b6 d2 48 39 c7 48 89 e5 41 55 <41> 54 53 0f 86
07 01 00 00 4c 8d 5c 37 ff 49 89 f8 48 b8 00 00 00
RSP: 0018:ffff88805be977b8 EFLAGS: 00000216 ORIG_RAX: ffffffffffffff13
RAX: ffff7fffffffffff RBX: ffff8880625080c8 RCX: ffffffff8158f457
RDX: 0000000000000000 RSI: 0000000000000004 RDI: ffff8880625080c8
RBP: ffff88805be977c0 R08: 1ffff1100c4a1019 R09: ffffed100c4a101a
R10: ffffed100c4a1019 R11: ffff8880625080cb R12: 0000000000000001
R13: 0000000000000003 R14: ffffed100c4a1019 R15: 0000000000000001
__kasan_check_read+0x11/0x20 mm/kasan/common.c:92
atomic_read include/asm-generic/atomic-instrumented.h:26 [inline]
virt_spin_lock arch/x86/include/asm/qspinlock.h:83 [inline]
native_queued_spin_lock_slowpath+0xb7/0x9f0 kernel/locking/qspinlock.c:325
pv_queued_spin_lock_slowpath arch/x86/include/asm/paravirt.h:642 [inline]
queued_spin_lock_slowpath arch/x86/include/asm/qspinlock.h:50 [inline]
queued_spin_lock include/asm-generic/qspinlock.h:81 [inline]
do_raw_spin_lock+0x20e/0x2e0 kernel/locking/spinlock_debug.c:113
__raw_spin_lock_bh include/linux/spinlock_api_smp.h:136 [inline]
_raw_spin_lock_bh+0x3b/0x50 kernel/locking/spinlock.c:175
spin_lock_bh include/linux/spinlock.h:343 [inline]
lock_sock_nested+0x41/0x120 net/core/sock.c:2917
lock_sock include/net/sock.h:1522 [inline]
sk_stream_wait_memory+0x83f/0xfc0 net/core/stream.c:149
tls_sw_sendmsg+0x673/0x17b0 net/tls/tls_sw.c:1054
inet6_sendmsg+0x9e/0xe0 net/ipv6/af_inet6.c:576
sock_sendmsg_nosec net/socket.c:637 [inline]
sock_sendmsg+0xd7/0x130 net/socket.c:657
__sys_sendto+0x262/0x380 net/socket.c:1952
__do_sys_sendto net/socket.c:1964 [inline]
__se_sys_sendto net/socket.c:1960 [inline]
__x64_sys_sendto+0xe1/0x1a0 net/socket.c:1960
do_syscall_64+0xfa/0x760 arch/x86/entry/common.c:290
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x459829
Code: fd b7 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7
48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff
ff 0f 83 cb b7 fb ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:00007f1c16940c78 EFLAGS: 00000246 ORIG_RAX: 000000000000002c
RAX: ffffffffffffffda RBX: 0000000000000006 RCX: 0000000000459829
RDX: ffffffffffffffc1 RSI: 00000000200005c0 RDI: 0000000000000004
RBP: 000000000075bf20 R08: 0000000000000000 R09: 1201000000003618
R10: 0000000000000000 R11: 0000000000000246 R12: 00007f1c169416d4
R13: 00000000004c77d9 R14: 00000000004dcf90 R15: 00000000ffffffff
rcu: rcu_preempt kthread starved for 10547 jiffies! g33389 f0x2
RCU_GP_WAIT_FQS(5) ->state=0x0 ->cpu=1
rcu: RCU grace-period kthread stack dump:
rcu_preempt R running task 29688 10 2 0x80004000
Call Trace:
context_switch kernel/sched/core.c:3254 [inline]
__schedule+0x755/0x15b0 kernel/sched/core.c:3921
schedule+0xa8/0x270 kernel/sched/core.c:3985
schedule_timeout+0x486/0xc50 kernel/time/timer.c:1893
rcu_gp_fqs_loop kernel/rcu/tree.c:1611 [inline]
rcu_gp_kthread+0x9b2/0x18c0 kernel/rcu/tree.c:1768
kthread+0x361/0x430 kernel/kthread.c:255
ret_from_fork+0x24/0x30 arch/x86/entry/entry_64.S:352
---
This bug is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.
syzbot will keep track of this bug report. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
^ permalink raw reply
* Re: [PATCH 3/3] ocelot_ace: fix action of trap
From: Allan W. Nielsen @ 2019-08-12 12:31 UTC (permalink / raw)
To: Yangbo Lu
Cc: netdev, David S . Miller, Alexandre Belloni,
Microchip Linux Driver Support
In-Reply-To: <20190812104827.5935-4-yangbo.lu@nxp.com>
The 08/12/2019 18:48, Yangbo Lu wrote:
> The trap action should be copying the frame to CPU and
> dropping it for forwarding, but current setting was just
> copying frame to CPU.
Are there any actions which do a "copy-to-cpu" and still forward the frame in
HW?
> Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
> ---
> drivers/net/ethernet/mscc/ocelot_ace.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c b/drivers/net/ethernet/mscc/ocelot_ace.c
> index 91250f3..59ad590 100644
> --- a/drivers/net/ethernet/mscc/ocelot_ace.c
> +++ b/drivers/net/ethernet/mscc/ocelot_ace.c
> @@ -317,9 +317,9 @@ static void is2_action_set(struct vcap_data *data,
> break;
> case OCELOT_ACL_ACTION_TRAP:
> VCAP_ACT_SET(PORT_MASK, 0x0);
> - VCAP_ACT_SET(MASK_MODE, 0x0);
> - VCAP_ACT_SET(POLICE_ENA, 0x0);
> - VCAP_ACT_SET(POLICE_IDX, 0x0);
> + VCAP_ACT_SET(MASK_MODE, 0x1);
> + VCAP_ACT_SET(POLICE_ENA, 0x1);
> + VCAP_ACT_SET(POLICE_IDX, OCELOT_POLICER_DISCARD);
This seems wrong. The policer is used to ensure that traffic are discarded, even
in the case where other users of the code has requested it to go to the CPU.
Are you sure this is working? If it is working, then I fear we have an issue
with the DROP action which uses this to discard frames.
> VCAP_ACT_SET(CPU_QU_NUM, 0x0);
> VCAP_ACT_SET(CPU_COPY_ENA, 0x1);
> break;
> --
> 2.7.4
--
/Allan
^ permalink raw reply
* WARNING in xfrm_policy_inexact_insert
From: syzbot @ 2019-08-12 12:30 UTC (permalink / raw)
To: davem, herbert, linux-kernel, netdev, steffen.klassert,
syzkaller-bugs
Hello,
syzbot found the following crash on:
HEAD commit: 296d05cb Merge tag 'riscv/for-v5.3-rc4' of git://git.kerne..
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=163917c2600000
kernel config: https://syzkaller.appspot.com/x/.config?x=2031e7d221391b8a
dashboard link: https://syzkaller.appspot.com/bug?extid=0ffe44015de138d98e79
compiler: clang version 9.0.0 (/home/glider/llvm/clang
80fee25776c2fb61e74c1ecb1a523375c2500b69)
Unfortunately, I don't have any reproducer for this crash yet.
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+0ffe44015de138d98e79@syzkaller.appspotmail.com
------------[ cut here ]------------
WARNING: CPU: 1 PID: 907 at net/xfrm/xfrm_policy.c:1506
xfrm_policy_insert_inexact_list net/xfrm/xfrm_policy.c:1506 [inline]
WARNING: CPU: 1 PID: 907 at net/xfrm/xfrm_policy.c:1506
xfrm_policy_inexact_insert+0x102a/0x1540 net/xfrm/xfrm_policy.c:1195
Kernel panic - not syncing: panic_on_warn set ...
CPU: 1 PID: 907 Comm: syz-executor.2 Not tainted 5.3.0-rc3+ #72
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x1d8/0x2f8 lib/dump_stack.c:113
panic+0x25c/0x799 kernel/panic.c:219
__warn+0x22f/0x230 kernel/panic.c:576
report_bug+0x190/0x290 lib/bug.c:186
fixup_bug arch/x86/kernel/traps.c:179 [inline]
do_error_trap+0xd7/0x440 arch/x86/kernel/traps.c:272
do_invalid_op+0x36/0x40 arch/x86/kernel/traps.c:291
invalid_op+0x23/0x30 arch/x86/entry/entry_64.S:1028
RIP: 0010:xfrm_policy_insert_inexact_list net/xfrm/xfrm_policy.c:1506
[inline]
RIP: 0010:xfrm_policy_inexact_insert+0x102a/0x1540
net/xfrm/xfrm_policy.c:1195
Code: c1 03 38 c1 0f 8c 0a f7 ff ff 48 89 df e8 6e 3a 38 fb e9 fd f6 ff ff
e8 44 41 ff fa 48 c7 c7 82 bf 3a 88 31 c0 e8 e9 8a e8 fa <0f> 0b e9 b4 fc
ff ff 89 d9 80 e1 07 80 c1 03 38 c1 0f 8c 04 f7 ff
RSP: 0018:ffff888088ca78b0 EFLAGS: 00010246
RAX: 0000000000000024 RBX: ffff8880a752d8a0 RCX: 2f5cd5be3d6cb100
RDX: ffffc9000a35f000 RSI: 0000000000005caf RDI: 0000000000005cb0
RBP: ffff888088ca79b8 R08: ffffffff815cf524 R09: ffffed1015d66088
R10: ffffed1015d66088 R11: 0000000000000000 R12: 0000000000000000
R13: 0000000000000000 R14: dffffc0000000000 R15: 0000000000000000
xfrm_policy_insert+0xdf/0xce0 net/xfrm/xfrm_policy.c:1574
pfkey_spdadd+0xe47/0x1980 net/key/af_key.c:2325
pfkey_process net/key/af_key.c:2834 [inline]
pfkey_sendmsg+0xacd/0xeb0 net/key/af_key.c:3673
sock_sendmsg_nosec net/socket.c:637 [inline]
sock_sendmsg net/socket.c:657 [inline]
___sys_sendmsg+0x60d/0x910 net/socket.c:2311
__sys_sendmsg net/socket.c:2356 [inline]
__do_sys_sendmsg net/socket.c:2365 [inline]
__se_sys_sendmsg net/socket.c:2363 [inline]
__x64_sys_sendmsg+0x17c/0x200 net/socket.c:2363
do_syscall_64+0xfe/0x140 arch/x86/entry/common.c:296
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x459829
Code: fd b7 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7
48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff
ff 0f 83 cb b7 fb ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:00007fa22f5f1c78 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000000459829
RDX: 0000000000000000 RSI: 0000000020000180 RDI: 0000000000000003
RBP: 000000000075bf20 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00007fa22f5f26d4
R13: 00000000004c76ea R14: 00000000004dceb0 R15: 00000000ffffffff
Kernel Offset: disabled
Rebooting in 86400 seconds..
---
This bug is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.
syzbot will keep track of this bug report. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
^ permalink raw reply
* WARNING in aa_sock_msg_perm
From: syzbot @ 2019-08-12 12:30 UTC (permalink / raw)
To: jmorris, john.johansen, linux-kernel, linux-security-module,
netdev, serge, syzkaller-bugs
Hello,
syzbot found the following crash on:
HEAD commit: fcc32a21 liquidio: Use pcie_flr() instead of reimplementin..
git tree: net-next
console output: https://syzkaller.appspot.com/x/log.txt?x=11233726600000
kernel config: https://syzkaller.appspot.com/x/.config?x=d4cf1ffb87d590d7
dashboard link: https://syzkaller.appspot.com/bug?extid=cda1ac91660a61b51495
compiler: gcc (GCC) 9.0.0 20181231 (experimental)
Unfortunately, I don't have any reproducer for this crash yet.
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+cda1ac91660a61b51495@syzkaller.appspotmail.com
------------[ cut here ]------------
AppArmor WARN aa_sock_msg_perm: ((!sock)):
WARNING: CPU: 0 PID: 11187 at security/apparmor/lsm.c:920
aa_sock_msg_perm.isra.0+0xdd/0x170 security/apparmor/lsm.c:920
Kernel panic - not syncing: panic_on_warn set ...
CPU: 0 PID: 11187 Comm: kworker/0:5 Not tainted 5.3.0-rc3+ #124
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
Workqueue: krxrpcd rxrpc_peer_keepalive_worker
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x172/0x1f0 lib/dump_stack.c:113
panic+0x2dc/0x755 kernel/panic.c:219
__warn.cold+0x20/0x4c kernel/panic.c:576
report_bug+0x263/0x2b0 lib/bug.c:186
fixup_bug arch/x86/kernel/traps.c:179 [inline]
fixup_bug arch/x86/kernel/traps.c:174 [inline]
do_error_trap+0x11b/0x200 arch/x86/kernel/traps.c:272
do_invalid_op+0x37/0x50 arch/x86/kernel/traps.c:291
invalid_op+0x23/0x30 arch/x86/entry/entry_64.S:1028
RIP: 0010:aa_sock_msg_perm.isra.0+0xdd/0x170 security/apparmor/lsm.c:920
Code: 89 ef e8 66 e6 02 00 5b 41 5c 41 5d 41 5e 41 5f 5d c3 e8 16 25 68 fe
48 c7 c6 a0 8f c0 87 48 c7 c7 a0 7a c0 87 e8 db 97 39 fe <0f> 0b e9 43 ff
ff ff e8 f7 24 68 fe 48 c7 c6 a0 8f c0 87 48 c7 c7
RSP: 0018:ffff8880689f79b0 EFLAGS: 00010286
RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffffffff815c3ba6 RDI: ffffed100d13ef28
RBP: ffff8880689f79d8 R08: ffff88806916e300 R09: fffffbfff11b42c5
R10: fffffbfff11b42c4 R11: ffffffff88da1623 R12: ffff8880689f7b20
R13: ffffffff87c07ee0 R14: 0000000000000002 R15: 000000000000001d
apparmor_socket_sendmsg+0x2a/0x30 security/apparmor/lsm.c:936
security_socket_sendmsg+0x77/0xc0 security/security.c:1973
sock_sendmsg+0x45/0x130 net/socket.c:654
kernel_sendmsg+0x44/0x50 net/socket.c:677
rxrpc_send_keepalive+0x1ff/0x940 net/rxrpc/output.c:656
rxrpc_peer_keepalive_dispatch net/rxrpc/peer_event.c:369 [inline]
rxrpc_peer_keepalive_worker+0x7be/0xd02 net/rxrpc/peer_event.c:430
process_one_work+0x9af/0x1740 kernel/workqueue.c:2269
worker_thread+0x98/0xe40 kernel/workqueue.c:2415
kthread+0x361/0x430 kernel/kthread.c:255
ret_from_fork+0x24/0x30 arch/x86/entry/entry_64.S:352
Kernel Offset: disabled
Rebooting in 86400 seconds..
---
This bug is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.
syzbot will keep track of this bug report. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
^ permalink raw reply
* Re: [PATCH bpf-next v4 1/2] xsk: remove AF_XDP socket from map when the socket is released
From: Daniel Borkmann @ 2019-08-12 12:28 UTC (permalink / raw)
To: Björn Töpel, ast, netdev
Cc: Björn Töpel, magnus.karlsson, bruce.richardson,
songliubraving, bpf
In-Reply-To: <20190802081154.30962-2-bjorn.topel@gmail.com>
On 8/2/19 10:11 AM, Björn Töpel wrote:
> From: Björn Töpel <bjorn.topel@intel.com>
>
> When an AF_XDP socket is released/closed the XSKMAP still holds a
> reference to the socket in a "released" state. The socket will still
> use the netdev queue resource, and block newly created sockets from
> attaching to that queue, but no user application can access the
> fill/complete/rx/tx queues. This results in that all applications need
> to explicitly clear the map entry from the old "zombie state"
> socket. This should be done automatically.
>
> In this patch, the sockets tracks, and have a reference to, which maps
> it resides in. When the socket is released, it will remove itself from
> all maps.
>
> Suggested-by: Bruce Richardson <bruce.richardson@intel.com>
> Signed-off-by: Björn Töpel <bjorn.topel@intel.com>
[ Sorry for the review delay, was on PTO and catching up with things. ]
Overall looks good to me, I think better than previous versions. One question /
clarification for below:
> ---
> include/net/xdp_sock.h | 18 +++++++
> kernel/bpf/xskmap.c | 113 ++++++++++++++++++++++++++++++++++-------
> net/xdp/xsk.c | 48 +++++++++++++++++
> 3 files changed, 160 insertions(+), 19 deletions(-)
>
> diff --git a/include/net/xdp_sock.h b/include/net/xdp_sock.h
> index 69796d264f06..066e3ae446a8 100644
> --- a/include/net/xdp_sock.h
> +++ b/include/net/xdp_sock.h
> @@ -50,6 +50,16 @@ struct xdp_umem {
> struct list_head xsk_list;
> };
>
> +/* Nodes are linked in the struct xdp_sock map_list field, and used to
> + * track which maps a certain socket reside in.
> + */
> +struct xsk_map;
> +struct xsk_map_node {
> + struct list_head node;
> + struct xsk_map *map;
> + struct xdp_sock **map_entry;
> +};
> +
> struct xdp_sock {
> /* struct sock must be the first member of struct xdp_sock */
> struct sock sk;
> @@ -75,6 +85,9 @@ struct xdp_sock {
> /* Protects generic receive. */
> spinlock_t rx_lock;
> u64 rx_dropped;
> + struct list_head map_list;
> + /* Protects map_list */
> + spinlock_t map_list_lock;
> };
>
> struct xdp_buff;
> @@ -96,6 +109,11 @@ struct xdp_umem_fq_reuse *xsk_reuseq_swap(struct xdp_umem *umem,
> void xsk_reuseq_free(struct xdp_umem_fq_reuse *rq);
> struct xdp_umem *xdp_get_umem_from_qid(struct net_device *dev, u16 queue_id);
>
> +void xsk_map_try_sock_delete(struct xsk_map *map, struct xdp_sock *xs,
> + struct xdp_sock **map_entry);
> +int xsk_map_inc(struct xsk_map *map);
> +void xsk_map_put(struct xsk_map *map);
> +
> static inline char *xdp_umem_get_data(struct xdp_umem *umem, u64 addr)
> {
> return umem->pages[addr >> PAGE_SHIFT].addr + (addr & (PAGE_SIZE - 1));
> diff --git a/kernel/bpf/xskmap.c b/kernel/bpf/xskmap.c
> index 9bb96ace9fa1..780639309f6b 100644
> --- a/kernel/bpf/xskmap.c
> +++ b/kernel/bpf/xskmap.c
> @@ -13,8 +13,71 @@ struct xsk_map {
> struct bpf_map map;
> struct xdp_sock **xsk_map;
> struct list_head __percpu *flush_list;
> + spinlock_t lock; /* Synchronize map updates */
> };
>
> +int xsk_map_inc(struct xsk_map *map)
> +{
> + struct bpf_map *m = &map->map;
> +
> + m = bpf_map_inc(m, false);
> + return IS_ERR(m) ? PTR_ERR(m) : 0;
> +}
> +
> +void xsk_map_put(struct xsk_map *map)
> +{
> + bpf_map_put(&map->map);
> +}
> +
> +static struct xsk_map_node *xsk_map_node_alloc(struct xsk_map *map,
> + struct xdp_sock **map_entry)
> +{
> + struct xsk_map_node *node;
> + int err;
> +
> + node = kzalloc(sizeof(*node), GFP_ATOMIC | __GFP_NOWARN);
> + if (!node)
> + return NULL;
> +
> + err = xsk_map_inc(map);
> + if (err) {
> + kfree(node);
> + return ERR_PTR(err);
> + }
> +
> + node->map = map;
> + node->map_entry = map_entry;
> + return node;
> +}
> +
> +static void xsk_map_node_free(struct xsk_map_node *node)
> +{
> + xsk_map_put(node->map);
> + kfree(node);
> +}
> +
> +static void xsk_map_sock_add(struct xdp_sock *xs, struct xsk_map_node *node)
> +{
> + spin_lock_bh(&xs->map_list_lock);
> + list_add_tail(&node->node, &xs->map_list);
> + spin_unlock_bh(&xs->map_list_lock);
> +}
> +
> +static void xsk_map_sock_delete(struct xdp_sock *xs,
> + struct xdp_sock **map_entry)
> +{
> + struct xsk_map_node *n, *tmp;
> +
> + spin_lock_bh(&xs->map_list_lock);
> + list_for_each_entry_safe(n, tmp, &xs->map_list, node) {
> + if (map_entry == n->map_entry) {
> + list_del(&n->node);
> + xsk_map_node_free(n);
> + }
> + }
> + spin_unlock_bh(&xs->map_list_lock);
> +}
> +
> static struct bpf_map *xsk_map_alloc(union bpf_attr *attr)
> {
> struct xsk_map *m;
> @@ -34,6 +97,7 @@ static struct bpf_map *xsk_map_alloc(union bpf_attr *attr)
> return ERR_PTR(-ENOMEM);
>
> bpf_map_init_from_attr(&m->map, attr);
> + spin_lock_init(&m->lock);
>
> cost = (u64)m->map.max_entries * sizeof(struct xdp_sock *);
> cost += sizeof(struct list_head) * num_possible_cpus();
> @@ -71,21 +135,9 @@ static struct bpf_map *xsk_map_alloc(union bpf_attr *attr)
> static void xsk_map_free(struct bpf_map *map)
> {
> struct xsk_map *m = container_of(map, struct xsk_map, map);
> - int i;
>
> bpf_clear_redirect_map(map);
> synchronize_net();
> -
> - for (i = 0; i < map->max_entries; i++) {
> - struct xdp_sock *xs;
> -
> - xs = m->xsk_map[i];
> - if (!xs)
> - continue;
> -
> - sock_put((struct sock *)xs);
> - }
> -
> free_percpu(m->flush_list);
> bpf_map_area_free(m->xsk_map);
> kfree(m);
> @@ -165,7 +217,8 @@ static int xsk_map_update_elem(struct bpf_map *map, void *key, void *value,
> {
> struct xsk_map *m = container_of(map, struct xsk_map, map);
> u32 i = *(u32 *)key, fd = *(u32 *)value;
> - struct xdp_sock *xs, *old_xs;
> + struct xdp_sock *xs, *old_xs, **entry;
> + struct xsk_map_node *node;
> struct socket *sock;
> int err;
>
> @@ -192,11 +245,19 @@ static int xsk_map_update_elem(struct bpf_map *map, void *key, void *value,
> return -EOPNOTSUPP;
> }
>
> - sock_hold(sock->sk);
> + entry = &m->xsk_map[i];
> + node = xsk_map_node_alloc(m, entry);
> + if (IS_ERR(node)) {
> + sockfd_put(sock);
> + return PTR_ERR(node);
> + }
>
> - old_xs = xchg(&m->xsk_map[i], xs);
> + spin_lock_bh(&m->lock);
> + xsk_map_sock_add(xs, node);
> + old_xs = xchg(entry, xs);
> if (old_xs)
> - sock_put((struct sock *)old_xs);
> + xsk_map_sock_delete(old_xs, entry);
> + spin_unlock_bh(&m->lock);
>
> sockfd_put(sock);
> return 0;
> @@ -205,19 +266,33 @@ static int xsk_map_update_elem(struct bpf_map *map, void *key, void *value,
> static int xsk_map_delete_elem(struct bpf_map *map, void *key)
> {
> struct xsk_map *m = container_of(map, struct xsk_map, map);
> - struct xdp_sock *old_xs;
> + struct xdp_sock *old_xs, **map_entry;
> int k = *(u32 *)key;
>
> if (k >= map->max_entries)
> return -EINVAL;
>
> - old_xs = xchg(&m->xsk_map[k], NULL);
> + spin_lock_bh(&m->lock);
> + map_entry = &m->xsk_map[k];
> + old_xs = xchg(map_entry, NULL);
> if (old_xs)
> - sock_put((struct sock *)old_xs);
> + xsk_map_sock_delete(old_xs, map_entry);
> + spin_unlock_bh(&m->lock);
>
> return 0;
> }
>
> +void xsk_map_try_sock_delete(struct xsk_map *map, struct xdp_sock *xs,
> + struct xdp_sock **map_entry)
> +{
> + spin_lock_bh(&map->lock);
> + if (READ_ONCE(*map_entry) == xs) {
> + WRITE_ONCE(*map_entry, NULL);
> + xsk_map_sock_delete(xs, map_entry);
> + }
> + spin_unlock_bh(&map->lock);
> +}
> +
> const struct bpf_map_ops xsk_map_ops = {
> .map_alloc = xsk_map_alloc,
> .map_free = xsk_map_free,
> diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
> index 59b57d708697..c3447bad608a 100644
> --- a/net/xdp/xsk.c
> +++ b/net/xdp/xsk.c
> @@ -362,6 +362,50 @@ static void xsk_unbind_dev(struct xdp_sock *xs)
> dev_put(dev);
> }
>
> +static struct xsk_map *xsk_get_map_list_entry(struct xdp_sock *xs,
> + struct xdp_sock ***map_entry)
> +{
> + struct xsk_map *map = NULL;
> + struct xsk_map_node *node;
> +
> + *map_entry = NULL;
> +
> + spin_lock_bh(&xs->map_list_lock);
> + node = list_first_entry_or_null(&xs->map_list, struct xsk_map_node,
> + node);
> + if (node) {
> + WARN_ON(xsk_map_inc(node->map));
Can you elaborate on the refcount usage here and against what scenario it is protecting?
Do we pretend it never fails on the bpf_map_inc() wrt the WARN_ON(), why that (what
makes it different from the xsk_map_node_alloc() inc above where we do error out)?
> + map = node->map;
> + *map_entry = node->map_entry;
> + }
> + spin_unlock_bh(&xs->map_list_lock);
> + return map;
> +}
> +
> +static void xsk_delete_from_maps(struct xdp_sock *xs)
> +{
> + /* This function removes the current XDP socket from all the
> + * maps it resides in. We need to take extra care here, due to
> + * the two locks involved. Each map has a lock synchronizing
> + * updates to the entries, and each socket has a lock that
> + * synchronizes access to the list of maps (map_list). For
> + * deadlock avoidance the locks need to be taken in the order
> + * "map lock"->"socket map list lock". We start off by
> + * accessing the socket map list, and take a reference to the
> + * map to guarantee existence. Then we ask the map to remove
> + * the socket, which tries to remove the socket from the
> + * map. Note that there might be updates to the map between
> + * xsk_get_map_list_entry() and xsk_map_try_sock_delete().
> + */
> + struct xdp_sock **map_entry = NULL;
> + struct xsk_map *map;
> +
> + while ((map = xsk_get_map_list_entry(xs, &map_entry))) {
> + xsk_map_try_sock_delete(map, xs, map_entry);
> + xsk_map_put(map);
> + }
> +}
> +
> static int xsk_release(struct socket *sock)
> {
> struct sock *sk = sock->sk;
> @@ -381,6 +425,7 @@ static int xsk_release(struct socket *sock)
> sock_prot_inuse_add(net, sk->sk_prot, -1);
> local_bh_enable();
>
> + xsk_delete_from_maps(xs);
> xsk_unbind_dev(xs);
>
> xskq_destroy(xs->rx);
> @@ -855,6 +900,9 @@ static int xsk_create(struct net *net, struct socket *sock, int protocol,
> spin_lock_init(&xs->rx_lock);
> spin_lock_init(&xs->tx_completion_lock);
>
> + INIT_LIST_HEAD(&xs->map_list);
> + spin_lock_init(&xs->map_list_lock);
> +
> mutex_lock(&net->xdp.lock);
> sk_add_node_rcu(sk, &net->xdp.list);
> mutex_unlock(&net->xdp.lock);
>
Thanks,
Daniel
^ permalink raw reply
* [patch net-next] devlink: send notifications for deleted snapshots on region destroy
From: Jiri Pirko @ 2019-08-12 12:28 UTC (permalink / raw)
To: netdev; +Cc: davem, mlxsw
From: Jiri Pirko <jiri@mellanox.com>
Currently the notifications for deleted snapshots are sent only in case
user deletes a snapshot manually. Send the notifications in case region
is destroyed too.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
net/core/devlink.c | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/net/core/devlink.c b/net/core/devlink.c
index aba2d45f9087..d33284ac3e7c 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -379,14 +379,6 @@ devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id)
return NULL;
}
-static void devlink_region_snapshot_del(struct devlink_snapshot *snapshot)
-{
- snapshot->region->cur_snapshots--;
- list_del(&snapshot->list);
- (*snapshot->data_destructor)(snapshot->data);
- kfree(snapshot);
-}
-
#define DEVLINK_NL_FLAG_NEED_DEVLINK BIT(0)
#define DEVLINK_NL_FLAG_NEED_PORT BIT(1)
#define DEVLINK_NL_FLAG_NEED_SB BIT(2)
@@ -3677,6 +3669,16 @@ static void devlink_nl_region_notify(struct devlink_region *region,
nlmsg_free(msg);
}
+static void devlink_region_snapshot_del(struct devlink_region *region,
+ struct devlink_snapshot *snapshot)
+{
+ devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL);
+ region->cur_snapshots--;
+ list_del(&snapshot->list);
+ (*snapshot->data_destructor)(snapshot->data);
+ kfree(snapshot);
+}
+
static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb,
struct genl_info *info)
{
@@ -3772,8 +3774,7 @@ static int devlink_nl_cmd_region_del(struct sk_buff *skb,
if (!snapshot)
return -EINVAL;
- devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL);
- devlink_region_snapshot_del(snapshot);
+ devlink_region_snapshot_del(region, snapshot);
return 0;
}
@@ -6836,7 +6837,7 @@ void devlink_region_destroy(struct devlink_region *region)
/* Free all snapshots of region */
list_for_each_entry_safe(snapshot, ts, ®ion->snapshot_list, list)
- devlink_region_snapshot_del(snapshot);
+ devlink_region_snapshot_del(region, snapshot);
list_del(®ion->list);
--
2.21.0
^ permalink raw reply related
* Re: KASAN: slab-out-of-bounds Read in usbnet_generic_cdc_bind
From: Andrey Konovalov @ 2019-08-12 12:27 UTC (permalink / raw)
To: syzbot
Cc: David S. Miller, LKML, USB list, netdev, Oliver Neukum,
syzkaller-bugs, Alan Stern
In-Reply-To: <000000000000487b44058fea845c@google.com>
On Mon, Aug 12, 2019 at 2:18 PM syzbot
<syzbot+45a53506b65321c1fe91@syzkaller.appspotmail.com> wrote:
>
> Hello,
>
> syzbot found the following crash on:
>
> HEAD commit: e96407b4 usb-fuzzer: main usb gadget fuzzer driver
> git tree: https://github.com/google/kasan.git usb-fuzzer
> console output: https://syzkaller.appspot.com/x/log.txt?x=1390791c600000
> kernel config: https://syzkaller.appspot.com/x/.config?x=cfa2c18fb6a8068e
> dashboard link: https://syzkaller.appspot.com/bug?extid=45a53506b65321c1fe91
> compiler: gcc (GCC) 9.0.0 20181231 (experimental)
> syz repro: https://syzkaller.appspot.com/x/repro.syz?x=12c78cd2600000
> C reproducer: https://syzkaller.appspot.com/x/repro.c?x=1395b40e600000
>
> IMPORTANT: if you fix the bug, please add the following tag to the commit:
> Reported-by: syzbot+45a53506b65321c1fe91@syzkaller.appspotmail.com
>
> usb 1-1: config 1 interface 0 altsetting 0 has 0 endpoint descriptors,
> different from the interface descriptor's value: 18
> usb 1-1: New USB device found, idVendor=0525, idProduct=a4a1, bcdDevice=
> 0.40
> usb 1-1: New USB device strings: Mfr=6, Product=0, SerialNumber=0
> ==================================================================
> BUG: KASAN: slab-out-of-bounds in memcmp+0xa6/0xb0 lib/string.c:904
> Read of size 1 at addr ffff8881d4262f3b by task kworker/1:2/83
>
> CPU: 1 PID: 83 Comm: kworker/1:2 Not tainted 5.3.0-rc2+ #25
> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
> Google 01/01/2011
> Workqueue: usb_hub_wq hub_event
> Call Trace:
> __dump_stack lib/dump_stack.c:77 [inline]
> dump_stack+0xca/0x13e lib/dump_stack.c:113
> print_address_description+0x6a/0x32c mm/kasan/report.c:351
> __kasan_report.cold+0x1a/0x33 mm/kasan/report.c:482
> kasan_report+0xe/0x12 mm/kasan/common.c:612
> memcmp+0xa6/0xb0 lib/string.c:904
> memcmp include/linux/string.h:400 [inline]
> usbnet_generic_cdc_bind+0x71b/0x17c0 drivers/net/usb/cdc_ether.c:225
> usbnet_ether_cdc_bind drivers/net/usb/cdc_ether.c:322 [inline]
> usbnet_cdc_bind+0x20/0x1a0 drivers/net/usb/cdc_ether.c:430
> usbnet_probe+0xb43/0x23d0 drivers/net/usb/usbnet.c:1722
> usb_probe_interface+0x305/0x7a0 drivers/usb/core/driver.c:361
> really_probe+0x281/0x650 drivers/base/dd.c:548
> driver_probe_device+0x101/0x1b0 drivers/base/dd.c:709
> __device_attach_driver+0x1c2/0x220 drivers/base/dd.c:816
> bus_for_each_drv+0x15c/0x1e0 drivers/base/bus.c:454
> __device_attach+0x217/0x360 drivers/base/dd.c:882
> bus_probe_device+0x1e4/0x290 drivers/base/bus.c:514
> device_add+0xae6/0x16f0 drivers/base/core.c:2114
> usb_set_configuration+0xdf6/0x1670 drivers/usb/core/message.c:2023
> generic_probe+0x9d/0xd5 drivers/usb/core/generic.c:210
> usb_probe_device+0x99/0x100 drivers/usb/core/driver.c:266
> really_probe+0x281/0x650 drivers/base/dd.c:548
> driver_probe_device+0x101/0x1b0 drivers/base/dd.c:709
> __device_attach_driver+0x1c2/0x220 drivers/base/dd.c:816
> bus_for_each_drv+0x15c/0x1e0 drivers/base/bus.c:454
> __device_attach+0x217/0x360 drivers/base/dd.c:882
> bus_probe_device+0x1e4/0x290 drivers/base/bus.c:514
> device_add+0xae6/0x16f0 drivers/base/core.c:2114
> usb_new_device.cold+0x6a4/0xe79 drivers/usb/core/hub.c:2536
> hub_port_connect drivers/usb/core/hub.c:5098 [inline]
> hub_port_connect_change drivers/usb/core/hub.c:5213 [inline]
> port_event drivers/usb/core/hub.c:5359 [inline]
> hub_event+0x1b5c/0x3640 drivers/usb/core/hub.c:5441
> process_one_work+0x92b/0x1530 kernel/workqueue.c:2269
> worker_thread+0x96/0xe20 kernel/workqueue.c:2415
> kthread+0x318/0x420 kernel/kthread.c:255
> ret_from_fork+0x24/0x30 arch/x86/entry/entry_64.S:352
>
> Allocated by task 83:
> save_stack+0x1b/0x80 mm/kasan/common.c:69
> set_track mm/kasan/common.c:77 [inline]
> __kasan_kmalloc mm/kasan/common.c:487 [inline]
> __kasan_kmalloc.constprop.0+0xbf/0xd0 mm/kasan/common.c:460
> kmalloc include/linux/slab.h:557 [inline]
> usb_get_configuration+0x30c/0x3070 drivers/usb/core/config.c:857
> usb_enumerate_device drivers/usb/core/hub.c:2369 [inline]
> usb_new_device+0xd3/0x160 drivers/usb/core/hub.c:2505
> hub_port_connect drivers/usb/core/hub.c:5098 [inline]
> hub_port_connect_change drivers/usb/core/hub.c:5213 [inline]
> port_event drivers/usb/core/hub.c:5359 [inline]
> hub_event+0x1b5c/0x3640 drivers/usb/core/hub.c:5441
> process_one_work+0x92b/0x1530 kernel/workqueue.c:2269
> worker_thread+0x96/0xe20 kernel/workqueue.c:2415
> kthread+0x318/0x420 kernel/kthread.c:255
> ret_from_fork+0x24/0x30 arch/x86/entry/entry_64.S:352
>
> Freed by task 269:
> save_stack+0x1b/0x80 mm/kasan/common.c:69
> set_track mm/kasan/common.c:77 [inline]
> __kasan_slab_free+0x130/0x180 mm/kasan/common.c:449
> slab_free_hook mm/slub.c:1423 [inline]
> slab_free_freelist_hook mm/slub.c:1470 [inline]
> slab_free mm/slub.c:3012 [inline]
> kfree+0xe4/0x2f0 mm/slub.c:3953
> kobject_uevent_env+0x294/0x1160 lib/kobject_uevent.c:624
> kobject_synth_uevent+0x70a/0x81e lib/kobject_uevent.c:208
> uevent_store+0x20/0x50 drivers/base/core.c:1244
> dev_attr_store+0x50/0x80 drivers/base/core.c:947
> sysfs_kf_write+0x110/0x160 fs/sysfs/file.c:138
> kernfs_fop_write+0x2b0/0x470 fs/kernfs/file.c:315
> __vfs_write+0x76/0x100 fs/read_write.c:494
> vfs_write+0x262/0x5c0 fs/read_write.c:558
> ksys_write+0x127/0x250 fs/read_write.c:611
> do_syscall_64+0xb7/0x580 arch/x86/entry/common.c:296
> entry_SYSCALL_64_after_hwframe+0x49/0xbe
>
> The buggy address belongs to the object at ffff8881d4262f00
> which belongs to the cache kmalloc-64 of size 64
> The buggy address is located 59 bytes inside of
> 64-byte region [ffff8881d4262f00, ffff8881d4262f40)
> The buggy address belongs to the page:
> page:ffffea0007509880 refcount:1 mapcount:0 mapping:ffff8881da003180
> index:0x0
> flags: 0x200000000000200(slab)
> raw: 0200000000000200 ffffea00074d1f00 0000001800000018 ffff8881da003180
> raw: 0000000000000000 00000000802a002a 00000001ffffffff 0000000000000000
> page dumped because: kasan: bad access detected
>
> Memory state around the buggy address:
> ffff8881d4262e00: fb fb fb fb fc fc fc fc 00 00 00 00 00 00 fc fc
> ffff8881d4262e80: fc fc fc fc fb fb fb fb fb fb fb fb fc fc fc fc
> > ffff8881d4262f00: 00 00 00 00 00 00 00 03 fc fc fc fc fb fb fb fb
> ^
> ffff8881d4262f80: fb fb fb fb fc fc fc fc fc fc fc fc fc fc fc fc
> ffff8881d4263000: fb fb fb fb fb fb fb fb fb fb fc fc fc fc fb fb
> ==================================================================
This one is funny, we do sizeof(struct usb_cdc_mdlm_desc *) instead of
sizeof(struct usb_cdc_mdlm_desc) and the same for
usb_cdc_mdlm_detail_desc in cdc_parse_cdc_header().
>
>
> ---
> This bug is generated by a bot. It may contain errors.
> See https://goo.gl/tpsmEJ for more information about syzbot.
> syzbot engineers can be reached at syzkaller@googlegroups.com.
>
> syzbot will keep track of this bug report. See:
> https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
> syzbot can test patches for this bug, for details see:
> https://goo.gl/tpsmEJ#testing-patches
>
> --
> You received this message because you are subscribed to the Google Groups "syzkaller-bugs" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to syzkaller-bugs+unsubscribe@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/syzkaller-bugs/000000000000487b44058fea845c%40google.com.
^ permalink raw reply
* KASAN: slab-out-of-bounds Read in usbnet_generic_cdc_bind
From: syzbot @ 2019-08-12 12:18 UTC (permalink / raw)
To: andreyknvl, davem, linux-kernel, linux-usb, netdev, oliver,
syzkaller-bugs
Hello,
syzbot found the following crash on:
HEAD commit: e96407b4 usb-fuzzer: main usb gadget fuzzer driver
git tree: https://github.com/google/kasan.git usb-fuzzer
console output: https://syzkaller.appspot.com/x/log.txt?x=1390791c600000
kernel config: https://syzkaller.appspot.com/x/.config?x=cfa2c18fb6a8068e
dashboard link: https://syzkaller.appspot.com/bug?extid=45a53506b65321c1fe91
compiler: gcc (GCC) 9.0.0 20181231 (experimental)
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=12c78cd2600000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=1395b40e600000
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+45a53506b65321c1fe91@syzkaller.appspotmail.com
usb 1-1: config 1 interface 0 altsetting 0 has 0 endpoint descriptors,
different from the interface descriptor's value: 18
usb 1-1: New USB device found, idVendor=0525, idProduct=a4a1, bcdDevice=
0.40
usb 1-1: New USB device strings: Mfr=6, Product=0, SerialNumber=0
==================================================================
BUG: KASAN: slab-out-of-bounds in memcmp+0xa6/0xb0 lib/string.c:904
Read of size 1 at addr ffff8881d4262f3b by task kworker/1:2/83
CPU: 1 PID: 83 Comm: kworker/1:2 Not tainted 5.3.0-rc2+ #25
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
Workqueue: usb_hub_wq hub_event
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0xca/0x13e lib/dump_stack.c:113
print_address_description+0x6a/0x32c mm/kasan/report.c:351
__kasan_report.cold+0x1a/0x33 mm/kasan/report.c:482
kasan_report+0xe/0x12 mm/kasan/common.c:612
memcmp+0xa6/0xb0 lib/string.c:904
memcmp include/linux/string.h:400 [inline]
usbnet_generic_cdc_bind+0x71b/0x17c0 drivers/net/usb/cdc_ether.c:225
usbnet_ether_cdc_bind drivers/net/usb/cdc_ether.c:322 [inline]
usbnet_cdc_bind+0x20/0x1a0 drivers/net/usb/cdc_ether.c:430
usbnet_probe+0xb43/0x23d0 drivers/net/usb/usbnet.c:1722
usb_probe_interface+0x305/0x7a0 drivers/usb/core/driver.c:361
really_probe+0x281/0x650 drivers/base/dd.c:548
driver_probe_device+0x101/0x1b0 drivers/base/dd.c:709
__device_attach_driver+0x1c2/0x220 drivers/base/dd.c:816
bus_for_each_drv+0x15c/0x1e0 drivers/base/bus.c:454
__device_attach+0x217/0x360 drivers/base/dd.c:882
bus_probe_device+0x1e4/0x290 drivers/base/bus.c:514
device_add+0xae6/0x16f0 drivers/base/core.c:2114
usb_set_configuration+0xdf6/0x1670 drivers/usb/core/message.c:2023
generic_probe+0x9d/0xd5 drivers/usb/core/generic.c:210
usb_probe_device+0x99/0x100 drivers/usb/core/driver.c:266
really_probe+0x281/0x650 drivers/base/dd.c:548
driver_probe_device+0x101/0x1b0 drivers/base/dd.c:709
__device_attach_driver+0x1c2/0x220 drivers/base/dd.c:816
bus_for_each_drv+0x15c/0x1e0 drivers/base/bus.c:454
__device_attach+0x217/0x360 drivers/base/dd.c:882
bus_probe_device+0x1e4/0x290 drivers/base/bus.c:514
device_add+0xae6/0x16f0 drivers/base/core.c:2114
usb_new_device.cold+0x6a4/0xe79 drivers/usb/core/hub.c:2536
hub_port_connect drivers/usb/core/hub.c:5098 [inline]
hub_port_connect_change drivers/usb/core/hub.c:5213 [inline]
port_event drivers/usb/core/hub.c:5359 [inline]
hub_event+0x1b5c/0x3640 drivers/usb/core/hub.c:5441
process_one_work+0x92b/0x1530 kernel/workqueue.c:2269
worker_thread+0x96/0xe20 kernel/workqueue.c:2415
kthread+0x318/0x420 kernel/kthread.c:255
ret_from_fork+0x24/0x30 arch/x86/entry/entry_64.S:352
Allocated by task 83:
save_stack+0x1b/0x80 mm/kasan/common.c:69
set_track mm/kasan/common.c:77 [inline]
__kasan_kmalloc mm/kasan/common.c:487 [inline]
__kasan_kmalloc.constprop.0+0xbf/0xd0 mm/kasan/common.c:460
kmalloc include/linux/slab.h:557 [inline]
usb_get_configuration+0x30c/0x3070 drivers/usb/core/config.c:857
usb_enumerate_device drivers/usb/core/hub.c:2369 [inline]
usb_new_device+0xd3/0x160 drivers/usb/core/hub.c:2505
hub_port_connect drivers/usb/core/hub.c:5098 [inline]
hub_port_connect_change drivers/usb/core/hub.c:5213 [inline]
port_event drivers/usb/core/hub.c:5359 [inline]
hub_event+0x1b5c/0x3640 drivers/usb/core/hub.c:5441
process_one_work+0x92b/0x1530 kernel/workqueue.c:2269
worker_thread+0x96/0xe20 kernel/workqueue.c:2415
kthread+0x318/0x420 kernel/kthread.c:255
ret_from_fork+0x24/0x30 arch/x86/entry/entry_64.S:352
Freed by task 269:
save_stack+0x1b/0x80 mm/kasan/common.c:69
set_track mm/kasan/common.c:77 [inline]
__kasan_slab_free+0x130/0x180 mm/kasan/common.c:449
slab_free_hook mm/slub.c:1423 [inline]
slab_free_freelist_hook mm/slub.c:1470 [inline]
slab_free mm/slub.c:3012 [inline]
kfree+0xe4/0x2f0 mm/slub.c:3953
kobject_uevent_env+0x294/0x1160 lib/kobject_uevent.c:624
kobject_synth_uevent+0x70a/0x81e lib/kobject_uevent.c:208
uevent_store+0x20/0x50 drivers/base/core.c:1244
dev_attr_store+0x50/0x80 drivers/base/core.c:947
sysfs_kf_write+0x110/0x160 fs/sysfs/file.c:138
kernfs_fop_write+0x2b0/0x470 fs/kernfs/file.c:315
__vfs_write+0x76/0x100 fs/read_write.c:494
vfs_write+0x262/0x5c0 fs/read_write.c:558
ksys_write+0x127/0x250 fs/read_write.c:611
do_syscall_64+0xb7/0x580 arch/x86/entry/common.c:296
entry_SYSCALL_64_after_hwframe+0x49/0xbe
The buggy address belongs to the object at ffff8881d4262f00
which belongs to the cache kmalloc-64 of size 64
The buggy address is located 59 bytes inside of
64-byte region [ffff8881d4262f00, ffff8881d4262f40)
The buggy address belongs to the page:
page:ffffea0007509880 refcount:1 mapcount:0 mapping:ffff8881da003180
index:0x0
flags: 0x200000000000200(slab)
raw: 0200000000000200 ffffea00074d1f00 0000001800000018 ffff8881da003180
raw: 0000000000000000 00000000802a002a 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff8881d4262e00: fb fb fb fb fc fc fc fc 00 00 00 00 00 00 fc fc
ffff8881d4262e80: fc fc fc fc fb fb fb fb fb fb fb fb fc fc fc fc
> ffff8881d4262f00: 00 00 00 00 00 00 00 03 fc fc fc fc fb fb fb fb
^
ffff8881d4262f80: fb fb fb fb fc fc fc fc fc fc fc fc fc fc fc fc
ffff8881d4263000: fb fb fb fb fb fb fb fb fb fb fc fc fc fc fb fb
==================================================================
---
This bug is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.
syzbot will keep track of this bug report. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
syzbot can test patches for this bug, for details see:
https://goo.gl/tpsmEJ#testing-patches
^ permalink raw reply
* KASAN: use-after-free Read in rxrpc_queue_local
From: syzbot @ 2019-08-12 12:08 UTC (permalink / raw)
To: davem, dhowells, linux-afs, linux-kernel, netdev, syzkaller-bugs
Hello,
syzbot found the following crash on:
HEAD commit: 125b7e09 net: tc35815: Explicitly check NET_IP_ALIGN is no..
git tree: net
console output: https://syzkaller.appspot.com/x/log.txt?x=174a6536600000
kernel config: https://syzkaller.appspot.com/x/.config?x=a4c9e9f08e9e8960
dashboard link: https://syzkaller.appspot.com/bug?extid=78e71c5bab4f76a6a719
compiler: gcc (GCC) 9.0.0 20181231 (experimental)
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=165ec172600000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=119d4eba600000
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+78e71c5bab4f76a6a719@syzkaller.appspotmail.com
==================================================================
BUG: KASAN: use-after-free in atomic_read
include/asm-generic/atomic-instrumented.h:26 [inline]
BUG: KASAN: use-after-free in rxrpc_queue_local+0x7c/0x3e0
net/rxrpc/local_object.c:354
Read of size 4 at addr ffff8880a7724014 by task syz-executor522/16188
CPU: 0 PID: 16188 Comm: syz-executor522 Not tainted 5.3.0-rc3+ #159
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x172/0x1f0 lib/dump_stack.c:113
print_address_description.cold+0xd4/0x306 mm/kasan/report.c:351
__kasan_report.cold+0x1b/0x36 mm/kasan/report.c:482
kasan_report+0x12/0x17 mm/kasan/common.c:612
check_memory_region_inline mm/kasan/generic.c:185 [inline]
check_memory_region+0x134/0x1a0 mm/kasan/generic.c:192
__kasan_check_read+0x11/0x20 mm/kasan/common.c:92
atomic_read include/asm-generic/atomic-instrumented.h:26 [inline]
rxrpc_queue_local+0x7c/0x3e0 net/rxrpc/local_object.c:354
rxrpc_unuse_local+0x52/0x80 net/rxrpc/local_object.c:408
rxrpc_release_sock net/rxrpc/af_rxrpc.c:904 [inline]
rxrpc_release+0x47d/0x840 net/rxrpc/af_rxrpc.c:930
__sock_release+0xce/0x280 net/socket.c:590
sock_close+0x1e/0x30 net/socket.c:1268
__fput+0x2ff/0x890 fs/file_table.c:280
____fput+0x16/0x20 fs/file_table.c:313
task_work_run+0x145/0x1c0 kernel/task_work.c:113
tracehook_notify_resume include/linux/tracehook.h:188 [inline]
exit_to_usermode_loop+0x316/0x380 arch/x86/entry/common.c:163
prepare_exit_to_usermode arch/x86/entry/common.c:194 [inline]
syscall_return_slowpath arch/x86/entry/common.c:274 [inline]
do_syscall_64+0x5a9/0x6a0 arch/x86/entry/common.c:299
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x407bb1
Code: 75 14 b8 03 00 00 00 0f 05 48 3d 01 f0 ff ff 0f 83 24 1a 00 00 c3 48
83 ec 08 e8 0a fc ff ff 48 89 04 24 b8 03 00 00 00 0f 05 <48> 8b 3c 24 48
89 c2 e8 53 fc ff ff 48 89 d0 48 83 c4 08 48 3d 01
RSP: 002b:00007ffc861e4d10 EFLAGS: 00000293 ORIG_RAX: 0000000000000003
RAX: 0000000000000000 RBX: 0000000000000004 RCX: 0000000000407bb1
RDX: 0000000000000000 RSI: 0000000000000080 RDI: 0000000000000003
RBP: 00000000006e5a0c R08: 00000000004b1939 R09: 00000000004b1939
R10: 00007ffc861e4d40 R11: 0000000000000293 R12: 00000000006e5a00
R13: 0000000000000000 R14: 000000000000002d R15: 20c49ba5e353f7cf
Allocated by task 16189:
save_stack+0x23/0x90 mm/kasan/common.c:69
set_track mm/kasan/common.c:77 [inline]
__kasan_kmalloc mm/kasan/common.c:487 [inline]
__kasan_kmalloc.constprop.0+0xcf/0xe0 mm/kasan/common.c:460
kasan_kmalloc+0x9/0x10 mm/kasan/common.c:501
kmem_cache_alloc_trace+0x158/0x790 mm/slab.c:3550
kmalloc include/linux/slab.h:552 [inline]
kzalloc include/linux/slab.h:748 [inline]
rxrpc_alloc_local net/rxrpc/local_object.c:79 [inline]
rxrpc_lookup_local+0x562/0x1b70 net/rxrpc/local_object.c:277
rxrpc_bind+0x34d/0x5e0 net/rxrpc/af_rxrpc.c:149
__sys_bind+0x239/0x290 net/socket.c:1647
__do_sys_bind net/socket.c:1658 [inline]
__se_sys_bind net/socket.c:1656 [inline]
__x64_sys_bind+0x73/0xb0 net/socket.c:1656
do_syscall_64+0xfd/0x6a0 arch/x86/entry/common.c:296
entry_SYSCALL_64_after_hwframe+0x49/0xbe
Freed by task 9:
save_stack+0x23/0x90 mm/kasan/common.c:69
set_track mm/kasan/common.c:77 [inline]
__kasan_slab_free+0x102/0x150 mm/kasan/common.c:449
kasan_slab_free+0xe/0x10 mm/kasan/common.c:457
__cache_free mm/slab.c:3425 [inline]
kfree+0x10a/0x2c0 mm/slab.c:3756
rxrpc_local_rcu+0x62/0x80 net/rxrpc/local_object.c:495
__rcu_reclaim kernel/rcu/rcu.h:222 [inline]
rcu_do_batch kernel/rcu/tree.c:2114 [inline]
rcu_core+0x67f/0x1580 kernel/rcu/tree.c:2314
rcu_core_si+0x9/0x10 kernel/rcu/tree.c:2323
__do_softirq+0x262/0x98c kernel/softirq.c:292
The buggy address belongs to the object at ffff8880a7724000
which belongs to the cache kmalloc-1k of size 1024
The buggy address is located 20 bytes inside of
1024-byte region [ffff8880a7724000, ffff8880a7724400)
The buggy address belongs to the page:
page:ffffea00029dc900 refcount:1 mapcount:0 mapping:ffff8880aa400c40
index:0xffff8880a7725200 compound_mapcount: 0
flags: 0x1fffc0000010200(slab|head)
raw: 01fffc0000010200 ffffea0002a6ad08 ffffea0002a6a808 ffff8880aa400c40
raw: ffff8880a7725200 ffff8880a7724000 0000000100000005 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff8880a7723f00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff8880a7723f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> ffff8880a7724000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff8880a7724080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8880a7724100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================
---
This bug is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.
syzbot will keep track of this bug report. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
syzbot can test patches for this bug, for details see:
https://goo.gl/tpsmEJ#testing-patches
^ permalink raw reply
* Re: [PATCH][net-next] rxrpc: fix uninitialized return value in variable err
From: David Howells @ 2019-08-12 12:05 UTC (permalink / raw)
To: Colin King
Cc: dhowells, David S . Miller, linux-afs, netdev, kernel-janitors,
linux-kernel
In-Reply-To: <20190809170259.29859-1-colin.king@canonical.com>
Colin King <colin.king@canonical.com> wrote:
> Fixes: b214b2d8f277 ("rxrpc: Don't use skb_cow_data() in rxkad")
This isn't in net or net-next and has been superseded in any case.
You can find it still in my afs-next branch, but the replacement in
rxrpc-fixes is fixed differently.
David
^ permalink raw reply
* [PATCH net] batman-adv: fix uninit-value in batadv_netlink_get_ifindex()
From: Eric Dumazet @ 2019-08-12 11:57 UTC (permalink / raw)
To: David S . Miller
Cc: netdev, Eric Dumazet, Eric Dumazet, syzbot, Marek Lindner,
Simon Wunderlich, Antonio Quartulli
batadv_netlink_get_ifindex() needs to make sure user passed
a correct u32 attribute.
syzbot reported :
BUG: KMSAN: uninit-value in batadv_netlink_dump_hardif+0x70d/0x880 net/batman-adv/netlink.c:968
CPU: 1 PID: 11705 Comm: syz-executor888 Not tainted 5.1.0+ #1
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x191/0x1f0 lib/dump_stack.c:113
kmsan_report+0x130/0x2a0 mm/kmsan/kmsan.c:622
__msan_warning+0x75/0xe0 mm/kmsan/kmsan_instr.c:310
batadv_netlink_dump_hardif+0x70d/0x880 net/batman-adv/netlink.c:968
genl_lock_dumpit+0xc6/0x130 net/netlink/genetlink.c:482
netlink_dump+0xa84/0x1ab0 net/netlink/af_netlink.c:2253
__netlink_dump_start+0xa3a/0xb30 net/netlink/af_netlink.c:2361
genl_family_rcv_msg net/netlink/genetlink.c:550 [inline]
genl_rcv_msg+0xfc1/0x1a40 net/netlink/genetlink.c:627
netlink_rcv_skb+0x431/0x620 net/netlink/af_netlink.c:2486
genl_rcv+0x63/0x80 net/netlink/genetlink.c:638
netlink_unicast_kernel net/netlink/af_netlink.c:1311 [inline]
netlink_unicast+0xf3e/0x1020 net/netlink/af_netlink.c:1337
netlink_sendmsg+0x127e/0x12f0 net/netlink/af_netlink.c:1926
sock_sendmsg_nosec net/socket.c:651 [inline]
sock_sendmsg net/socket.c:661 [inline]
___sys_sendmsg+0xcc6/0x1200 net/socket.c:2260
__sys_sendmsg net/socket.c:2298 [inline]
__do_sys_sendmsg net/socket.c:2307 [inline]
__se_sys_sendmsg+0x305/0x460 net/socket.c:2305
__x64_sys_sendmsg+0x4a/0x70 net/socket.c:2305
do_syscall_64+0xbc/0xf0 arch/x86/entry/common.c:291
entry_SYSCALL_64_after_hwframe+0x63/0xe7
RIP: 0033:0x440209
Fixes: b60620cf567b ("batman-adv: netlink: hardif query")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: syzbot <syzkaller@googlegroups.com>
Cc: Marek Lindner <mareklindner@neomailbox.ch>
Cc: Simon Wunderlich <sw@simonwunderlich.de>
Cc: Antonio Quartulli <a@unstable.cc>
---
net/batman-adv/netlink.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index 6f08fd122a8ddea43600c856a6be171dc7625d9c..7e052d6f759b659dbee0edd7546c367cf14b8e9e 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -164,7 +164,7 @@ batadv_netlink_get_ifindex(const struct nlmsghdr *nlh, int attrtype)
{
struct nlattr *attr = nlmsg_find_attr(nlh, GENL_HDRLEN, attrtype);
- return attr ? nla_get_u32(attr) : 0;
+ return (attr && nla_len(attr) == sizeof(u32)) ? nla_get_u32(attr) : 0;
}
/**
--
2.23.0.rc1.153.gdeed80330f-goog
^ permalink raw reply related
* [PATCH net] nexthop: use nlmsg_parse_deprecated()
From: Eric Dumazet @ 2019-08-12 11:36 UTC (permalink / raw)
To: David S . Miller; +Cc: netdev, Eric Dumazet, Eric Dumazet, syzbot, David Ahern
David missed that commit 8cb081746c03 ("netlink: make validation
more configurable for future strictness") has renamed nlmsg_parse()
syzbot reported :
BUG: KMSAN: uninit-value in nh_valid_get_del_req+0x6f1/0x8c0 net/ipv4/nexthop.c:1510
CPU: 0 PID: 11812 Comm: syz-executor444 Not tainted 5.3.0-rc3+ #17
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x191/0x1f0 lib/dump_stack.c:113
kmsan_report+0x162/0x2d0 mm/kmsan/kmsan_report.c:109
__msan_warning+0x75/0xe0 mm/kmsan/kmsan_instr.c:294
nh_valid_get_del_req+0x6f1/0x8c0 net/ipv4/nexthop.c:1510
rtm_del_nexthop+0x1b1/0x610 net/ipv4/nexthop.c:1543
rtnetlink_rcv_msg+0x115a/0x1580 net/core/rtnetlink.c:5223
netlink_rcv_skb+0x431/0x620 net/netlink/af_netlink.c:2477
rtnetlink_rcv+0x50/0x60 net/core/rtnetlink.c:5241
netlink_unicast_kernel net/netlink/af_netlink.c:1302 [inline]
netlink_unicast+0xf6c/0x1050 net/netlink/af_netlink.c:1328
netlink_sendmsg+0x110f/0x1330 net/netlink/af_netlink.c:1917
sock_sendmsg_nosec net/socket.c:637 [inline]
sock_sendmsg net/socket.c:657 [inline]
___sys_sendmsg+0x14ff/0x1590 net/socket.c:2311
__sys_sendmmsg+0x53a/0xae0 net/socket.c:2413
__do_sys_sendmmsg net/socket.c:2442 [inline]
__se_sys_sendmmsg+0xbd/0xe0 net/socket.c:2439
__x64_sys_sendmmsg+0x56/0x70 net/socket.c:2439
do_syscall_64+0xbc/0xf0 arch/x86/entry/common.c:297
entry_SYSCALL_64_after_hwframe+0x63/0xe7
Fixes: ab84be7e54fc ("net: Initial nexthop code")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: syzbot <syzkaller@googlegroups.com>
Cc: David Ahern <dsahern@gmail.com>
---
net/ipv4/nexthop.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c
index 5fe5a3981d4316ad8d9dbf54f5d9017b89e24038..2672e1a7b544253f2d1d0aaffd2bab9db5d76b9f 100644
--- a/net/ipv4/nexthop.c
+++ b/net/ipv4/nexthop.c
@@ -1304,8 +1304,8 @@ static int rtm_to_nh_config(struct net *net, struct sk_buff *skb,
struct nlattr *tb[NHA_MAX + 1];
int err;
- err = nlmsg_parse(nlh, sizeof(*nhm), tb, NHA_MAX, rtm_nh_policy,
- extack);
+ err = nlmsg_parse_deprecated(nlh, sizeof(*nhm), tb, NHA_MAX,
+ rtm_nh_policy, extack);
if (err < 0)
return err;
@@ -1488,8 +1488,8 @@ static int nh_valid_get_del_req(struct nlmsghdr *nlh, u32 *id,
struct nlattr *tb[NHA_MAX + 1];
int err, i;
- err = nlmsg_parse(nlh, sizeof(*nhm), tb, NHA_MAX, rtm_nh_policy,
- extack);
+ err = nlmsg_parse_deprecated(nlh, sizeof(*nhm), tb, NHA_MAX,
+ rtm_nh_policy, extack);
if (err < 0)
return err;
@@ -1639,8 +1639,8 @@ static int nh_valid_dump_req(const struct nlmsghdr *nlh, int *dev_idx,
int err, i;
u32 idx;
- err = nlmsg_parse(nlh, sizeof(*nhm), tb, NHA_MAX, rtm_nh_policy,
- NULL);
+ err = nlmsg_parse_deprecated(nlh, sizeof(*nhm), tb, NHA_MAX,
+ rtm_nh_policy, NULL);
if (err < 0)
return err;
--
2.23.0.rc1.153.gdeed80330f-goog
^ permalink raw reply related
* [PATCH bpf-next] mm: mmap: increase sockets maximum memory size pgoff for 32bits
From: Ivan Khoronzhuk @ 2019-08-12 11:34 UTC (permalink / raw)
To: bjorn.topel, linux-mm
Cc: xdp-newbies, netdev, bpf, linux-kernel, akpm, ast,
magnus.karlsson, Ivan Khoronzhuk
The AF_XDP sockets umem mapping interface uses XDP_UMEM_PGOFF_FILL_RING
and XDP_UMEM_PGOFF_COMPLETION_RING offsets. The offsets seems like are
established already and are part of configuration interface.
But for 32-bit systems, while AF_XDP socket configuration, the values
are to large to pass maximum allowed file size verification.
The offsets can be tuned ofc, but instead of changing existent
interface - extend max allowed file size for sockets. The 64-bit
systems seems like ok with this, so extend threshold only for
32-bits for now.
Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
---
Based on bpf-next/master
mm/mmap.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/mm/mmap.c b/mm/mmap.c
index 7e8c3e8ae75f..238ce6b71405 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1358,6 +1358,11 @@ static inline u64 file_mmap_size_max(struct file *file, struct inode *inode)
if (S_ISBLK(inode->i_mode))
return MAX_LFS_FILESIZE;
+#if BITS_PER_LONG == 32
+ if (S_ISSOCK(inode->i_mode))
+ return MAX_LFS_FILESIZE;
+#endif
+
/* Special "we do even unsigned file positions" case */
if (file->f_mode & FMODE_UNSIGNED_OFFSET)
return 0;
--
2.17.1
^ permalink raw reply related
* [PATCH v4 00/14] net: phy: adin: add support for Analog Devices PHYs
From: Alexandru Ardelean @ 2019-08-12 11:23 UTC (permalink / raw)
To: netdev, devicetree, linux-kernel
Cc: davem, robh+dt, mark.rutland, f.fainelli, hkallweit1, andrew,
Alexandru Ardelean
This changeset adds support for Analog Devices Industrial Ethernet PHYs.
Particularly the PHYs this driver adds support for:
* ADIN1200 - Robust, Industrial, Low Power 10/100 Ethernet PHY
* ADIN1300 - Robust, Industrial, Low Latency 10/100/1000 Gigabit
Ethernet PHY
The 2 chips are register compatible with one another. The main
difference being that ADIN1200 doesn't operate in gigabit mode.
The chips can be operated by the Generic PHY driver as well via the
standard IEEE PHY registers (0x0000 - 0x000F) which are supported by the
kernel as well. This assumes that configuration of the PHY has been done
completely in HW, according to spec, i.e. no extra SW configuration
required.
This changeset also implements the ability to configure the chips via SW
registers.
Datasheets:
https://www.analog.com/media/en/technical-documentation/data-sheets/ADIN1300.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/ADIN1200.pdf
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
Alexandru Ardelean (14):
net: phy: adin: add support for Analog Devices PHYs
net: phy: adin: hook genphy_{suspend,resume} into the driver
net: phy: adin: add support for interrupts
net: phy: adin: add {write,read}_mmd hooks
net: phy: adin: configure RGMII/RMII/MII modes on config
net: phy: adin: make RGMII internal delays configurable
net: phy: adin: make RMII fifo depth configurable
net: phy: adin: add support MDI/MDIX/Auto-MDI selection
net: phy: adin: add EEE translation layer from Clause 45 to Clause 22
net: phy: adin: implement PHY subsystem software reset
net: phy: adin: implement Energy Detect Powerdown mode
net: phy: adin: implement downshift configuration via phy-tunable
net: phy: adin: add ethtool get_stats support
dt-bindings: net: add bindings for ADIN PHY driver
.../devicetree/bindings/net/adi,adin.yaml | 73 ++
MAINTAINERS | 8 +
drivers/net/phy/Kconfig | 9 +
drivers/net/phy/Makefile | 1 +
drivers/net/phy/adin.c | 763 ++++++++++++++++++
5 files changed, 854 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/adi,adin.yaml
create mode 100644 drivers/net/phy/adin.c
--
Changelog v3 -> v4:
* [PATCH v3 03/14] net: phy: adin: add support for interrupts
- using only Link status interrupt
* [PATCH v3 04/14] net: phy: adin: add {write,read}_mmd hooks
- dropped C45 access code; it is dead-code, since `is_c45` will never be true
2.20.1
^ permalink raw reply
* [PATCH v4 01/14] net: phy: adin: add support for Analog Devices PHYs
From: Alexandru Ardelean @ 2019-08-12 11:23 UTC (permalink / raw)
To: netdev, devicetree, linux-kernel
Cc: davem, robh+dt, mark.rutland, f.fainelli, hkallweit1, andrew,
Alexandru Ardelean
In-Reply-To: <20190812112350.15242-1-alexandru.ardelean@analog.com>
This change adds support for Analog Devices Industrial Ethernet PHYs.
Particularly the PHYs this driver adds support for:
* ADIN1200 - Robust, Industrial, Low Power 10/100 Ethernet PHY
* ADIN1300 - Robust, Industrial, Low Latency 10/100/1000 Gigabit
Ethernet PHY
The 2 chips are register compatible with one another. The main difference
being that ADIN1200 doesn't operate in gigabit mode.
The chips can be operated by the Generic PHY driver as well via the
standard IEEE PHY registers (0x0000 - 0x000F) which are supported by the
kernel as well. This assumes that configuration of the PHY has been done
completely in HW, according to spec.
Configuration can also be done via registers, which will be supported by
this driver.
Datasheets:
https://www.analog.com/media/en/technical-documentation/data-sheets/ADIN1300.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/ADIN1200.pdf
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
---
MAINTAINERS | 7 ++++++
drivers/net/phy/Kconfig | 9 ++++++++
drivers/net/phy/Makefile | 1 +
drivers/net/phy/adin.c | 49 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 66 insertions(+)
create mode 100644 drivers/net/phy/adin.c
diff --git a/MAINTAINERS b/MAINTAINERS
index e352550a6895..e8aa8a667864 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -938,6 +938,13 @@ S: Supported
F: drivers/mux/adgs1408.c
F: Documentation/devicetree/bindings/mux/adi,adgs1408.txt
+ANALOG DEVICES INC ADIN DRIVER
+M: Alexandru Ardelean <alexaundru.ardelean@analog.com>
+L: netdev@vger.kernel.org
+W: http://ez.analog.com/community/linux-device-drivers
+S: Supported
+F: drivers/net/phy/adin.c
+
ANALOG DEVICES INC ADIS DRIVER LIBRARY
M: Alexandru Ardelean <alexandru.ardelean@analog.com>
S: Supported
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 48ca213c0ada..03be30cde552 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -257,6 +257,15 @@ config SFP
depends on HWMON || HWMON=n
select MDIO_I2C
+config ADIN_PHY
+ tristate "Analog Devices Industrial Ethernet PHYs"
+ help
+ Adds support for the Analog Devices Industrial Ethernet PHYs.
+ Currently supports the:
+ - ADIN1200 - Robust,Industrial, Low Power 10/100 Ethernet PHY
+ - ADIN1300 - Robust,Industrial, Low Latency 10/100/1000 Gigabit
+ Ethernet PHY
+
config AMD_PHY
tristate "AMD PHYs"
---help---
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index ba07c27e4208..a03437e091f3 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_SFP) += sfp.o
sfp-obj-$(CONFIG_SFP) += sfp-bus.o
obj-y += $(sfp-obj-y) $(sfp-obj-m)
+obj-$(CONFIG_ADIN_PHY) += adin.o
obj-$(CONFIG_AMD_PHY) += amd.o
aquantia-objs += aquantia_main.o
ifdef CONFIG_HWMON
diff --git a/drivers/net/phy/adin.c b/drivers/net/phy/adin.c
new file mode 100644
index 000000000000..6d7af4743957
--- /dev/null
+++ b/drivers/net/phy/adin.c
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0+
+/**
+ * Driver for Analog Devices Industrial Ethernet PHYs
+ *
+ * Copyright 2019 Analog Devices Inc.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+
+#define PHY_ID_ADIN1200 0x0283bc20
+#define PHY_ID_ADIN1300 0x0283bc30
+
+static int adin_config_init(struct phy_device *phydev)
+{
+ return genphy_config_init(phydev);
+}
+
+static struct phy_driver adin_driver[] = {
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_ADIN1200),
+ .name = "ADIN1200",
+ .config_init = adin_config_init,
+ .config_aneg = genphy_config_aneg,
+ .read_status = genphy_read_status,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_ADIN1300),
+ .name = "ADIN1300",
+ .config_init = adin_config_init,
+ .config_aneg = genphy_config_aneg,
+ .read_status = genphy_read_status,
+ },
+};
+
+module_phy_driver(adin_driver);
+
+static struct mdio_device_id __maybe_unused adin_tbl[] = {
+ { PHY_ID_MATCH_MODEL(PHY_ID_ADIN1200) },
+ { PHY_ID_MATCH_MODEL(PHY_ID_ADIN1300) },
+ { }
+};
+
+MODULE_DEVICE_TABLE(mdio, adin_tbl);
+MODULE_DESCRIPTION("Analog Devices Industrial Ethernet PHY driver");
+MODULE_LICENSE("GPL");
--
2.20.1
^ permalink raw reply related
* [PATCH v4 02/14] net: phy: adin: hook genphy_{suspend,resume} into the driver
From: Alexandru Ardelean @ 2019-08-12 11:23 UTC (permalink / raw)
To: netdev, devicetree, linux-kernel
Cc: davem, robh+dt, mark.rutland, f.fainelli, hkallweit1, andrew,
Alexandru Ardelean
In-Reply-To: <20190812112350.15242-1-alexandru.ardelean@analog.com>
The chip supports standard suspend/resume via BMCR reg.
Hook these functions into the `adin` driver.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
---
drivers/net/phy/adin.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/phy/adin.c b/drivers/net/phy/adin.c
index 6d7af4743957..fc0148ba4b94 100644
--- a/drivers/net/phy/adin.c
+++ b/drivers/net/phy/adin.c
@@ -26,6 +26,8 @@ static struct phy_driver adin_driver[] = {
.config_init = adin_config_init,
.config_aneg = genphy_config_aneg,
.read_status = genphy_read_status,
+ .resume = genphy_resume,
+ .suspend = genphy_suspend,
},
{
PHY_ID_MATCH_MODEL(PHY_ID_ADIN1300),
@@ -33,6 +35,8 @@ static struct phy_driver adin_driver[] = {
.config_init = adin_config_init,
.config_aneg = genphy_config_aneg,
.read_status = genphy_read_status,
+ .resume = genphy_resume,
+ .suspend = genphy_suspend,
},
};
--
2.20.1
^ permalink raw reply related
* [PATCH v4 03/14] net: phy: adin: add support for interrupts
From: Alexandru Ardelean @ 2019-08-12 11:23 UTC (permalink / raw)
To: netdev, devicetree, linux-kernel
Cc: davem, robh+dt, mark.rutland, f.fainelli, hkallweit1, andrew,
Alexandru Ardelean
In-Reply-To: <20190812112350.15242-1-alexandru.ardelean@analog.com>
This change hooks link-status-change interrupts to phylib.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
---
drivers/net/phy/adin.c | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/drivers/net/phy/adin.c b/drivers/net/phy/adin.c
index fc0148ba4b94..f4ee611e33df 100644
--- a/drivers/net/phy/adin.c
+++ b/drivers/net/phy/adin.c
@@ -14,11 +14,43 @@
#define PHY_ID_ADIN1200 0x0283bc20
#define PHY_ID_ADIN1300 0x0283bc30
+#define ADIN1300_INT_MASK_REG 0x0018
+#define ADIN1300_INT_MDIO_SYNC_EN BIT(9)
+#define ADIN1300_INT_ANEG_STAT_CHNG_EN BIT(8)
+#define ADIN1300_INT_ANEG_PAGE_RX_EN BIT(6)
+#define ADIN1300_INT_IDLE_ERR_CNT_EN BIT(5)
+#define ADIN1300_INT_MAC_FIFO_OU_EN BIT(4)
+#define ADIN1300_INT_RX_STAT_CHNG_EN BIT(3)
+#define ADIN1300_INT_LINK_STAT_CHNG_EN BIT(2)
+#define ADIN1300_INT_SPEED_CHNG_EN BIT(1)
+#define ADIN1300_INT_HW_IRQ_EN BIT(0)
+#define ADIN1300_INT_MASK_EN \
+ (ADIN1300_INT_LINK_STAT_CHNG_EN | ADIN1300_INT_HW_IRQ_EN)
+#define ADIN1300_INT_STATUS_REG 0x0019
+
static int adin_config_init(struct phy_device *phydev)
{
return genphy_config_init(phydev);
}
+static int adin_phy_ack_intr(struct phy_device *phydev)
+{
+ /* Clear pending interrupts */
+ int rc = phy_read(phydev, ADIN1300_INT_STATUS_REG);
+
+ return rc < 0 ? rc : 0;
+}
+
+static int adin_phy_config_intr(struct phy_device *phydev)
+{
+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
+ return phy_set_bits(phydev, ADIN1300_INT_MASK_REG,
+ ADIN1300_INT_MASK_EN);
+
+ return phy_clear_bits(phydev, ADIN1300_INT_MASK_REG,
+ ADIN1300_INT_MASK_EN);
+}
+
static struct phy_driver adin_driver[] = {
{
PHY_ID_MATCH_MODEL(PHY_ID_ADIN1200),
@@ -26,6 +58,8 @@ static struct phy_driver adin_driver[] = {
.config_init = adin_config_init,
.config_aneg = genphy_config_aneg,
.read_status = genphy_read_status,
+ .ack_interrupt = adin_phy_ack_intr,
+ .config_intr = adin_phy_config_intr,
.resume = genphy_resume,
.suspend = genphy_suspend,
},
@@ -35,6 +69,8 @@ static struct phy_driver adin_driver[] = {
.config_init = adin_config_init,
.config_aneg = genphy_config_aneg,
.read_status = genphy_read_status,
+ .ack_interrupt = adin_phy_ack_intr,
+ .config_intr = adin_phy_config_intr,
.resume = genphy_resume,
.suspend = genphy_suspend,
},
--
2.20.1
^ permalink raw reply related
* [PATCH v4 08/14] net: phy: adin: add support MDI/MDIX/Auto-MDI selection
From: Alexandru Ardelean @ 2019-08-12 11:23 UTC (permalink / raw)
To: netdev, devicetree, linux-kernel
Cc: davem, robh+dt, mark.rutland, f.fainelli, hkallweit1, andrew,
Alexandru Ardelean
In-Reply-To: <20190812112350.15242-1-alexandru.ardelean@analog.com>
The ADIN PHYs support automatic MDI/MDIX negotiation. By default this is
disabled, so this is enabled at `config_init`.
This is controlled via the PHY Control 1 register.
The supported modes are:
1. Manual MDI
2. Manual MDIX
3. Auto MDIX - prefer MDIX
4. Auto MDIX - prefer MDI
The phydev mdix & mdix_ctrl fields include modes 3 & 4 into a single
auto-mode. So, the default mode this driver enables is 4 when Auto-MDI mode
is used.
When detecting MDI/MDIX mode, a combination of the PHY Control 1 register
and PHY Status 1 register is used to determine the correct MDI/MDIX mode.
If Auto-MDI mode is not set, then the manual MDI/MDIX mode is returned.
If Auto-MDI mode is set, then MDIX mode is returned differs from the
preferred MDI/MDIX mode.
This covers all cases where:
1. MDI preferred & Pair01Swapped == MDIX
2. MDIX preferred & Pair01Swapped == MDI
3. MDI preferred & ! Pair01Swapped == MDIX
4. MDIX preferred & ! Pair01Swapped == MDI
The preferred MDI/MDIX mode is not configured via SW, but can be configured
via HW pins. Note that the `Pair01Swapped` is the Green-Yellow physical
pairs.
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
---
drivers/net/phy/adin.c | 117 +++++++++++++++++++++++++++++++++++++++--
1 file changed, 113 insertions(+), 4 deletions(-)
diff --git a/drivers/net/phy/adin.c b/drivers/net/phy/adin.c
index 4ca685780622..51c0d17577de 100644
--- a/drivers/net/phy/adin.c
+++ b/drivers/net/phy/adin.c
@@ -19,6 +19,10 @@
#define ADIN1300_MII_EXT_REG_PTR 0x0010
#define ADIN1300_MII_EXT_REG_DATA 0x0011
+#define ADIN1300_PHY_CTRL1 0x0012
+#define ADIN1300_AUTO_MDI_EN BIT(10)
+#define ADIN1300_MAN_MDIX_EN BIT(9)
+
#define ADIN1300_INT_MASK_REG 0x0018
#define ADIN1300_INT_MDIO_SYNC_EN BIT(9)
#define ADIN1300_INT_ANEG_STAT_CHNG_EN BIT(8)
@@ -33,6 +37,9 @@
(ADIN1300_INT_LINK_STAT_CHNG_EN | ADIN1300_INT_HW_IRQ_EN)
#define ADIN1300_INT_STATUS_REG 0x0019
+#define ADIN1300_PHY_STATUS1 0x001a
+#define ADIN1300_PAIR_01_SWAP BIT(11)
+
#define ADIN1300_GE_RGMII_CFG_REG 0xff23
#define ADIN1300_GE_RGMII_RX_MSK GENMASK(8, 6)
#define ADIN1300_GE_RGMII_RX_SEL(x) \
@@ -206,6 +213,8 @@ static int adin_config_init(struct phy_device *phydev)
{
int rc;
+ phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
+
rc = genphy_config_init(phydev);
if (rc < 0)
return rc;
@@ -269,13 +278,113 @@ static int adin_write_mmd(struct phy_device *phydev, int devad, u16 regnum,
return __mdiobus_write(bus, phy_addr, ADIN1300_MII_EXT_REG_DATA, val);
}
+static int adin_config_mdix(struct phy_device *phydev)
+{
+ bool auto_en, mdix_en;
+ int reg;
+
+ mdix_en = false;
+ auto_en = false;
+ switch (phydev->mdix_ctrl) {
+ case ETH_TP_MDI:
+ break;
+ case ETH_TP_MDI_X:
+ mdix_en = true;
+ break;
+ case ETH_TP_MDI_AUTO:
+ auto_en = true;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ reg = phy_read(phydev, ADIN1300_PHY_CTRL1);
+ if (reg < 0)
+ return reg;
+
+ if (mdix_en)
+ reg |= ADIN1300_MAN_MDIX_EN;
+ else
+ reg &= ~ADIN1300_MAN_MDIX_EN;
+
+ if (auto_en)
+ reg |= ADIN1300_AUTO_MDI_EN;
+ else
+ reg &= ~ADIN1300_AUTO_MDI_EN;
+
+ return phy_write(phydev, ADIN1300_PHY_CTRL1, reg);
+}
+
+static int adin_config_aneg(struct phy_device *phydev)
+{
+ int ret;
+
+ ret = adin_config_mdix(phydev);
+ if (ret)
+ return ret;
+
+ return genphy_config_aneg(phydev);
+}
+
+static int adin_mdix_update(struct phy_device *phydev)
+{
+ bool auto_en, mdix_en;
+ bool swapped;
+ int reg;
+
+ reg = phy_read(phydev, ADIN1300_PHY_CTRL1);
+ if (reg < 0)
+ return reg;
+
+ auto_en = !!(reg & ADIN1300_AUTO_MDI_EN);
+ mdix_en = !!(reg & ADIN1300_MAN_MDIX_EN);
+
+ /* If MDI/MDIX is forced, just read it from the control reg */
+ if (!auto_en) {
+ if (mdix_en)
+ phydev->mdix = ETH_TP_MDI_X;
+ else
+ phydev->mdix = ETH_TP_MDI;
+ return 0;
+ }
+
+ /**
+ * Otherwise, we need to deduce it from the PHY status2 reg.
+ * When Auto-MDI is enabled, the ADIN1300_MAN_MDIX_EN bit implies
+ * a preference for MDIX when it is set.
+ */
+ reg = phy_read(phydev, ADIN1300_PHY_STATUS1);
+ if (reg < 0)
+ return reg;
+
+ swapped = !!(reg & ADIN1300_PAIR_01_SWAP);
+
+ if (mdix_en != swapped)
+ phydev->mdix = ETH_TP_MDI_X;
+ else
+ phydev->mdix = ETH_TP_MDI;
+
+ return 0;
+}
+
+static int adin_read_status(struct phy_device *phydev)
+{
+ int ret;
+
+ ret = adin_mdix_update(phydev);
+ if (ret < 0)
+ return ret;
+
+ return genphy_read_status(phydev);
+}
+
static struct phy_driver adin_driver[] = {
{
PHY_ID_MATCH_MODEL(PHY_ID_ADIN1200),
.name = "ADIN1200",
.config_init = adin_config_init,
- .config_aneg = genphy_config_aneg,
- .read_status = genphy_read_status,
+ .config_aneg = adin_config_aneg,
+ .read_status = adin_read_status,
.ack_interrupt = adin_phy_ack_intr,
.config_intr = adin_phy_config_intr,
.resume = genphy_resume,
@@ -287,8 +396,8 @@ static struct phy_driver adin_driver[] = {
PHY_ID_MATCH_MODEL(PHY_ID_ADIN1300),
.name = "ADIN1300",
.config_init = adin_config_init,
- .config_aneg = genphy_config_aneg,
- .read_status = genphy_read_status,
+ .config_aneg = adin_config_aneg,
+ .read_status = adin_read_status,
.ack_interrupt = adin_phy_ack_intr,
.config_intr = adin_phy_config_intr,
.resume = genphy_resume,
--
2.20.1
^ permalink raw reply related
* [PATCH v4 09/14] net: phy: adin: add EEE translation layer from Clause 45 to Clause 22
From: Alexandru Ardelean @ 2019-08-12 11:23 UTC (permalink / raw)
To: netdev, devicetree, linux-kernel
Cc: davem, robh+dt, mark.rutland, f.fainelli, hkallweit1, andrew,
Alexandru Ardelean
In-Reply-To: <20190812112350.15242-1-alexandru.ardelean@analog.com>
The ADIN1200 & ADIN1300 PHYs support EEE by using standard Clause 45 access
to access MMD registers for EEE.
The EEE register addresses (when using Clause 22) are available at
different addresses (than Clause 45), and since accessing these regs (via
Clause 22) needs a special mechanism, a translation table is required to
convert these addresses.
For Clause 45, this is not needed since the driver will likely never use
this access mode.
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
---
drivers/net/phy/adin.c | 69 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 67 insertions(+), 2 deletions(-)
diff --git a/drivers/net/phy/adin.c b/drivers/net/phy/adin.c
index 51c0d17577de..a0f8b616bcb7 100644
--- a/drivers/net/phy/adin.c
+++ b/drivers/net/phy/adin.c
@@ -40,6 +40,17 @@
#define ADIN1300_PHY_STATUS1 0x001a
#define ADIN1300_PAIR_01_SWAP BIT(11)
+/* EEE register addresses, accessible via Clause 22 access using
+ * ADIN1300_MII_EXT_REG_PTR & ADIN1300_MII_EXT_REG_DATA.
+ * The bit-fields are the same as specified by IEEE, and can be
+ * accessed via standard Clause 45 access.
+ */
+#define ADIN1300_EEE_CAP_REG 0x8000
+#define ADIN1300_EEE_ADV_REG 0x8001
+#define ADIN1300_EEE_LPABLE_REG 0x8002
+#define ADIN1300_CLOCK_STOP_REG 0x9400
+#define ADIN1300_LPI_WAKE_ERR_CNT_REG 0xa000
+
#define ADIN1300_GE_RGMII_CFG_REG 0xff23
#define ADIN1300_GE_RGMII_RX_MSK GENMASK(8, 6)
#define ADIN1300_GE_RGMII_RX_SEL(x) \
@@ -101,6 +112,26 @@ static const struct adin_cfg_reg_map adin_rmii_fifo_depths[] = {
{ },
};
+/**
+ * struct adin_clause45_mmd_map - map to convert Clause 45 regs to Clause 22
+ * @devad device address used in Clause 45 access
+ * @cl45_regnum register address defined by Clause 45
+ * @adin_regnum equivalent register address accessible via Clause 22
+ */
+struct adin_clause45_mmd_map {
+ int devad;
+ u16 cl45_regnum;
+ u16 adin_regnum;
+};
+
+static struct adin_clause45_mmd_map adin_clause45_mmd_map[] = {
+ { MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE, ADIN1300_EEE_CAP_REG },
+ { MDIO_MMD_AN, MDIO_AN_EEE_LPABLE, ADIN1300_EEE_LPABLE_REG },
+ { MDIO_MMD_AN, MDIO_AN_EEE_ADV, ADIN1300_EEE_ADV_REG },
+ { MDIO_MMD_PCS, MDIO_CTRL1, ADIN1300_CLOCK_STOP_REG },
+ { MDIO_MMD_PCS, MDIO_PCS_EEE_WK_ERR, ADIN1300_LPI_WAKE_ERR_CNT_REG },
+};
+
static int adin_lookup_reg_value(const struct adin_cfg_reg_map *tbl, int cfg)
{
size_t i;
@@ -251,13 +282,41 @@ static int adin_phy_config_intr(struct phy_device *phydev)
ADIN1300_INT_MASK_EN);
}
+static int adin_cl45_to_adin_reg(struct phy_device *phydev, int devad,
+ u16 cl45_regnum)
+{
+ struct adin_clause45_mmd_map *m;
+ int i;
+
+ if (devad == MDIO_MMD_VEND1)
+ return cl45_regnum;
+
+ for (i = 0; i < ARRAY_SIZE(adin_clause45_mmd_map); i++) {
+ m = &adin_clause45_mmd_map[i];
+ if (m->devad == devad && m->cl45_regnum == cl45_regnum)
+ return m->adin_regnum;
+ }
+
+ phydev_err(phydev,
+ "No translation available for devad: %d reg: %04x\n",
+ devad, cl45_regnum);
+
+ return -EINVAL;
+}
+
static int adin_read_mmd(struct phy_device *phydev, int devad, u16 regnum)
{
struct mii_bus *bus = phydev->mdio.bus;
int phy_addr = phydev->mdio.addr;
+ int adin_regnum;
int err;
- err = __mdiobus_write(bus, phy_addr, ADIN1300_MII_EXT_REG_PTR, regnum);
+ adin_regnum = adin_cl45_to_adin_reg(phydev, devad, regnum);
+ if (adin_regnum < 0)
+ return adin_regnum;
+
+ err = __mdiobus_write(bus, phy_addr, ADIN1300_MII_EXT_REG_PTR,
+ adin_regnum);
if (err)
return err;
@@ -269,9 +328,15 @@ static int adin_write_mmd(struct phy_device *phydev, int devad, u16 regnum,
{
struct mii_bus *bus = phydev->mdio.bus;
int phy_addr = phydev->mdio.addr;
+ int adin_regnum;
int err;
- err = __mdiobus_write(bus, phy_addr, ADIN1300_MII_EXT_REG_PTR, regnum);
+ adin_regnum = adin_cl45_to_adin_reg(phydev, devad, regnum);
+ if (adin_regnum < 0)
+ return adin_regnum;
+
+ err = __mdiobus_write(bus, phy_addr, ADIN1300_MII_EXT_REG_PTR,
+ adin_regnum);
if (err)
return err;
--
2.20.1
^ permalink raw reply related
* [PATCH v4 10/14] net: phy: adin: implement PHY subsystem software reset
From: Alexandru Ardelean @ 2019-08-12 11:23 UTC (permalink / raw)
To: netdev, devicetree, linux-kernel
Cc: davem, robh+dt, mark.rutland, f.fainelli, hkallweit1, andrew,
Alexandru Ardelean
In-Reply-To: <20190812112350.15242-1-alexandru.ardelean@analog.com>
The ADIN PHYs supports 4 types of reset:
1. The standard PHY reset via BMCR_RESET bit in MII_BMCR reg
2. Reset via GPIO
3. Reset via reg GeSftRst (0xff0c) & reload previous pin configs
4. Reset via reg GeSftRst (0xff0c) & request new pin configs
Resets 2 & 4 are almost identical, with the exception that the crystal
oscillator is available during reset for 2.
As it turns out, phylib already supports GPIO reset.
In case this is configured, the PHY driver won't do anything. In case it
isn't specified the subsystem software reset will kick in.
Resetting via GeSftRst or via GPIO is useful when doing a warm reboot,
because this will reset the subsystem registers to default values.
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
---
drivers/net/phy/adin.c | 43 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/drivers/net/phy/adin.c b/drivers/net/phy/adin.c
index a0f8b616bcb7..ddf0512a9a4d 100644
--- a/drivers/net/phy/adin.c
+++ b/drivers/net/phy/adin.c
@@ -6,6 +6,7 @@
*/
#include <linux/kernel.h>
#include <linux/bitfield.h>
+#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/module.h>
@@ -51,6 +52,9 @@
#define ADIN1300_CLOCK_STOP_REG 0x9400
#define ADIN1300_LPI_WAKE_ERR_CNT_REG 0xa000
+#define ADIN1300_GE_SOFT_RESET_REG 0xff0c
+#define ADIN1300_GE_SOFT_RESET BIT(0)
+
#define ADIN1300_GE_RGMII_CFG_REG 0xff23
#define ADIN1300_GE_RGMII_RX_MSK GENMASK(8, 6)
#define ADIN1300_GE_RGMII_RX_SEL(x) \
@@ -443,11 +447,49 @@ static int adin_read_status(struct phy_device *phydev)
return genphy_read_status(phydev);
}
+static int adin_subsytem_soft_reset(struct phy_device *phydev)
+{
+ int reg, rc, i;
+
+ rc = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+ ADIN1300_GE_SOFT_RESET_REG,
+ ADIN1300_GE_SOFT_RESET);
+ if (rc < 0)
+ return rc;
+
+ for (i = 0; i < 20; i++) {
+ usleep_range(500, 1000);
+ reg = phy_read_mmd(phydev, MDIO_MMD_VEND1,
+ ADIN1300_GE_SOFT_RESET_REG);
+ if (reg < 0 || (reg & ADIN1300_GE_SOFT_RESET))
+ continue;
+ return 0;
+ }
+
+ return -ETIMEDOUT;
+}
+
+static int adin_reset(struct phy_device *phydev)
+{
+ /* If there is a reset GPIO just exit */
+ if (!IS_ERR_OR_NULL(phydev->mdio.reset_gpio))
+ return 0;
+
+ /* Reset PHY core regs & subsystem regs */
+ return adin_subsytem_soft_reset(phydev);
+}
+
+static int adin_probe(struct phy_device *phydev)
+{
+ return adin_reset(phydev);
+}
+
static struct phy_driver adin_driver[] = {
{
PHY_ID_MATCH_MODEL(PHY_ID_ADIN1200),
.name = "ADIN1200",
.config_init = adin_config_init,
+ .probe = adin_probe,
.config_aneg = adin_config_aneg,
.read_status = adin_read_status,
.ack_interrupt = adin_phy_ack_intr,
@@ -461,6 +503,7 @@ static struct phy_driver adin_driver[] = {
PHY_ID_MATCH_MODEL(PHY_ID_ADIN1300),
.name = "ADIN1300",
.config_init = adin_config_init,
+ .probe = adin_probe,
.config_aneg = adin_config_aneg,
.read_status = adin_read_status,
.ack_interrupt = adin_phy_ack_intr,
--
2.20.1
^ permalink raw reply related
* [PATCH v4 12/14] net: phy: adin: implement downshift configuration via phy-tunable
From: Alexandru Ardelean @ 2019-08-12 11:23 UTC (permalink / raw)
To: netdev, devicetree, linux-kernel
Cc: davem, robh+dt, mark.rutland, f.fainelli, hkallweit1, andrew,
Alexandru Ardelean
In-Reply-To: <20190812112350.15242-1-alexandru.ardelean@analog.com>
Down-speed auto-negotiation may not always be enabled, in which case the
PHY won't down-shift to 100 or 10 during auto-negotiation.
This change enables downshift and configures the number of retries to
default 4 (which is also in the datasheet
The downshift control mechanism can also be controlled via the phy-tunable
interface (ETHTOOL_PHY_DOWNSHIFT control).
The change has been adapted from the Aquantia PHY driver.
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
---
drivers/net/phy/adin.c | 86 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 86 insertions(+)
diff --git a/drivers/net/phy/adin.c b/drivers/net/phy/adin.c
index 131a72567f25..e4afa8c2bec7 100644
--- a/drivers/net/phy/adin.c
+++ b/drivers/net/phy/adin.c
@@ -29,6 +29,17 @@
#define ADIN1300_NRG_PD_TX_EN BIT(2)
#define ADIN1300_NRG_PD_STATUS BIT(1)
+#define ADIN1300_PHY_CTRL2 0x0016
+#define ADIN1300_DOWNSPEED_AN_100_EN BIT(11)
+#define ADIN1300_DOWNSPEED_AN_10_EN BIT(10)
+#define ADIN1300_GROUP_MDIO_EN BIT(6)
+#define ADIN1300_DOWNSPEEDS_EN \
+ (ADIN1300_DOWNSPEED_AN_100_EN | ADIN1300_DOWNSPEED_AN_10_EN)
+
+#define ADIN1300_PHY_CTRL3 0x0017
+#define ADIN1300_LINKING_EN BIT(13)
+#define ADIN1300_DOWNSPEED_RETRIES_MSK GENMASK(12, 10)
+
#define ADIN1300_INT_MASK_REG 0x0018
#define ADIN1300_INT_MDIO_SYNC_EN BIT(9)
#define ADIN1300_INT_ANEG_STAT_CHNG_EN BIT(8)
@@ -257,6 +268,73 @@ static int adin_config_rmii_mode(struct phy_device *phydev)
ADIN1300_GE_RMII_CFG_REG, reg);
}
+static int adin_get_downshift(struct phy_device *phydev, u8 *data)
+{
+ int val, cnt, enable;
+
+ val = phy_read(phydev, ADIN1300_PHY_CTRL2);
+ if (val < 0)
+ return val;
+
+ cnt = phy_read(phydev, ADIN1300_PHY_CTRL3);
+ if (cnt < 0)
+ return cnt;
+
+ enable = FIELD_GET(ADIN1300_DOWNSPEEDS_EN, val);
+ cnt = FIELD_GET(ADIN1300_DOWNSPEED_RETRIES_MSK, cnt);
+
+ *data = enable & cnt ? cnt : DOWNSHIFT_DEV_DISABLE;
+
+ return 0;
+}
+
+static int adin_set_downshift(struct phy_device *phydev, u8 cnt)
+{
+ u16 val;
+ int rc;
+
+ if (cnt == DOWNSHIFT_DEV_DISABLE)
+ return phy_clear_bits(phydev, ADIN1300_PHY_CTRL2,
+ ADIN1300_DOWNSPEEDS_EN);
+
+ if (cnt > 8)
+ return -E2BIG;
+
+ val = FIELD_PREP(ADIN1300_DOWNSPEED_RETRIES_MSK, cnt);
+ val |= ADIN1300_LINKING_EN;
+
+ rc = phy_modify(phydev, ADIN1300_PHY_CTRL3,
+ ADIN1300_LINKING_EN | ADIN1300_DOWNSPEED_RETRIES_MSK,
+ val);
+ if (rc < 0)
+ return rc;
+
+ return phy_set_bits(phydev, ADIN1300_PHY_CTRL2,
+ ADIN1300_DOWNSPEEDS_EN);
+}
+
+static int adin_get_tunable(struct phy_device *phydev,
+ struct ethtool_tunable *tuna, void *data)
+{
+ switch (tuna->id) {
+ case ETHTOOL_PHY_DOWNSHIFT:
+ return adin_get_downshift(phydev, data);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int adin_set_tunable(struct phy_device *phydev,
+ struct ethtool_tunable *tuna, const void *data)
+{
+ switch (tuna->id) {
+ case ETHTOOL_PHY_DOWNSHIFT:
+ return adin_set_downshift(phydev, *(const u8 *)data);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
static int adin_config_init_edpd(struct phy_device *phydev)
{
struct adin_priv *priv = phydev->priv;
@@ -287,6 +365,10 @@ static int adin_config_init(struct phy_device *phydev)
if (rc < 0)
return rc;
+ rc = adin_set_downshift(phydev, 4);
+ if (rc < 0)
+ return rc;
+
rc = adin_config_init_edpd(phydev);
if (rc < 0)
return rc;
@@ -532,6 +614,8 @@ static struct phy_driver adin_driver[] = {
.probe = adin_probe,
.config_aneg = adin_config_aneg,
.read_status = adin_read_status,
+ .get_tunable = adin_get_tunable,
+ .set_tunable = adin_set_tunable,
.ack_interrupt = adin_phy_ack_intr,
.config_intr = adin_phy_config_intr,
.resume = genphy_resume,
@@ -546,6 +630,8 @@ static struct phy_driver adin_driver[] = {
.probe = adin_probe,
.config_aneg = adin_config_aneg,
.read_status = adin_read_status,
+ .get_tunable = adin_get_tunable,
+ .set_tunable = adin_set_tunable,
.ack_interrupt = adin_phy_ack_intr,
.config_intr = adin_phy_config_intr,
.resume = genphy_resume,
--
2.20.1
^ permalink raw reply related
* [PATCH v4 13/14] net: phy: adin: add ethtool get_stats support
From: Alexandru Ardelean @ 2019-08-12 11:23 UTC (permalink / raw)
To: netdev, devicetree, linux-kernel
Cc: davem, robh+dt, mark.rutland, f.fainelli, hkallweit1, andrew,
Alexandru Ardelean
In-Reply-To: <20190812112350.15242-1-alexandru.ardelean@analog.com>
This change implements retrieving all the error counters from the PHY.
The PHY supports several error counters/stats. The `Mean Square Errors`
status values are only valie when a link is established, and shouldn't be
accumulated. These values characterize the quality of a signal.
The rest of the error counters are self-clearing on read.
Most of them are reports from the Frame Checker engine that the PHY has.
Not retrieving the `LPI Wake Error Count Register` here, since that is used
by the PHY framework to check for any EEE errors. And that register is
self-clearing when read (as per IEEE spec).
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
---
drivers/net/phy/adin.c | 109 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 109 insertions(+)
diff --git a/drivers/net/phy/adin.c b/drivers/net/phy/adin.c
index e4afa8c2bec7..3ab15a585c1b 100644
--- a/drivers/net/phy/adin.c
+++ b/drivers/net/phy/adin.c
@@ -152,12 +152,40 @@ static struct adin_clause45_mmd_map adin_clause45_mmd_map[] = {
{ MDIO_MMD_PCS, MDIO_PCS_EEE_WK_ERR, ADIN1300_LPI_WAKE_ERR_CNT_REG },
};
+struct adin_hw_stat {
+ const char *string;
+ u16 reg1;
+ u16 reg2;
+ bool do_not_accumulate;
+};
+
+/* Named just like in the datasheet */
+static struct adin_hw_stat adin_hw_stats[] = {
+ { "RxErrCnt", 0x0014, },
+ { "MseA", 0x8402, 0, true },
+ { "MseB", 0x8403, 0, true },
+ { "MseC", 0x8404, 0, true },
+ { "MseD", 0x8405, 0, true },
+ { "FcFrmCnt", 0x940A, 0x940B }, /* FcFrmCntH + FcFrmCntL */
+ { "FcLenErrCnt", 0x940C },
+ { "FcAlgnErrCnt", 0x940D },
+ { "FcSymbErrCnt", 0x940E },
+ { "FcOszCnt", 0x940F },
+ { "FcUszCnt", 0x9410 },
+ { "FcOddCnt", 0x9411 },
+ { "FcOddPreCnt", 0x9412 },
+ { "FcDribbleBitsCnt", 0x9413 },
+ { "FcFalseCarrierCnt", 0x9414 },
+};
+
/**
* struct adin_priv - ADIN PHY driver private data
* edpd_enabled true if Energy Detect Powerdown mode is enabled
+ * stats statistic counters for the PHY
*/
struct adin_priv {
bool edpd_enabled;
+ u64 stats[ARRAY_SIZE(adin_hw_stats)];
};
static int adin_lookup_reg_value(const struct adin_cfg_reg_map *tbl, int cfg)
@@ -590,6 +618,81 @@ static int adin_reset(struct phy_device *phydev)
return adin_subsytem_soft_reset(phydev);
}
+static int adin_get_sset_count(struct phy_device *phydev)
+{
+ return ARRAY_SIZE(adin_hw_stats);
+}
+
+static void adin_get_strings(struct phy_device *phydev, u8 *data)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(adin_hw_stats); i++) {
+ strlcpy(&data[i * ETH_GSTRING_LEN],
+ adin_hw_stats[i].string, ETH_GSTRING_LEN);
+ }
+}
+
+static int adin_read_mmd_stat_regs(struct phy_device *phydev,
+ struct adin_hw_stat *stat,
+ u32 *val)
+{
+ int ret;
+
+ ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, stat->reg1);
+ if (ret < 0)
+ return ret;
+
+ *val = (ret & 0xffff);
+
+ if (stat->reg2 == 0)
+ return 0;
+
+ ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, stat->reg2);
+ if (ret < 0)
+ return ret;
+
+ *val <<= 16;
+ *val |= (ret & 0xffff);
+
+ return 0;
+}
+
+static u64 adin_get_stat(struct phy_device *phydev, int i)
+{
+ struct adin_hw_stat *stat = &adin_hw_stats[i];
+ struct adin_priv *priv = phydev->priv;
+ u32 val;
+ int ret;
+
+ if (stat->reg1 > 0x1f) {
+ ret = adin_read_mmd_stat_regs(phydev, stat, &val);
+ if (ret < 0)
+ return (u64)(~0);
+ } else {
+ ret = phy_read(phydev, stat->reg1);
+ if (ret < 0)
+ return (u64)(~0);
+ val = (ret & 0xffff);
+ }
+
+ if (stat->do_not_accumulate)
+ priv->stats[i] = val;
+ else
+ priv->stats[i] += val;
+
+ return priv->stats[i];
+}
+
+static void adin_get_stats(struct phy_device *phydev,
+ struct ethtool_stats *stats, u64 *data)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(adin_hw_stats); i++)
+ data[i] = adin_get_stat(phydev, i);
+}
+
static int adin_probe(struct phy_device *phydev)
{
struct device *dev = &phydev->mdio.dev;
@@ -618,6 +721,9 @@ static struct phy_driver adin_driver[] = {
.set_tunable = adin_set_tunable,
.ack_interrupt = adin_phy_ack_intr,
.config_intr = adin_phy_config_intr,
+ .get_sset_count = adin_get_sset_count,
+ .get_strings = adin_get_strings,
+ .get_stats = adin_get_stats,
.resume = genphy_resume,
.suspend = genphy_suspend,
.read_mmd = adin_read_mmd,
@@ -634,6 +740,9 @@ static struct phy_driver adin_driver[] = {
.set_tunable = adin_set_tunable,
.ack_interrupt = adin_phy_ack_intr,
.config_intr = adin_phy_config_intr,
+ .get_sset_count = adin_get_sset_count,
+ .get_strings = adin_get_strings,
+ .get_stats = adin_get_stats,
.resume = genphy_resume,
.suspend = genphy_suspend,
.read_mmd = adin_read_mmd,
--
2.20.1
^ permalink raw reply related
* [PATCH v4 14/14] dt-bindings: net: add bindings for ADIN PHY driver
From: Alexandru Ardelean @ 2019-08-12 11:23 UTC (permalink / raw)
To: netdev, devicetree, linux-kernel
Cc: davem, robh+dt, mark.rutland, f.fainelli, hkallweit1, andrew,
Alexandru Ardelean
In-Reply-To: <20190812112350.15242-1-alexandru.ardelean@analog.com>
This change adds bindings for the Analog Devices ADIN PHY driver, detailing
all the properties implemented by the driver.
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
---
.../devicetree/bindings/net/adi,adin.yaml | 73 +++++++++++++++++++
MAINTAINERS | 1 +
2 files changed, 74 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/adi,adin.yaml
diff --git a/Documentation/devicetree/bindings/net/adi,adin.yaml b/Documentation/devicetree/bindings/net/adi,adin.yaml
new file mode 100644
index 000000000000..69375cb28e92
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/adi,adin.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: GPL-2.0+
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/adi,adin.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices ADIN1200/ADIN1300 PHY
+
+maintainers:
+ - Alexandru Ardelean <alexandru.ardelean@analog.com>
+
+description: |
+ Bindings for Analog Devices Industrial Ethernet PHYs
+
+allOf:
+ - $ref: ethernet-phy.yaml#
+
+properties:
+ adi,rx-internal-delay-ps:
+ description: |
+ RGMII RX Clock Delay used only when PHY operates in RGMII mode with
+ internal delay (phy-mode is 'rgmii-id' or 'rgmii-rxid') in pico-seconds.
+ enum: [ 1600, 1800, 2000, 2200, 2400 ]
+ default: 2000
+
+ adi,tx-internal-delay-ps:
+ description: |
+ RGMII TX Clock Delay used only when PHY operates in RGMII mode with
+ internal delay (phy-mode is 'rgmii-id' or 'rgmii-txid') in pico-seconds.
+ enum: [ 1600, 1800, 2000, 2200, 2400 ]
+ default: 2000
+
+ adi,fifo-depth-bits:
+ description: |
+ When operating in RMII mode, this option configures the FIFO depth.
+ enum: [ 4, 8, 12, 16, 20, 24 ]
+ default: 8
+
+ adi,disable-energy-detect:
+ description: |
+ Disables Energy Detect Powerdown Mode (default disabled, i.e energy detect
+ is enabled if this property is unspecified)
+ type: boolean
+
+examples:
+ - |
+ ethernet {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ phy-mode = "rgmii-id";
+
+ ethernet-phy@0 {
+ reg = <0>;
+
+ adi,rx-internal-delay-ps = <1800>;
+ adi,tx-internal-delay-ps = <2200>;
+ };
+ };
+ - |
+ ethernet {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ phy-mode = "rmii";
+
+ ethernet-phy@1 {
+ reg = <1>;
+
+ adi,fifo-depth-bits = <16>;
+ adi,disable-energy-detect;
+ };
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index e8aa8a667864..fd9ab61c2670 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -944,6 +944,7 @@ L: netdev@vger.kernel.org
W: http://ez.analog.com/community/linux-device-drivers
S: Supported
F: drivers/net/phy/adin.c
+F: Documentation/devicetree/bindings/net/adi,adin.yaml
ANALOG DEVICES INC ADIS DRIVER LIBRARY
M: Alexandru Ardelean <alexandru.ardelean@analog.com>
--
2.20.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox