mirror of https://github.com/ipxe/ipxe.git
[acpi] Compute and check checksum for ACPI tables
Modified-by: Michael Brown <mcb30@ipxe.org> Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/66/head
parent
8866c919f8
commit
041d362423
|
@ -42,19 +42,41 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
******************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
* Compute ACPI table checksum
|
||||
*
|
||||
* @v table Any ACPI table
|
||||
* @ret checksum 0 if checksum is good
|
||||
*/
|
||||
static uint8_t acpi_checksum ( userptr_t table ) {
|
||||
struct acpi_header acpi;
|
||||
uint8_t sum = 0;
|
||||
uint8_t data;
|
||||
unsigned int i;
|
||||
|
||||
/* Read table length */
|
||||
copy_from_user ( &acpi.length, table,
|
||||
offsetof ( typeof ( acpi ), length ),
|
||||
sizeof ( acpi.length ) );
|
||||
|
||||
/* Compute checksum */
|
||||
for ( i = 0 ; i < le32_to_cpu ( acpi.length ) ; i++ ) {
|
||||
copy_from_user ( &data, table, i, sizeof ( data ) );
|
||||
sum += data;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix up ACPI table checksum
|
||||
*
|
||||
* @v acpi ACPI table header
|
||||
*/
|
||||
void acpi_fix_checksum ( struct acpi_header *acpi ) {
|
||||
unsigned int i = 0;
|
||||
uint8_t sum = 0;
|
||||
|
||||
for ( i = 0 ; i < acpi->length ; i++ ) {
|
||||
sum += *( ( ( uint8_t * ) acpi ) + i );
|
||||
}
|
||||
acpi->checksum -= sum;
|
||||
/* Update checksum */
|
||||
acpi->checksum -= acpi_checksum ( virt_to_user ( acpi ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -123,6 +145,15 @@ userptr_t acpi_find ( uint32_t signature, unsigned int index ) {
|
|||
if ( index-- )
|
||||
continue;
|
||||
|
||||
/* Check table integrity */
|
||||
if ( acpi_checksum ( table ) != 0 ) {
|
||||
DBGC ( rsdt, "RSDT %#08lx found %s with bad checksum "
|
||||
"at %08lx\n", user_to_phys ( rsdt, 0 ),
|
||||
acpi_name ( signature ),
|
||||
user_to_phys ( table, 0 ) );
|
||||
break;
|
||||
}
|
||||
|
||||
DBGC ( rsdt, "RSDT %#08lx found %s at %08lx\n",
|
||||
user_to_phys ( rsdt, 0 ), acpi_name ( signature ),
|
||||
user_to_phys ( table, 0 ) );
|
||||
|
|
Loading…
Reference in New Issue