* Unaligned Memory Access on mesh_*.c files
@ 2019-08-10 4:07 Guo Wei Lim
2019-08-10 8:50 ` Johannes Berg
0 siblings, 1 reply; 4+ messages in thread
From: Guo Wei Lim @ 2019-08-10 4:07 UTC (permalink / raw)
To: linux-wireless
I have traced a large number of unaligned memory access on mips cpu
due to ether_addr_equal(), is_multicast_ether_addr(),
is_broadcast_ether_addr() being called on odd addresses.
Even though the values are u8, the inlines in etherdevice.h converts
them to u16 causing the issue.
I can replace ether_addr_equal() with ether_addr_equal_unaligned() but
it doesn't seem like a proper fix. Anyone has better ideas?
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Unaligned Memory Access on mesh_*.c files
2019-08-10 4:07 Unaligned Memory Access on mesh_*.c files Guo Wei Lim
@ 2019-08-10 8:50 ` Johannes Berg
2019-08-10 10:28 ` Guo Wei Lim
0 siblings, 1 reply; 4+ messages in thread
From: Johannes Berg @ 2019-08-10 8:50 UTC (permalink / raw)
To: Guo Wei Lim, linux-wireless
On August 10, 2019 6:07:15 AM GMT+02:00, Guo Wei Lim <limguowei@gmail.com> wrote:
>I have traced a large number of unaligned memory access on mips cpu
>due to ether_addr_equal(), is_multicast_ether_addr(),
>is_broadcast_ether_addr() being called on odd addresses.
>
>Even though the values are u8, the inlines in etherdevice.h converts
>them to u16 causing the issue.
>
>I can replace ether_addr_equal() with ether_addr_equal_unaligned() but
>it doesn't seem like a proper fix. Anyone has better ideas?
Can you say which places cause this,and which driver you're using? Also, I guess the type of frame and what address format it has would be good to know.
If you aren't also hitting the warning in rx.c about alignment though, it might be that we do in fact need to use code not expecting alignment.
johannes
--
Sent from my phone.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Unaligned Memory Access on mesh_*.c files
2019-08-10 8:50 ` Johannes Berg
@ 2019-08-10 10:28 ` Guo Wei Lim
2019-08-21 7:39 ` Johannes Berg
0 siblings, 1 reply; 4+ messages in thread
From: Guo Wei Lim @ 2019-08-10 10:28 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
Hi Johannes,
Correct me if I am wrong.
The problem is largely in net/mac80211/mesh_hwmp.c
The macros
#define PREQ_IE_ORIG_ADDR(x) (x + 7)
#define PREP_IE_TARGET_ADDR(x) (x + 3)
Almost guarantees the addresses will be odd when it hit the following
switch (action) {
case MPATH_PREQ:
orig_addr = PREQ_IE_ORIG_ADDR(hwmp_ie);
orig_sn = PREQ_IE_ORIG_SN(hwmp_ie);
orig_lifetime = PREQ_IE_LIFETIME(hwmp_ie);
orig_metric = PREQ_IE_METRIC(hwmp_ie);
hopcount = PREQ_IE_HOPCOUNT(hwmp_ie) + 1;
break;
case MPATH_PREP:
/* Originator here refers to the MP that was the target in the
* Path Request. We divert from the nomenclature in the draft
* so that we can easily use a single function to gather path
* information from both PREQ and PREP frames.
*/
orig_addr = PREP_IE_TARGET_ADDR(hwmp_ie);
orig_sn = PREP_IE_TARGET_SN(hwmp_ie);
orig_lifetime = PREP_IE_LIFETIME(hwmp_ie);
orig_metric = PREP_IE_METRIC(hwmp_ie);
hopcount = PREP_IE_HOPCOUNT(hwmp_ie) + 1;
break;
default:
rcu_read_unlock();
return 0;
}
So following that many functions like
if (ether_addr_equal(orig_addr, sdata->vif.addr)) {
Results in unaligned memory access
I traced and caught all the following functions creating unaligned memory access
This is just one example
[ 344.065508] Call Trace:
[ 344.068111] [<870d9b7c>] mesh_rx_plink_frame+0xed0/0x139c [mac80211]
[ 344.074626] Code: 96c40002 9646000c 00451026 <96c30004> 9645000e
00862026 00441025 00651826 00431025
[ 344.084628]
[ 344.086166] CPU: 0 PID: 5 Comm: kworker/u2:0 Not tainted 4.14.123 #0
[ 344.092833] Workqueue: phy1 ieee80211_ibss_leave [mac80211]
[ 344.098609] task: 87c25600 task.stack: 87c3a000
[ 344.103319] $ 0 : 00000000 00000001 00000000 00000000
[ 344.108656] $ 4 : 00000000 0000c46e 000067a5 00000000
[ 344.114057] $ 8 : 86e25464 00000001 00000004 873811e8
[ 344.119433] $12 : ffffffff 00000000 00b00000 00000000
[ 344.124806] $16 : 804f0000 8773f078 87315460 8773f082
[ 344.130155] $20 : 8773f094 8773f0a9 000000b3 870e89e8
[ 344.135485] $24 : 804ef040 870de528
[ 344.140915] $28 : 87c3a000 87c3bcb8 870e8a14 870da454
[ 344.146279] Hi : 0004e2ca
[ 344.149300] Lo : b0250b0d
[ 344.152383] epc : 870da988 mesh_rx_path_sel_frame+0x658/0xb08 [mac80211]
[ 344.159527] ra : 870da454 mesh_rx_path_sel_frame+0x124/0xb08 [mac80211]
[ 344.166543] Status: 1100dc03 KERNEL EXL IE
[ 344.170825] Cause : 00800010 (ExcCode 04)
[ 344.174894] BadVA : 8773f0a9
[ 344.177829] PrId : 0001974c (MIPS 74Kc)
[ 344.181881] Modules linked in: ath9k ath9k_common pppoe ppp_async
l2tp_ppp ath9k_hw ath qmi_wwan pptp pppox ppp_mppe ppp_generic
nf_conntrack_ipv6 mac80211 iptable_nat ipt_REJECT ipt_MASQUERADE
cfg80211 xt_time xt_tcpudp xt_tcpmss xt_statistic xt_state xt_recent
xt_nat xt_multiport xt_mark xt_mac xt_limit xt_length xt_hl xt_helper
xt_ecn xt_dscp xt_conntrack xt_connmark xt_connlimit xt_connbytes
xt_comment xt_TCPMSS xt_REDIRECT xt_LOG xt_HL xt_DSCP xt_CT
xt_CLASSIFY wireguard usbnet slhc nf_reject_ipv4 nf_nat_redirect
nf_nat_masquerade_ipv4 nf_conntrack_ipv4 nf_nat_ipv4 nf_nat
nf_log_ipv4 nf_defrag_ipv6 nf_defrag_ipv4 nf_conntrack_rtcache
nf_conntrack_netlink iptable_raw iptable_mangle iptable_filter ipt_ECN
ip_tables crc_ccitt compat cdc_wdm sch_cake nf_conntrack sch_tbf
sch_ingress sch_htb sch_hfsc
[ 344.254146] em_u32 cls_u32 cls_tcindex cls_route cls_matchall
cls_fw cls_flow cls_basic act_skbedit act_mirred ledtrig_usbport
cryptodev xt_set ip_set_list_set ip_set_hash_netportnet
ip_set_hash_netport ip_set_hash_netnet ip_set_hash_netiface
ip_set_hash_net ip_set_hash_mac ip_set_hash_ipportnet
ip_set_hash_ipportip ip_set_hash_ipport ip_set_hash_ipmark
ip_set_hash_ip ip_set_bitmap_port ip_set_bitmap_ipmac ip_set_bitmap_ip
ip_set nfnetlink nf_log_ipv6 nf_log_common ip6table_mangle
ip6table_filter ip6_tables ip6t_REJECT x_tables nf_reject_ipv6 ip_gre
gre ifb l2tp_netlink l2tp_core udp_tunnel ip6_udp_tunnel ip_tunnel tun
shortcut_fe_ipv6 shortcut_fe algif_skcipher algif_hash af_alg
sha1_generic ecb authenc ehci_platform ehci_hcd gpio_button_hotplug
usbcore nls_base usb_common mii aead cryptomgr crypto_null
[ 344.326861] crypto_hash
[ 344.329502] Process kworker/u2:0 (pid: 5, threadinfo=87c3a000,
task=87c25600, tls=00000000)
[ 344.338022] Stack : 0000002f 870ac7f0 00000000 20000009 00000000
00000000 00000000 00000041
[ 344.346622] 8717a780 804f0000 87315460 00000041 87380bc0
870b2d30 8717a780 8717a780
[ 344.355242] 000000a0 00000000 00000000 802d09dc 8773f092
00000021 00000000 00000000
[ 344.363839] 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000
[ 344.372380] 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000
[ 344.380888] ...
[ 344.383382] Call Trace:
[ 344.386011] [<870da988>] mesh_rx_path_sel_frame+0x658/0xb08 [mac80211]
[ 344.392801] [<870d5bb4>] ieee80211_mesh_rx_queued_mgmt+0x15c/0x164 [mac80211]
[ 344.400279] [<87097164>] ieee80211_ibss_leave+0x80c/0x1888 [mac80211]
[ 344.406922] [<870d5cd0>] ieee80211_mesh_work+0x114/0x2cc [mac80211]
[ 344.413498] [<8009d280>] process_one_work+0x1f8/0x428
[ 344.418706] [<8009d630>] worker_thread+0x180/0x548
[ 344.423692] [<800a3a04>] kthread+0x134/0x13c
[ 344.428075] [<80066db8>] ret_from_kernel_thread+0x14/0x1c
[ 344.433622] Code: 26950015 2695001b 964508a0 <96a20000> 96a40002
964608a2 00451026 96a30004 964508a4
orig_addr = PREP_IE_ORIG_ADDR(prep_elem);
5bb7c: 92620000 lbu v0,0(s3)
5bb80: 30420040 andi v0,v0,0x40
5bb84: 14400002 bnez v0,5bb90 <mesh_rx_path_sel_frame+0x510>
5bb88: 2674001b addiu s4,s3,27
5bb8c: 26740015 addiu s4,s3,21
return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) == 0;
5bb90: 962508b8 lhu a1,2232(s1)
5bb94: 96820000 lhu v0,0(s4)
5bb98: 96840002 lhu a0,2(s4)
5bb9c: 962608ba lhu a2,2234(s1)
5bba0: 00451026 xor v0,v0,a1
5bba4: 96830004 lhu v1,4(s4)
5bba8: 962508bc lhu a1,2236(s1)
5bbac: 00862026 xor a0,a0,a2
5bbb0: 00441025 or v0,v0,a0
5bbb4: 00651826 xor v1,v1,a1
if (ether_addr_equal(orig_addr, sdata->vif.addr))
I have tested that replacing ether_addr_equal with
ether_addr_equal_unaligned fixes the issue but this happens in many
places as well as other functions like is_multicast_ether_addr(),
is_broadcast_ether_addr() so it isn't the correct fix.
On Sat, Aug 10, 2019 at 8:50 AM Johannes Berg <johannes@sipsolutions.net> wrote:
>
>
>
> On August 10, 2019 6:07:15 AM GMT+02:00, Guo Wei Lim <limguowei@gmail.com> wrote:
> >I have traced a large number of unaligned memory access on mips cpu
> >due to ether_addr_equal(), is_multicast_ether_addr(),
> >is_broadcast_ether_addr() being called on odd addresses.
> >
> >Even though the values are u8, the inlines in etherdevice.h converts
> >them to u16 causing the issue.
> >
> >I can replace ether_addr_equal() with ether_addr_equal_unaligned() but
> >it doesn't seem like a proper fix. Anyone has better ideas?
>
> Can you say which places cause this,and which driver you're using? Also, I guess the type of frame and what address format it has would be good to know.
>
> If you aren't also hitting the warning in rx.c about alignment though, it might be that we do in fact need to use code not expecting alignment.
>
> johannes
> --
> Sent from my phone.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Unaligned Memory Access on mesh_*.c files
2019-08-10 10:28 ` Guo Wei Lim
@ 2019-08-21 7:39 ` Johannes Berg
0 siblings, 0 replies; 4+ messages in thread
From: Johannes Berg @ 2019-08-21 7:39 UTC (permalink / raw)
To: Guo Wei Lim; +Cc: linux-wireless
On Sat, 2019-08-10 at 10:28 +0000, Guo Wei Lim wrote:
> Hi Johannes,
>
> Correct me if I am wrong.
> The problem is largely in net/mac80211/mesh_hwmp.c
> The macros
> #define PREQ_IE_ORIG_ADDR(x) (x + 7)
> #define PREP_IE_TARGET_ADDR(x) (x + 3)
>
> Almost guarantees the addresses will be odd when it hit the following
Oh, yeah, good point.
> if (ether_addr_equal(orig_addr, sdata->vif.addr)) {
>
> Results in unaligned memory access
Right.
> I have tested that replacing ether_addr_equal with
> ether_addr_equal_unaligned fixes the issue but this happens in many
> places as well as other functions like is_multicast_ether_addr(),
> is_broadcast_ether_addr() so it isn't the correct fix.
Unfortunately, I think it _is_ in fact the correct (and only possible)
fix, I can't think of anything other than making the code properly
handle unaligned addresses, as they do seem to happen here.
johannes
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2019-08-21 7:39 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-10 4:07 Unaligned Memory Access on mesh_*.c files Guo Wei Lim
2019-08-10 8:50 ` Johannes Berg
2019-08-10 10:28 ` Guo Wei Lim
2019-08-21 7:39 ` Johannes Berg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).