Преглед изворни кода

[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 година
родитељ
комит
041d362423
1 измењених фајлова са 37 додато и 6 уклоњено
  1. 37
    6
      src/core/acpi.c

+ 37
- 6
src/core/acpi.c Прегледај датотеку

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
  * Fix up ACPI table checksum
72
  * Fix up ACPI table checksum
47
  *
73
  *
48
  * @v acpi		ACPI table header
74
  * @v acpi		ACPI table header
49
  */
75
  */
50
 void acpi_fix_checksum ( struct acpi_header *acpi ) {
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
 		if ( index-- )
145
 		if ( index-- )
124
 			continue;
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
 		DBGC ( rsdt, "RSDT %#08lx found %s at %08lx\n",
157
 		DBGC ( rsdt, "RSDT %#08lx found %s at %08lx\n",
127
 		       user_to_phys ( rsdt, 0 ), acpi_name ( signature ),
158
 		       user_to_phys ( rsdt, 0 ), acpi_name ( signature ),
128
 		       user_to_phys ( table, 0 ) );
159
 		       user_to_phys ( table, 0 ) );

Loading…
Откажи
Сачувај