git: f8b5f7426f0f - stable/12 - AMD-vi: Fortify IVHD device_identify process

Ka Ho Ng khng at FreeBSD.org
Fri Sep 3 19:06:03 UTC 2021


The branch stable/12 has been updated by khng:

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

commit f8b5f7426f0fbb3e9dfa08d6c9d3f14380245681
Author:     Ka Ho Ng <khng at FreeBSD.org>
AuthorDate: 2021-04-19 08:07:03 +0000
Commit:     Ka Ho Ng <khng at FreeBSD.org>
CommitDate: 2021-09-03 18:46:40 +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
    
    (cherry picked from commit 6fe60f1d5c39c94fc87534e9dd4e9630594e0bec)
---
 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 f1ba3e92277b..16f5e05e23e3 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. */
 
@@ -135,9 +135,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);
 }
@@ -340,7 +342,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"))
@@ -361,32 +363,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));
 
@@ -408,13 +413,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


More information about the dev-commits-src-all mailing list