Skip to content

Commit ad6819c

Browse files
weiny2gregkh
authored andcommitted
IB/hfi1: Define variables as unsigned long to fix KASAN warning
commit f8659d6 upstream. Define the working variables to be unsigned long to be compatible with for_each_set_bit and change types as needed. While we are at it remove unused variables from a couple of functions. This was found because of the following KASAN warning: ================================================================== BUG: KASAN: stack-out-of-bounds in find_first_bit+0x19/0x70 Read of size 8 at addr ffff888362d778d0 by task kworker/u308:2/1889 CPU: 21 PID: 1889 Comm: kworker/u308:2 Tainted: G W 5.3.0-rc2-mm1+ #2 Hardware name: Intel Corporation W2600CR/W2600CR, BIOS SE5C600.86B.02.04.0003.102320141138 10/23/2014 Workqueue: ib-comp-unb-wq ib_cq_poll_work [ib_core] Call Trace: dump_stack+0x9a/0xf0 ? find_first_bit+0x19/0x70 print_address_description+0x6c/0x332 ? find_first_bit+0x19/0x70 ? find_first_bit+0x19/0x70 __kasan_report.cold.6+0x1a/0x3b ? find_first_bit+0x19/0x70 kasan_report+0xe/0x12 find_first_bit+0x19/0x70 pma_get_opa_portstatus+0x5cc/0xa80 [hfi1] ? ret_from_fork+0x3a/0x50 ? pma_get_opa_port_ectrs+0x200/0x200 [hfi1] ? stack_trace_consume_entry+0x80/0x80 hfi1_process_mad+0x39b/0x26c0 [hfi1] ? __lock_acquire+0x65e/0x21b0 ? clear_linkup_counters+0xb0/0xb0 [hfi1] ? check_chain_key+0x1d7/0x2e0 ? lock_downgrade+0x3a0/0x3a0 ? match_held_lock+0x2e/0x250 ib_mad_recv_done+0x698/0x15e0 [ib_core] ? clear_linkup_counters+0xb0/0xb0 [hfi1] ? ib_mad_send_done+0xc80/0xc80 [ib_core] ? mark_held_locks+0x79/0xa0 ? _raw_spin_unlock_irqrestore+0x44/0x60 ? rvt_poll_cq+0x1e1/0x340 [rdmavt] __ib_process_cq+0x97/0x100 [ib_core] ib_cq_poll_work+0x31/0xb0 [ib_core] process_one_work+0x4ee/0xa00 ? pwq_dec_nr_in_flight+0x110/0x110 ? do_raw_spin_lock+0x113/0x1d0 worker_thread+0x57/0x5a0 ? process_one_work+0xa00/0xa00 kthread+0x1bb/0x1e0 ? kthread_create_on_node+0xc0/0xc0 ret_from_fork+0x3a/0x50 The buggy address belongs to the page: page:ffffea000d8b5dc0 refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 flags: 0x17ffffc0000000() raw: 0017ffffc0000000 0000000000000000 ffffea000d8b5dc8 0000000000000000 raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000 page dumped because: kasan: bad access detected addr ffff888362d778d0 is located in stack of task kworker/u308:2/1889 at offset 32 in frame: pma_get_opa_portstatus+0x0/0xa80 [hfi1] this frame has 1 object: [32, 36) 'vl_select_mask' Memory state around the buggy address: ffff888362d77780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffff888362d77800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >ffff888362d77880: 00 00 00 00 00 00 f1 f1 f1 f1 04 f2 f2 f2 00 00 ^ ffff888362d77900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffff888362d77980: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 04 f2 f2 f2 ================================================================== Cc: <stable@vger.kernel.org> Fixes: 7724105 ("IB/hfi1: add driver files") Link: https://lore.kernel.org/r/20190911113053.126040.47327.stgit@awfm-01.aw.intel.com Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com> Signed-off-by: Ira Weiny <ira.weiny@intel.com> Signed-off-by: Kaike Wan <kaike.wan@intel.com> Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent a924850 commit ad6819c

File tree

1 file changed

+19
-26
lines changed
  • drivers/infiniband/hw/hfi1

1 file changed

+19
-26
lines changed

drivers/infiniband/hw/hfi1/mad.c

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2326,7 +2326,7 @@ struct opa_port_status_req {
23262326
__be32 vl_select_mask;
23272327
};
23282328

2329-
#define VL_MASK_ALL 0x000080ff
2329+
#define VL_MASK_ALL 0x00000000000080ffUL
23302330

23312331
struct opa_port_status_rsp {
23322332
__u8 port_num;
@@ -2625,15 +2625,14 @@ static int pma_get_opa_classportinfo(struct opa_pma_mad *pmp,
26252625
}
26262626

26272627
static void a0_portstatus(struct hfi1_pportdata *ppd,
2628-
struct opa_port_status_rsp *rsp, u32 vl_select_mask)
2628+
struct opa_port_status_rsp *rsp)
26292629
{
26302630
if (!is_bx(ppd->dd)) {
26312631
unsigned long vl;
26322632
u64 sum_vl_xmit_wait = 0;
2633-
u32 vl_all_mask = VL_MASK_ALL;
2633+
unsigned long vl_all_mask = VL_MASK_ALL;
26342634

2635-
for_each_set_bit(vl, (unsigned long *)&(vl_all_mask),
2636-
8 * sizeof(vl_all_mask)) {
2635+
for_each_set_bit(vl, &vl_all_mask, BITS_PER_LONG) {
26372636
u64 tmp = sum_vl_xmit_wait +
26382637
read_port_cntr(ppd, C_TX_WAIT_VL,
26392638
idx_from_vl(vl));
@@ -2730,12 +2729,12 @@ static int pma_get_opa_portstatus(struct opa_pma_mad *pmp,
27302729
(struct opa_port_status_req *)pmp->data;
27312730
struct hfi1_devdata *dd = dd_from_ibdev(ibdev);
27322731
struct opa_port_status_rsp *rsp;
2733-
u32 vl_select_mask = be32_to_cpu(req->vl_select_mask);
2732+
unsigned long vl_select_mask = be32_to_cpu(req->vl_select_mask);
27342733
unsigned long vl;
27352734
size_t response_data_size;
27362735
u32 nports = be32_to_cpu(pmp->mad_hdr.attr_mod) >> 24;
27372736
u8 port_num = req->port_num;
2738-
u8 num_vls = hweight32(vl_select_mask);
2737+
u8 num_vls = hweight64(vl_select_mask);
27392738
struct _vls_pctrs *vlinfo;
27402739
struct hfi1_ibport *ibp = to_iport(ibdev, port);
27412740
struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
@@ -2771,7 +2770,7 @@ static int pma_get_opa_portstatus(struct opa_pma_mad *pmp,
27712770

27722771
hfi1_read_link_quality(dd, &rsp->link_quality_indicator);
27732772

2774-
rsp->vl_select_mask = cpu_to_be32(vl_select_mask);
2773+
rsp->vl_select_mask = cpu_to_be32((u32)vl_select_mask);
27752774
rsp->port_xmit_data = cpu_to_be64(read_dev_cntr(dd, C_DC_XMIT_FLITS,
27762775
CNTR_INVALID_VL));
27772776
rsp->port_rcv_data = cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_FLITS,
@@ -2842,8 +2841,7 @@ static int pma_get_opa_portstatus(struct opa_pma_mad *pmp,
28422841
* So in the for_each_set_bit() loop below, we don't need
28432842
* any additional checks for vl.
28442843
*/
2845-
for_each_set_bit(vl, (unsigned long *)&(vl_select_mask),
2846-
8 * sizeof(vl_select_mask)) {
2844+
for_each_set_bit(vl, &vl_select_mask, BITS_PER_LONG) {
28472845
memset(vlinfo, 0, sizeof(*vlinfo));
28482846

28492847
tmp = read_dev_cntr(dd, C_DC_RX_FLIT_VL, idx_from_vl(vl));
@@ -2884,7 +2882,7 @@ static int pma_get_opa_portstatus(struct opa_pma_mad *pmp,
28842882
vfi++;
28852883
}
28862884

2887-
a0_portstatus(ppd, rsp, vl_select_mask);
2885+
a0_portstatus(ppd, rsp);
28882886

28892887
if (resp_len)
28902888
*resp_len += response_data_size;
@@ -2931,16 +2929,14 @@ static u64 get_error_counter_summary(struct ib_device *ibdev, u8 port,
29312929
return error_counter_summary;
29322930
}
29332931

2934-
static void a0_datacounters(struct hfi1_pportdata *ppd, struct _port_dctrs *rsp,
2935-
u32 vl_select_mask)
2932+
static void a0_datacounters(struct hfi1_pportdata *ppd, struct _port_dctrs *rsp)
29362933
{
29372934
if (!is_bx(ppd->dd)) {
29382935
unsigned long vl;
29392936
u64 sum_vl_xmit_wait = 0;
2940-
u32 vl_all_mask = VL_MASK_ALL;
2937+
unsigned long vl_all_mask = VL_MASK_ALL;
29412938

2942-
for_each_set_bit(vl, (unsigned long *)&(vl_all_mask),
2943-
8 * sizeof(vl_all_mask)) {
2939+
for_each_set_bit(vl, &vl_all_mask, BITS_PER_LONG) {
29442940
u64 tmp = sum_vl_xmit_wait +
29452941
read_port_cntr(ppd, C_TX_WAIT_VL,
29462942
idx_from_vl(vl));
@@ -2995,7 +2991,7 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp,
29952991
u64 port_mask;
29962992
u8 port_num;
29972993
unsigned long vl;
2998-
u32 vl_select_mask;
2994+
unsigned long vl_select_mask;
29992995
int vfi;
30002996
u16 link_width;
30012997
u16 link_speed;
@@ -3073,8 +3069,7 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp,
30733069
* So in the for_each_set_bit() loop below, we don't need
30743070
* any additional checks for vl.
30753071
*/
3076-
for_each_set_bit(vl, (unsigned long *)&(vl_select_mask),
3077-
8 * sizeof(req->vl_select_mask)) {
3072+
for_each_set_bit(vl, &vl_select_mask, BITS_PER_LONG) {
30783073
memset(vlinfo, 0, sizeof(*vlinfo));
30793074

30803075
rsp->vls[vfi].port_vl_xmit_data =
@@ -3122,7 +3117,7 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp,
31223117
vfi++;
31233118
}
31243119

3125-
a0_datacounters(ppd, rsp, vl_select_mask);
3120+
a0_datacounters(ppd, rsp);
31263121

31273122
if (resp_len)
31283123
*resp_len += response_data_size;
@@ -3217,7 +3212,7 @@ static int pma_get_opa_porterrors(struct opa_pma_mad *pmp,
32173212
struct _vls_ectrs *vlinfo;
32183213
unsigned long vl;
32193214
u64 port_mask, tmp;
3220-
u32 vl_select_mask;
3215+
unsigned long vl_select_mask;
32213216
int vfi;
32223217

32233218
req = (struct opa_port_error_counters64_msg *)pmp->data;
@@ -3276,8 +3271,7 @@ static int pma_get_opa_porterrors(struct opa_pma_mad *pmp,
32763271
vlinfo = &rsp->vls[0];
32773272
vfi = 0;
32783273
vl_select_mask = be32_to_cpu(req->vl_select_mask);
3279-
for_each_set_bit(vl, (unsigned long *)&(vl_select_mask),
3280-
8 * sizeof(req->vl_select_mask)) {
3274+
for_each_set_bit(vl, &vl_select_mask, BITS_PER_LONG) {
32813275
memset(vlinfo, 0, sizeof(*vlinfo));
32823276
rsp->vls[vfi].port_vl_xmit_discards =
32833277
cpu_to_be64(read_port_cntr(ppd, C_SW_XMIT_DSCD_VL,
@@ -3488,7 +3482,7 @@ static int pma_set_opa_portstatus(struct opa_pma_mad *pmp,
34883482
u32 nports = be32_to_cpu(pmp->mad_hdr.attr_mod) >> 24;
34893483
u64 portn = be64_to_cpu(req->port_select_mask[3]);
34903484
u32 counter_select = be32_to_cpu(req->counter_select_mask);
3491-
u32 vl_select_mask = VL_MASK_ALL; /* clear all per-vl cnts */
3485+
unsigned long vl_select_mask = VL_MASK_ALL; /* clear all per-vl cnts */
34923486
unsigned long vl;
34933487

34943488
if ((nports != 1) || (portn != 1 << port)) {
@@ -3582,8 +3576,7 @@ static int pma_set_opa_portstatus(struct opa_pma_mad *pmp,
35823576
if (counter_select & CS_UNCORRECTABLE_ERRORS)
35833577
write_dev_cntr(dd, C_DC_UNC_ERR, CNTR_INVALID_VL, 0);
35843578

3585-
for_each_set_bit(vl, (unsigned long *)&(vl_select_mask),
3586-
8 * sizeof(vl_select_mask)) {
3579+
for_each_set_bit(vl, &vl_select_mask, BITS_PER_LONG) {
35873580
if (counter_select & CS_PORT_XMIT_DATA)
35883581
write_port_cntr(ppd, C_TX_FLIT_VL, idx_from_vl(vl), 0);
35893582

0 commit comments

Comments
 (0)