NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/55926: aarch64: pci_intr_alloc() return msi/msi-x count, but struct msi is not initialized.
>Number: 55926
>Category: kern
>Synopsis: aarch64: pci_intr_alloc() return msi/msi-x count, but struct msi is not initialized.
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Jan 14 04:30:00 +0000 2021
>Originator: Kouichi Hashikawa
>Release: NetBSD-9.99.77
>Organization:
>Environment:
>Description:
Like RPi4, on system that gic_v2m_init() is not called
(struct msi is not initialized),
pci_intr_alloc() returns msi/msi-x count (---> Patch 1).
I have a question, if a system has msi/msi-x capability,
and pci_intr_alloc() returns only intx count,
then turn off PCI_MSI_CTL_MSI_ENABLE or PCI_MSIX_CTL_ENABLE flag on
pci_msi_machdep.c? or each driver?
>How-To-Repeat:
>Fix:
(Patch 1)
--------
--- src/sys/arch/arm/pci/pci_msi_machdep.c-dist 2020-02-13 15:28:25.000000000 +0900
+++ src/sys/arch/arm/pci/pci_msi_machdep.c 2021-01-14 13:07:53.053314571 +0900
@@ -142,7 +142,7 @@
struct arm_pci_msi *msi;
msi = arm_pci_msi_find_frame(pih);
- if (msi == NULL)
+ if (msi == NULL || msi->msi_intr_establish == NULL)
return NULL;
return msi->msi_intr_establish(msi, pih, ipl, func, arg, xname);
@@ -204,6 +204,7 @@
pci_intr_alloc(const struct pci_attach_args *pa, pci_intr_handle_t **ihps, int *counts, pci_intr_type_t max_type)
{
int intx_count, msi_count, msix_count, error;
+ struct arm_pci_msi *msi;
error = EINVAL;
@@ -230,20 +231,32 @@
intx_count = msi_count = msix_count = 1;
}
- if (msix_count == -1)
- msix_count = pci_msix_count(pa->pa_pc, pa->pa_tag);
- if (msix_count > 0 && (error = pci_msix_alloc_exact(pa, ihps, msix_count)) == 0) {
- if (counts != NULL)
- counts[PCI_INTR_TYPE_MSIX] = msix_count;
- return 0;
- }
+ msi = arm_pci_msi_lookup(pa);
- if (msi_count == -1)
- msi_count = pci_msi_count(pa->pa_pc, pa->pa_tag);
- if (msi_count > 0 && (error = pci_msi_alloc_exact(pa, ihps, msi_count)) == 0) {
- if (counts != NULL)
- counts[PCI_INTR_TYPE_MSI] = msi_count;
- return 0;
+ if (msi != NULL) {
+ if (msi->msix_alloc != NULL) {
+ if (msix_count == -1)
+ msix_count = pci_msix_count(pa->pa_pc,
+ pa->pa_tag);
+ if (msix_count > 0 && (error = pci_msix_alloc_exact(pa,
+ ihps, msix_count)) == 0) {
+ if (counts != NULL)
+ counts[PCI_INTR_TYPE_MSIX] = msix_count;
+ return 0;
+ }
+ }
+
+ if (msi->msi_alloc != NULL) {
+ if (msi_count == -1)
+ msi_count = pci_msi_count(pa->pa_pc,
+ pa->pa_tag);
+ if (msi_count > 0 && (error = pci_msi_alloc_exact(pa,
+ ihps, msi_count)) == 0) {
+ if (counts != NULL)
+ counts[PCI_INTR_TYPE_MSI] = msi_count;
+ return 0;
+ }
+ }
}
if (intx_count > 0 && (error = pci_intx_alloc(pa, ihps)) == 0) {
@@ -266,6 +279,8 @@
if ((pih[0] & (ARM_PCI_INTR_MSIX|ARM_PCI_INTR_MSI)) != 0) {
msi = arm_pci_msi_find_frame(pih[0]);
KASSERT(msi != NULL);
+ if (msi->msi_intr_release == NULL)
+ return;
msi->msi_intr_release(msi, pih, count);
}
Home |
Main Index |
Thread Index |
Old Index