scsi: mpt3sas: Use 63-bit DMA addressing on SAS35 HBA
commit df9a606184bfdb5ae3ca9d226184e9489f5c24f7 upstream. Although SAS3 & SAS3.5 IT HBA controllers support 64-bit DMA addressing, as per hardware design, if DMA-able range contains all 64-bits set (0xFFFFFFFF-FFFFFFFF) then it results in a firmware fault. E.g. SGE's start address is 0xFFFFFFFF-FFFF000 and data length is 0x1000 bytes. when HBA tries to DMA the data at 0xFFFFFFFF-FFFFFFFF location then HBA will fault the firmware. Driver will set 63-bit DMA mask to ensure the above address will not be used. Cc: <stable@vger.kernel.org> # 5.1.20+ Signed-off-by: Suganath Prabu <suganath-prabu.subramani@broadcom.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
3475e0c3b2
commit
9841b51b04
1 changed files with 7 additions and 5 deletions
|
@ -1686,9 +1686,11 @@ _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
struct sysinfo s;
|
struct sysinfo s;
|
||||||
u64 consistent_dma_mask;
|
u64 consistent_dma_mask;
|
||||||
|
/* Set 63 bit DMA mask for all SAS3 and SAS35 controllers */
|
||||||
|
int dma_mask = (ioc->hba_mpi_version_belonged > MPI2_VERSION) ? 63 : 64;
|
||||||
|
|
||||||
if (ioc->dma_mask)
|
if (ioc->dma_mask)
|
||||||
consistent_dma_mask = DMA_BIT_MASK(64);
|
consistent_dma_mask = DMA_BIT_MASK(dma_mask);
|
||||||
else
|
else
|
||||||
consistent_dma_mask = DMA_BIT_MASK(32);
|
consistent_dma_mask = DMA_BIT_MASK(32);
|
||||||
|
|
||||||
|
@ -1696,11 +1698,11 @@ _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev)
|
||||||
const uint64_t required_mask =
|
const uint64_t required_mask =
|
||||||
dma_get_required_mask(&pdev->dev);
|
dma_get_required_mask(&pdev->dev);
|
||||||
if ((required_mask > DMA_BIT_MASK(32)) &&
|
if ((required_mask > DMA_BIT_MASK(32)) &&
|
||||||
!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) &&
|
!pci_set_dma_mask(pdev, DMA_BIT_MASK(dma_mask)) &&
|
||||||
!pci_set_consistent_dma_mask(pdev, consistent_dma_mask)) {
|
!pci_set_consistent_dma_mask(pdev, consistent_dma_mask)) {
|
||||||
ioc->base_add_sg_single = &_base_add_sg_single_64;
|
ioc->base_add_sg_single = &_base_add_sg_single_64;
|
||||||
ioc->sge_size = sizeof(Mpi2SGESimple64_t);
|
ioc->sge_size = sizeof(Mpi2SGESimple64_t);
|
||||||
ioc->dma_mask = 64;
|
ioc->dma_mask = dma_mask;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1726,7 +1728,7 @@ static int
|
||||||
_base_change_consistent_dma_mask(struct MPT3SAS_ADAPTER *ioc,
|
_base_change_consistent_dma_mask(struct MPT3SAS_ADAPTER *ioc,
|
||||||
struct pci_dev *pdev)
|
struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
|
if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(ioc->dma_mask))) {
|
||||||
if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))
|
if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
@ -3325,7 +3327,7 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
|
||||||
total_sz += sz;
|
total_sz += sz;
|
||||||
} while (ioc->rdpq_array_enable && (++i < ioc->reply_queue_count));
|
} while (ioc->rdpq_array_enable && (++i < ioc->reply_queue_count));
|
||||||
|
|
||||||
if (ioc->dma_mask == 64) {
|
if (ioc->dma_mask > 32) {
|
||||||
if (_base_change_consistent_dma_mask(ioc, ioc->pdev) != 0) {
|
if (_base_change_consistent_dma_mask(ioc, ioc->pdev) != 0) {
|
||||||
pr_warn(MPT3SAS_FMT
|
pr_warn(MPT3SAS_FMT
|
||||||
"no suitable consistent DMA mask for %s\n",
|
"no suitable consistent DMA mask for %s\n",
|
||||||
|
|
Loading…
Add table
Reference in a new issue