From 920de6ebfab865a5bb2bcc60f6998aa270300b95 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Thu, 24 Mar 2016 09:41:09 +0800 Subject: [PATCH] ACPICA: Hardware: Enhance acpi_hw_validate_register() with access_width/bit_offset awareness ACPICA commit 997a90f810a4cb78604ef2e187611a181b498286 This patch enhances acpi_hw_validate_register() to sanitize register accesses with awareness of access_width and bit_offset. Lv Zheng. Link: https://github.com/acpica/acpica/commit/997a90f8 Link: https://bugs.acpica.org/show_bug.cgi?id=1240 Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/hwregs.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index 5ba0498412fd..035fb52c3bcd 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c @@ -83,6 +83,8 @@ acpi_status acpi_hw_validate_register(struct acpi_generic_address *reg, u8 max_bit_width, u64 *address) { + u8 bit_width; + u8 access_width; /* Must have a valid pointer to a GAS structure */ @@ -109,23 +111,26 @@ acpi_hw_validate_register(struct acpi_generic_address *reg, return (AE_SUPPORT); } - /* Validate the bit_width */ + /* Validate the access_width */ - if ((reg->bit_width != 8) && - (reg->bit_width != 16) && - (reg->bit_width != 32) && (reg->bit_width != max_bit_width)) { + if (reg->access_width > 4) { ACPI_ERROR((AE_INFO, - "Unsupported register bit width: 0x%X", - reg->bit_width)); + "Unsupported register access width: 0x%X", + reg->access_width)); return (AE_SUPPORT); } - /* Validate the bit_offset. Just a warning for now. */ + /* Validate the bit_width, convert access_width into number of bits */ - if (reg->bit_offset != 0) { + access_width = reg->access_width ? reg->access_width : 1; + access_width = 1 << (access_width + 2); + bit_width = + ACPI_ROUND_UP(reg->bit_offset + reg->bit_width, access_width); + if (max_bit_width < bit_width) { ACPI_WARNING((AE_INFO, - "Unsupported register bit offset: 0x%X", - reg->bit_offset)); + "Requested bit width 0x%X is smaller than register bit width 0x%X", + max_bit_width, bit_width)); + return (AE_SUPPORT); } return (AE_OK);