Skip to content

Commit b9e63d6

Browse files
Ranjan Kumarmartinkpetersen
authored andcommitted
scsi: mpi3mr: Validate SAS port assignments
A sanity check on phy_mask was added in commit 3668651 ("scsi: mpi3mr: Sanitise num_phys"). This causes warning messages when more than 64 phys are detected and devices connected to phys greater than 64 are dropped. The phy_mask bitmap is only needed for controller phys and not required for expander phys. Controller phys can go up to a maximum of 64 and therefore u64 is good enough to contain phy_mask bitmap. To suppress those warnings and allow devices to be discovered as before the offending commit, restrict the phy_mask setting and lowest phy setting only to the controller phys. Fixes: 3668651 ("scsi: mpi3mr: Sanitise num_phys") Cc: stable@vger.kernel.org Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202410051943.Mp9o5DlF-lkp@intel.com/ Reported-by: Alexander Motin <mav@ixsystems.com> Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com> Link: https://lore.kernel.org/r/20241008074353.200379-1-ranjan.kumar@broadcom.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent 19a198b commit b9e63d6

File tree

2 files changed

+29
-17
lines changed

2 files changed

+29
-17
lines changed

drivers/scsi/mpi3mr/mpi3mr.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -542,8 +542,8 @@ struct mpi3mr_hba_port {
542542
* @port_list: List of ports belonging to a SAS node
543543
* @num_phys: Number of phys associated with port
544544
* @marked_responding: used while refresing the sas ports
545-
* @lowest_phy: lowest phy ID of current sas port
546-
* @phy_mask: phy_mask of current sas port
545+
* @lowest_phy: lowest phy ID of current sas port, valid for controller port
546+
* @phy_mask: phy_mask of current sas port, valid for controller port
547547
* @hba_port: HBA port entry
548548
* @remote_identify: Attached device identification
549549
* @rphy: SAS transport layer rphy object

drivers/scsi/mpi3mr/mpi3mr_transport.c

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -590,12 +590,13 @@ static enum sas_linkrate mpi3mr_convert_phy_link_rate(u8 link_rate)
590590
* @mrioc: Adapter instance reference
591591
* @mr_sas_port: Internal Port object
592592
* @mr_sas_phy: Internal Phy object
593+
* @host_node: Flag to indicate this is a host_node
593594
*
594595
* Return: None.
595596
*/
596597
static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc,
597598
struct mpi3mr_sas_port *mr_sas_port,
598-
struct mpi3mr_sas_phy *mr_sas_phy)
599+
struct mpi3mr_sas_phy *mr_sas_phy, u8 host_node)
599600
{
600601
u64 sas_address = mr_sas_port->remote_identify.sas_address;
601602

@@ -605,9 +606,13 @@ static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc,
605606

606607
list_del(&mr_sas_phy->port_siblings);
607608
mr_sas_port->num_phys--;
608-
mr_sas_port->phy_mask &= ~(1 << mr_sas_phy->phy_id);
609-
if (mr_sas_port->lowest_phy == mr_sas_phy->phy_id)
610-
mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1;
609+
610+
if (host_node) {
611+
mr_sas_port->phy_mask &= ~(1 << mr_sas_phy->phy_id);
612+
613+
if (mr_sas_port->lowest_phy == mr_sas_phy->phy_id)
614+
mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1;
615+
}
611616
sas_port_delete_phy(mr_sas_port->port, mr_sas_phy->phy);
612617
mr_sas_phy->phy_belongs_to_port = 0;
613618
}
@@ -617,12 +622,13 @@ static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc,
617622
* @mrioc: Adapter instance reference
618623
* @mr_sas_port: Internal Port object
619624
* @mr_sas_phy: Internal Phy object
625+
* @host_node: Flag to indicate this is a host_node
620626
*
621627
* Return: None.
622628
*/
623629
static void mpi3mr_add_sas_phy(struct mpi3mr_ioc *mrioc,
624630
struct mpi3mr_sas_port *mr_sas_port,
625-
struct mpi3mr_sas_phy *mr_sas_phy)
631+
struct mpi3mr_sas_phy *mr_sas_phy, u8 host_node)
626632
{
627633
u64 sas_address = mr_sas_port->remote_identify.sas_address;
628634

@@ -632,9 +638,12 @@ static void mpi3mr_add_sas_phy(struct mpi3mr_ioc *mrioc,
632638

633639
list_add_tail(&mr_sas_phy->port_siblings, &mr_sas_port->phy_list);
634640
mr_sas_port->num_phys++;
635-
mr_sas_port->phy_mask |= (1 << mr_sas_phy->phy_id);
636-
if (mr_sas_phy->phy_id < mr_sas_port->lowest_phy)
637-
mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1;
641+
if (host_node) {
642+
mr_sas_port->phy_mask |= (1 << mr_sas_phy->phy_id);
643+
644+
if (mr_sas_phy->phy_id < mr_sas_port->lowest_phy)
645+
mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1;
646+
}
638647
sas_port_add_phy(mr_sas_port->port, mr_sas_phy->phy);
639648
mr_sas_phy->phy_belongs_to_port = 1;
640649
}
@@ -675,7 +684,7 @@ static void mpi3mr_add_phy_to_an_existing_port(struct mpi3mr_ioc *mrioc,
675684
if (srch_phy == mr_sas_phy)
676685
return;
677686
}
678-
mpi3mr_add_sas_phy(mrioc, mr_sas_port, mr_sas_phy);
687+
mpi3mr_add_sas_phy(mrioc, mr_sas_port, mr_sas_phy, mr_sas_node->host_node);
679688
return;
680689
}
681690
}
@@ -736,7 +745,7 @@ static void mpi3mr_del_phy_from_an_existing_port(struct mpi3mr_ioc *mrioc,
736745
mpi3mr_delete_sas_port(mrioc, mr_sas_port);
737746
else
738747
mpi3mr_delete_sas_phy(mrioc, mr_sas_port,
739-
mr_sas_phy);
748+
mr_sas_phy, mr_sas_node->host_node);
740749
return;
741750
}
742751
}
@@ -1028,7 +1037,7 @@ mpi3mr_alloc_hba_port(struct mpi3mr_ioc *mrioc, u16 port_id)
10281037
/**
10291038
* mpi3mr_get_hba_port_by_id - find hba port by id
10301039
* @mrioc: Adapter instance reference
1031-
* @port_id - Port ID to search
1040+
* @port_id: Port ID to search
10321041
*
10331042
* Return: mpi3mr_hba_port reference for the matched port
10341043
*/
@@ -1367,7 +1376,8 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc,
13671376
mpi3mr_sas_port_sanity_check(mrioc, mr_sas_node,
13681377
mr_sas_port->remote_identify.sas_address, hba_port);
13691378

1370-
if (mr_sas_node->num_phys >= sizeof(mr_sas_port->phy_mask) * 8)
1379+
if (mr_sas_node->host_node && mr_sas_node->num_phys >=
1380+
sizeof(mr_sas_port->phy_mask) * 8)
13711381
ioc_info(mrioc, "max port count %u could be too high\n",
13721382
mr_sas_node->num_phys);
13731383

@@ -1377,15 +1387,16 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc,
13771387
(mr_sas_node->phy[i].hba_port != hba_port))
13781388
continue;
13791389

1380-
if (i >= sizeof(mr_sas_port->phy_mask) * 8) {
1390+
if (mr_sas_node->host_node && (i >= sizeof(mr_sas_port->phy_mask) * 8)) {
13811391
ioc_warn(mrioc, "skipping port %u, max allowed value is %zu\n",
13821392
i, sizeof(mr_sas_port->phy_mask) * 8);
13831393
goto out_fail;
13841394
}
13851395
list_add_tail(&mr_sas_node->phy[i].port_siblings,
13861396
&mr_sas_port->phy_list);
13871397
mr_sas_port->num_phys++;
1388-
mr_sas_port->phy_mask |= (1 << i);
1398+
if (mr_sas_node->host_node)
1399+
mr_sas_port->phy_mask |= (1 << i);
13891400
}
13901401

13911402
if (!mr_sas_port->num_phys) {
@@ -1394,7 +1405,8 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc,
13941405
goto out_fail;
13951406
}
13961407

1397-
mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1;
1408+
if (mr_sas_node->host_node)
1409+
mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1;
13981410

13991411
if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) {
14001412
tgtdev = mpi3mr_get_tgtdev_by_addr(mrioc,

0 commit comments

Comments
 (0)