Browse Source

[acpi] Compute and check checksum for ACPI tables

Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Laurent Gourvénec 6 years ago
parent
commit
041d362423
1 changed files with 37 additions and 6 deletions
  1. 37
    6
      src/core/acpi.c

+ 37
- 6
src/core/acpi.c View File

@@ -42,19 +42,41 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
42 42
  ******************************************************************************
43 43
  */
44 44
 
45
+/**
46
+ * Compute ACPI table checksum
47
+ *
48
+ * @v table		Any ACPI table
49
+ * @ret checksum	0 if checksum is good
50
+ */
51
+static uint8_t acpi_checksum ( userptr_t table ) {
52
+	struct acpi_header acpi;
53
+	uint8_t sum = 0;
54
+	uint8_t data;
55
+	unsigned int i;
56
+
57
+	/* Read table length */
58
+	copy_from_user ( &acpi.length, table,
59
+			 offsetof ( typeof ( acpi ), length ),
60
+			 sizeof ( acpi.length ) );
61
+
62
+	/* Compute checksum */
63
+	for ( i = 0 ; i < le32_to_cpu ( acpi.length ) ; i++ ) {
64
+		copy_from_user ( &data, table, i, sizeof ( data ) );
65
+		sum += data;
66
+	}
67
+
68
+	return sum;
69
+}
70
+
45 71
 /**
46 72
  * Fix up ACPI table checksum
47 73
  *
48 74
  * @v acpi		ACPI table header
49 75
  */
50 76
 void acpi_fix_checksum ( struct acpi_header *acpi ) {
51
-	unsigned int i = 0;
52
-	uint8_t sum = 0;
53 77
 
54
-	for ( i = 0 ; i < acpi->length ; i++ ) {
55
-		sum += *( ( ( uint8_t * ) acpi ) + i );
56
-	}
57
-	acpi->checksum -= sum;
78
+	/* Update checksum */
79
+	acpi->checksum -= acpi_checksum ( virt_to_user ( acpi ) );
58 80
 }
59 81
 
60 82
 /**
@@ -123,6 +145,15 @@ userptr_t acpi_find ( uint32_t signature, unsigned int index ) {
123 145
 		if ( index-- )
124 146
 			continue;
125 147
 
148
+		/* Check table integrity */
149
+		if ( acpi_checksum ( table ) != 0 ) {
150
+			DBGC ( rsdt, "RSDT %#08lx found %s with bad checksum "
151
+			       "at %08lx\n", user_to_phys ( rsdt, 0 ),
152
+			       acpi_name ( signature ),
153
+			       user_to_phys ( table, 0 ) );
154
+			break;
155
+		}
156
+
126 157
 		DBGC ( rsdt, "RSDT %#08lx found %s at %08lx\n",
127 158
 		       user_to_phys ( rsdt, 0 ), acpi_name ( signature ),
128 159
 		       user_to_phys ( table, 0 ) );

Loading…
Cancel
Save