diff options
| author | Vivian Wang <wangruikang@iscas.ac.cn> | 2026-01-29 09:56:06 +0800 |
|---|---|---|
| committer | Thomas Gleixner <tglx@kernel.org> | 2026-01-31 01:11:48 +0100 |
| commit | 386ced19e9a348e8131d20f009e692fa8fcc4568 (patch) | |
| tree | 07e95b5949b774feba691dae8d8408ecb9aab05f /arch | |
| parent | 37f9d5026cd78fbe80a124edbbadab382b26545f (diff) | |
PCI/MSI: Convert the boolean no_64bit_msi flag to a DMA address mask
Some PCI devices have PCI_MSI_FLAGS_64BIT in the MSI capability, but
implement less than 64 address bits. This breaks on platforms where such
a device is assigned an MSI address higher than what's supported.
Currently, no_64bit_msi bit is set for these devices, meaning that only
32-bit MSI addresses are allowed for them. However, on some platforms the
MSI doorbell address is above the 32-bit limit but within the addressable
range of the device.
As a first step to enable MSI on those combinations of devices and
platforms, convert the boolean no_64bit_msi flag to a DMA mask and fixup
the affected usage sites:
- no_64bit_msi = 1 -> msi_addr_mask = DMA_BIT_MASK(32)
- no_64bit_msi = 0 -> msi_addr_mask = DMA_BIT_MASK(64)
- if (no_64bit_msi) -> if (msi_addr_mask < DMA_BIT_MASK(64))
Since no values other than DMA_BIT_MASK(32) and DMA_BIT_MASK(64) are used,
this is functionally equivalent.
This prepares for changing the binary decision between 32 and 64 bit to a
DMA mask based decision which allows to support systems which have a DMA
address space less than 64bit but a MSI doorbell address above the 32-bit
limit.
[ tglx: Massaged changelog ]
Signed-off-by: Vivian Wang <wangruikang@iscas.ac.cn>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Brett Creeley <brett.creeley@amd.com> # ionic
Reviewed-by: Thomas Gleixner <tglx@kernel.org>
Acked-by: Takashi Iwai <tiwai@suse.de> # sound
Link: https://patch.msgid.link/20260129-pci-msi-addr-mask-v4-1-70da998f2750@iscas.ac.cn
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/powerpc/platforms/powernv/pci-ioda.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/platforms/pseries/msi.c | 4 |
2 files changed, 3 insertions, 3 deletions
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index b0c1d9d16fb5..1c78fdfb7b03 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -1666,7 +1666,7 @@ static int __pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, return -ENXIO; /* Force 32-bit MSI on some broken devices */ - if (dev->no_64bit_msi) + if (dev->msi_addr_mask < DMA_BIT_MASK(64)) is_64 = 0; /* Assign XIVE to PE */ diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index a82aaa786e9e..7473c7ca1db0 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c @@ -383,7 +383,7 @@ static int rtas_prepare_msi_irqs(struct pci_dev *pdev, int nvec_in, int type, */ again: if (type == PCI_CAP_ID_MSI) { - if (pdev->no_64bit_msi) { + if (pdev->msi_addr_mask < DMA_BIT_MASK(64)) { rc = rtas_change_msi(pdn, RTAS_CHANGE_32MSI_FN, nvec); if (rc < 0) { /* @@ -409,7 +409,7 @@ again: if (use_32bit_msi_hack && rc > 0) rtas_hack_32bit_msi_gen2(pdev); } else { - if (pdev->no_64bit_msi) + if (pdev->msi_addr_mask < DMA_BIT_MASK(64)) rc = rtas_change_msi(pdn, RTAS_CHANGE_32MSIX_FN, nvec); else rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec); |
