From: Laurence Oberman <loberman@redhat.com>
To: Michael Kelley <mhklinux@outlook.com>,
"njavali@marvell.com" <njavali@marvell.com>,
"martin.petersen@oracle.com" <martin.petersen@oracle.com>,
"wei.liu@kernel.org" <wei.liu@kernel.org>,
Mukesh R <mrathor@linux.microsoft.com>
Cc: "GR-QLogic-Storage-Upstream@marvell.com"
<GR-QLogic-Storage-Upstream@marvell.com>,
"James.Bottomley@HansenPartnership.com"
<James.Bottomley@HansenPartnership.com>,
"haiyangz@microsoft.com" <haiyangz@microsoft.com>,
"decui@microsoft.com" <decui@microsoft.com>,
"sbhat@linux.ibm.com" <sbhat@linux.ibm.com>,
"kmahlkuc@linux.ibm.com" <kmahlkuc@linux.ibm.com>,
"linux-scsi@vger.kernel.org" <linux-scsi@vger.kernel.org>,
"linux-hyperv@vger.kernel.org" <linux-hyperv@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [RFC PATCH] scsi: qla2xxx: Use the real INTx pin for the port number on Hyper-V guests
Date: Sun, 08 Nov 2026 11:55:47 -0500 [thread overview]
Message-ID: <b6b39c415514de821d8a71cefda41f3d4f53405a.camel@redhat.com> (raw)
In-Reply-To: <080f3cc7097c9a8191e4fa2f03ff2d67d0640f40.camel@redhat.com>
On Sat, 2026-11-07 at 10:14 -0500, Laurence Oberman wrote:
> On Thu, 2026-11-05 at 00:46 +0000, Michael Kelley wrote:
> > From: Laurence Oberman <loberman@redhat.com> Sent: Wednesday,
> > November 4, 2026 2:26 PM
> > >
> > > qla2x00_set_isp_flags() derives the physical port number from
> > > PCI_INTERRUPT_PIN, and the port number selects the per-port VPD,
> > > NVRAM,
> > > NPIV and FCP priority flash regions.
> > >
> > > On Hyper-V guests, pci-hyperv returns 0 for byte and word reads
> > > of
> > > PCI_INTERRUPT_PIN since commit fea93a3e5d5e ("PCI: hv: Return
> > > zero,
> > > not
> > > garbage, when reading PCI_INTERRUPT_PIN"). Commit 7268e509b43a
> > > ("scsi:
> > > qla2xxx: Handle INTx not connected while passing through") then
> > > falls
> > > back to PCI_FUNC(). With Discrete Device Assignment (DDA), each
> > > function
> > > of a multi-port HBA is presented as function 0 in its own PCI
> > > domain, so
> > > every port gets port_no 0. All ports read port 0's NVRAM, pass
> > > the
> > > checksum and register the same WWPN, and nothing is logged.
> > >
> > > Without that commit, port_no underflows to 255, no flash region
> > > is
> > > selected and every port fails with "Inconsistent NVRAM checksum"
> > > and
> > > falls back to the default WWPN.
> > >
> > > pci-hyperv only zeroes byte and word accesses within 0x3c-0x3d. A
> > > dword
> > > read at PCI_INTERRUPT_LINE reaches the device's config space and
> > > returns
> > > the real pin in bits 15:8. On Hyper-V guests, use that when the
> > > byte
> > > read returns 0, and warn if the pin is still 0 so that duplicate
> > > WWPNs
> > > are not silent. Bare metal, KVM/vfio and other hypervisors are
> > > unchanged.
> >
> > There's a patch in flight [1] that kills the behavior that your
> > patch
> > takes
> > advantage of. I don't have knowledge of the full details that
> > motivated [1],
> > so maybe Mukesh Rathor or Wei Liu can add some info, as well as
> > comment on the validity of what you are observing as a possible
> > work-around to the qla2xxx problem.
> >
> > Michael
> >
> > [1]
> > https://lore.kernel.org/linux-hyperv/20260913232255.2801797-1-wei.liu@kernel.org/
> >
> > >
> > > Tested with an equivalent change on a RHEL 9 (5.14-based) guest
> > > with a
> > > dual-port QLE2692 (ISP2261) assigned through DDA (Hyper-V host
> > > 10.0.17763):
> > >
> > > before: both ports "Inconsistent NVRAM checksum=0xffffffc0
> > > id=NGKP",
> > > both WWPN 0x210000e08b1c5586
> > > after: port_no 1 and 0, NVRAM valid, WWPN 0x210034800d7065bd
> > > and
> > > 0x210034800d7065bc, fabric login and FC-NVMe localport
> > > registration on both ports
> > >
> > > Also tested on bare metal (ISP2031): the new path is not taken
> > > and
> > > port
> > > numbers and WWPNs are unchanged.
> > >
> > > Signed-off-by: Laurence Oberman <loberman@redhat.com>
> > > ---
> > > RFC: this relies on pci-hyperv not virtualizing dword reads at
> > > 0x3c,
> > > which is an implementation detail rather than an interface. It is
> > > posted
> > > as the smallest working fix and to start the discussion. Feedback
> > > wanted
> > > on cleaner alternatives:
> > >
> > > - Hyper-V (linux-hyperv): could pci-hyperv expose the real
> > > PCI_INTERRUPT_PIN, or provide the physical function number,
> > > for
> > > DDA
> > > devices? Some drivers use the pin for port identity, not only
> > > for
> > > interrupt routing.
> > >
> > > - Marvell: is there a firmware or register source for the
> > > physical
> > > port that does not depend on PCI config space? CSRX_FUNCTION
> > > in
> > > ctrl_status is a single bit and would not cover quad-port
> > > 27xx/28xx/29xx.
> > >
> > > - The check is x86-only (hypervisor_is_type()). pci-hyperv also
> > > supports arm64 guests; a better way to detect a pci-hyperv bus
> > > is
> > > welcome.
> > >
> > > This has not yet been tested on a 7.3 kernel in the DDA guest;
> > > testing
> > > was on a RHEL 9.8 backport. The upstream behaviour without this
> > > patch
> > > (duplicate WWPNs with no warning) follows from the code and has
> > > not
> > > yet
> > > been reproduced on 7.3.
> > >
> > > drivers/scsi/qla2xxx/qla_os.c | 40
> > > ++++++++++++++++++++++++++++++++++-
> > > 1 file changed, 39 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/scsi/qla2xxx/qla_os.c
> > > b/drivers/scsi/qla2xxx/qla_os.c
> > > index 3c412c7fb6fe..4180d3f15231 100644
> > > --- a/drivers/scsi/qla2xxx/qla_os.c
> > > +++ b/drivers/scsi/qla2xxx/qla_os.c
> > > @@ -24,6 +24,10 @@
> > > #include <scsi/scsi_transport.h>
> > > #include <scsi/scsi_transport_fc.h>
> > >
> > > +#ifdef CONFIG_X86
> > > +#include <asm/hypervisor.h>
> > > +#endif
> > > +
> > > #include "qla_target.h"
> > >
> > > /*
> > > @@ -2704,6 +2708,40 @@ static struct isp_operations
> > > qla29xx_isp_ops
> > > = {
> > > .initialize_adapter = qla2x00_initialize_adapter,
> > > };
> > >
> > > +/*
> > > + * Read the INTx pin used to derive the physical port number.
> > > + *
> > > + * pci-hyperv hard-wires byte and word reads of
> > > PCI_INTERRUPT_PIN
> > > to zero.
> > > + * With Hyper-V Discrete Device Assignment every function is
> > > also
> > > presented
> > > + * as function 0 in its own PCI domain, so the PCI_FUNC()
> > > fallback
> > > gives
> > > + * port 0 for every port and they all report port 0's WWPN. A
> > > dword read at
> > > + * PCI_INTERRUPT_LINE is not virtualized by pci-hyperv and
> > > returns
> > > the
> > > + * device's pin in bits 15:8, so use that on Hyper-V guests.
> > > + */
> > > +static u8
> > > +qla2x00_get_intx_pin(struct qla_hw_data *ha)
> > > +{
> > > + u8 pin;
> > > +
> > > + pci_read_config_byte(ha->pdev, PCI_INTERRUPT_PIN, &pin);
> > > +#ifdef CONFIG_X86
> > > + if (!pin && hypervisor_is_type(X86_HYPER_MS_HYPERV)) {
> > > + u32 val = 0;
> > > +
> > > + pci_read_config_dword(ha->pdev,
> > > PCI_INTERRUPT_LINE, &val);
> > > + pin = (val >> 8) & 0xff;
> > > + if (pin)
> > > + ql_log_pci(ql_log_info, ha->pdev,
> > > 0xffff,
> > > + "Hyper-V: INTx pin reads 0,
> > > config dword 0x%08x
> > > gives pin %u.\n",
> > > + val, pin);
> > > + else
> > > + ql_log_pci(ql_log_warn, ha->pdev,
> > > 0xffff,
> > > + "Hyper-V: unable to determine
> > > physical port, ports
> > > may report duplicate WWPNs.\n");
> > > + }
> > > +#endif
> > > + return pin;
> > > +}
> > > +
> > > static inline void
> > > qla2x00_set_isp_flags(struct qla_hw_data *ha)
> > > {
> > > @@ -2887,7 +2925,7 @@ qla2x00_set_isp_flags(struct qla_hw_data
> > > *ha)
> > > ha->port_no = ha->portnum & 1;
> > > else {
> > > /* Get adapter physical port no from interrupt
> > > pin
> > > register. */
> > > - pci_read_config_byte(ha->pdev,
> > > PCI_INTERRUPT_PIN,
> > > &ha->port_no);
> > > + ha->port_no = qla2x00_get_intx_pin(ha);
> > > if (ha->port_no == 0) {
> > > /* None of INT[A|B|C|D] may be
> > > virtualized
> > > by vfio */
> > > ha->port_no = PCI_FUNC(ha->pdev->devfn);
> > > --
> > > 2.56.0
> > >
> Hello Michael,
>
> Thanks very much for the information. I will follow the thread.
> Our main pressing issue is any guest on HYPER-V with DDA moving to
> RHEL9 from RHEL8 loses functionality for the pass-through qla2xxx
> ports
>
> Regards
> Laurence
Hi Michael,
Thanks, that settles it. With "PCI: hv: hardwire PCI_INTERRUPT_PIN to
0"
any read covering 0x3d returns 0, so qla2xxx cannot use the pin under
DDA at all. Please consider this RFC withdrawn.
The qla2xxx problem itself remains. The driver uses the pin, not for
interrupts, but as its only indication of which physical port a
function
is on. That selects the per-port VPD, NVRAM, NPIV and FCP priority
flash
regions. Under DDA each function is presented as function 0 in its own
domain, so PCI_FUNC() cannot tell the ports apart either, and every
port
of a dual-port QLE2692 comes up with port 0's WWPN.
Wei, Mukesh: if there is a supported way for a guest to learn the
physical function of a DDA-assigned device, qla2xxx could use it.
Otherwise I think this has to be solved in the driver.
Nilesh: on the same guest, the -1015 mailbox dump logged by the Marvell
out-of-tree driver at init differs between the two ports only in
mb[15]:
pin A port: mb[8-15] 0003h 0001h 0001h 0001h f080h 0000h 0008h 0000h
pin B port: mb[8-15] 0003h 0001h 0001h 0001h f080h 0000h 0008h 4001h
Is that firmware reporting the physical function? If so, and if it is
available on ISP25xx/27xx/28xx/29xx before the flash regions are
selected, it would give qla2xxx a port number that does not depend on
PCI config space, under any hypervisor. I am happy to test a patch on
the customer's DDA guest.
Thanks,
Laurence
prev parent reply other threads:[~2026-11-08 16:55 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-04 22:25 Laurence Oberman
2026-11-05 0:46 ` Michael Kelley
2026-11-07 15:14 ` Laurence Oberman
2026-11-08 16:55 ` Laurence Oberman [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=b6b39c415514de821d8a71cefda41f3d4f53405a.camel@redhat.com \
--to=loberman@redhat.com \
--cc=GR-QLogic-Storage-Upstream@marvell.com \
--cc=James.Bottomley@HansenPartnership.com \
--cc=decui@microsoft.com \
--cc=haiyangz@microsoft.com \
--cc=kmahlkuc@linux.ibm.com \
--cc=linux-hyperv@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=mhklinux@outlook.com \
--cc=mrathor@linux.microsoft.com \
--cc=njavali@marvell.com \
--cc=sbhat@linux.ibm.com \
--cc=wei.liu@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®