The branch main has been updated by khng:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=6fe60f1d5c39c94fc87534e9dd4e9630594e0bec

commit 6fe60f1d5c39c94fc87534e9dd4e9630594e0bec
Author:     Ka Ho Ng <k...@freebsd.org>
AuthorDate: 2021-04-19 08:07:03 +0000
Commit:     Ka Ho Ng <k...@freebsd.org>
CommitDate: 2021-04-19 08:08:13 +0000

    AMD-vi: Fortify IVHD device_identify process
    
    - Use malloc(9) to allocate ivhd_hdrs list. The previous assumption
      that there are at most 10 IVHDs in a system is not true. A counter
      example would be a system with 4 IOMMUs, and each IOMMU is related
      to IVHDs type 10h, 11h and 40h in the ACPI IVRS table.
    - Always scan through the whole ivhd_hdrs list to find IVHDs that has
      the same DeviceId but less prioritized IVHD type.
    
    Sponsored by:   The FreeBSD Foundation
    MFC with:       74ada297e897
    Reviewed by:    grehan
    Approved by:    lwhsu (mentor)
    Differential Revision:  https://reviews.freebsd.org/D29525
---
 sys/amd64/vmm/amd/ivrs_drv.c | 47 ++++++++++++++++++++++++--------------------
 1 file changed, 26 insertions(+), 21 deletions(-)

diff --git a/sys/amd64/vmm/amd/ivrs_drv.c b/sys/amd64/vmm/amd/ivrs_drv.c
index 1cd76069d0a2..67b205076cb2 100644
--- a/sys/amd64/vmm/amd/ivrs_drv.c
+++ b/sys/amd64/vmm/amd/ivrs_drv.c
@@ -57,7 +57,7 @@ int   ivhd_count;                     /* Number of IVHD 
header. */
  * Cached IVHD header list.
  * Single entry for each IVHD, filtered the legacy one.
  */
-ACPI_IVRS_HARDWARE1 *ivhd_hdrs[10];    
+ACPI_IVRS_HARDWARE1 **ivhd_hdrs;
 
 extern int amdvi_ptp_level;            /* Page table levels. */
 
@@ -134,9 +134,11 @@ ivrs_is_ivhd(UINT8 type)
 static int
 ivhd_count_iter(ACPI_IVRS_HEADER * ivrs_he, void *arg)
 {
+       int *count;
 
+       count = (int *)arg;
        if (ivrs_is_ivhd(ivrs_he->Type))
-               ivhd_count++;
+               (*count)++;
 
        return (1);
 }
@@ -339,7 +341,7 @@ ivhd_identify(driver_t *driver, device_t parent)
        ACPI_TABLE_IVRS *ivrs;
        ACPI_IVRS_HARDWARE1 *ivhd;
        ACPI_STATUS status;
-       int i, count = 0;
+       int i, j, count = 0;
        uint32_t ivrs_ivinfo;
 
        if (acpi_disabled("ivhd"))
@@ -360,32 +362,35 @@ ivhd_identify(driver_t *driver, device_t parent)
                REG_BITS(ivrs_ivinfo, 7, 5), REG_BITS(ivrs_ivinfo, 22, 22),
                "\020\001EFRSup");
 
-       ivrs_hdr_iterate_tbl(ivhd_count_iter, NULL);
-       if (!ivhd_count)
+       ivrs_hdr_iterate_tbl(ivhd_count_iter, &count);
+       if (!count)
                return;
 
-       for (i = 0; i < ivhd_count; i++) {
+       ivhd_hdrs = malloc(sizeof(void *) * count, M_DEVBUF,
+               M_WAITOK | M_ZERO);
+       for (i = 0; i < count; i++) {
                ivhd = ivhd_find_by_index(i);
                KASSERT(ivhd, ("ivhd%d is NULL\n", i));
-               ivhd_hdrs[i] = ivhd;
-       }
 
-        /* 
-        * Scan for presence of legacy and non-legacy device type
-        * for same AMD-Vi device and override the old one.
-        */
-       for (i = ivhd_count - 1 ; i > 0 ; i--){
-                       if (ivhd_is_newer(&ivhd_hdrs[i-1]->Header, 
-                       &ivhd_hdrs[i]->Header)) {
-                       memmove(&ivhd_hdrs[i-1], &ivhd_hdrs[i],
-                           sizeof(void *) * (ivhd_count - i));
-                       ivhd_count--;
+               /*
+                * Scan for presence of legacy and non-legacy device type
+                * for same IOMMU device and override the old one.
+                *
+                * If there is no existing IVHD to the same IOMMU device,
+                * the IVHD header pointer is appended.
+                */
+               for (j = 0; j < ivhd_count; j++) {
+                       if (ivhd_is_newer(&ivhd_hdrs[j]->Header, &ivhd->Header))
+                               break;
                }
+               ivhd_hdrs[j] = ivhd;
+               if (j == ivhd_count)
+                       ivhd_count++;
        }
 
        ivhd_devs = malloc(sizeof(device_t) * ivhd_count, M_DEVBUF,
                M_WAITOK | M_ZERO);
-       for (i = 0; i < ivhd_count; i++) {
+       for (i = 0, j = 0; i < ivhd_count; i++) {
                ivhd = ivhd_hdrs[i];
                KASSERT(ivhd, ("ivhd%d is NULL\n", i));
 
@@ -407,13 +412,13 @@ ivhd_identify(driver_t *driver, device_t parent)
                                break;
                        }
                }
-               count++;
+               j++;
        }
 
        /*
         * Update device count in case failed to attach.
         */
-       ivhd_count = count;
+       ivhd_count = j;
 }
 
 static int
_______________________________________________
dev-commits-src-main@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
To unsubscribe, send any mail to "dev-commits-src-main-unsubscr...@freebsd.org"

Reply via email to