Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 25 Sep 2023 07:42:02 +0000
From:      bugzilla-noreply@freebsd.org
To:        bugs@FreeBSD.org
Subject:   [Bug 274074] native_apic_alloc_vectors() does not properly align vectors when 32 are requested
Message-ID:  <bug-274074-227@https.bugs.freebsd.org/bugzilla/>

next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D274074

            Bug ID: 274074
           Summary: native_apic_alloc_vectors() does not properly align
                    vectors when 32 are requested
           Product: Base System
           Version: Unspecified
          Hardware: amd64
                OS: Any
            Status: New
          Severity: Affects Only Me
          Priority: ---
         Component: kern
          Assignee: bugs@FreeBSD.org
          Reporter: john@sanren.ac.za

Created attachment 245210
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=3D245210&action=
=3Dedit
Fix to align the msi vector properly

MSI interrupt vectors needs to be aligned to the size of the request and ha=
ve
to be in powers of 2.

The code in native_apic_alloc_vectors() does an alignment check in the loop:

    if ((vector & (align - 1)) !=3D 0)
        continue;
    first =3D vector;

But when it adds APIC_IO_INTS to the value it returns:

    return (first + APIC_IO_INTS);

The problem is that APIC_IO_INTS is not a multiple of 32. It is 48:

#define NRSVIDT         32
#define IDT_IO_INTS     NRSVIDT
#define APIC_IO_INTS    (IDT_IO_INTS + 16)

My fix is to include it during the alignment check:

--- /sys/x86/x86/local_apic.c.org       2023-04-07 02:34:45.000000000 +0200
+++ /sys/x86/x86/local_apic.c   2023-09-24 21:10:04.785720000 +0200
@@ -1657,7 +1657,7 @@

                /* Start a new run if run =3D=3D 0 and vector is aligned. */
                if (run =3D=3D 0) {
-                       if ((vector & (align - 1)) !=3D 0)
+                       if (((vector + APIC_IO_INTS) & (align - 1)) !=3D 0)
                                continue;
                        first =3D vector;
                }

The patch is against 13.2, but the code in current looks the same.

Without the patch, pci_alloc_msi() with a count of 32 would return without =
an
error and allocate 32 vectors, but in my case with a base vector of 0x50 and
that was configured on the card. But the card would then ignore the bottom 5
bits and generate interrupt vectors from 0x40 to 0x5f.

--=20
You are receiving this mail because:
You are the assignee for the bug.=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-274074-227>