Commit c420dbd1 authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Rafael J. Wysocki

ACPI: Implement proper length checks for mem resources

Check whether the resulting length is the same as the given
length. Check for start <= end as well.

We need to hand in the resource for this, so we can apply the flags
directly.

[Jiang] Remove enforcement that resource starting address must be
non-zero.
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarJiang Liu <jiang.liu@linux.intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent c793504d
...@@ -34,21 +34,37 @@ ...@@ -34,21 +34,37 @@
#define valid_IRQ(i) (true) #define valid_IRQ(i) (true)
#endif #endif
static unsigned long acpi_dev_memresource_flags(u64 len, u8 write_protect, static bool acpi_dev_resource_len_valid(u64 start, u64 end, u64 len, bool io)
bool window)
{ {
unsigned long flags = IORESOURCE_MEM; u64 reslen = end - start + 1;
if (len == 0) /*
flags |= IORESOURCE_DISABLED; * CHECKME: len might be required to check versus a minimum
* length as well. 1 for io is fine, but for memory it does
* not make any sense at all.
*/
if (len && reslen && reslen == len && start <= end)
return true;
pr_info("ACPI: invalid or unassigned resource %s [%016llx - %016llx] length [%016llx]\n",
io ? "io" : "mem", start, end, len);
return false;
}
static void acpi_dev_memresource_flags(struct resource *res, u64 len,
u8 write_protect, bool window)
{
res->flags = IORESOURCE_MEM;
if (!acpi_dev_resource_len_valid(res->start, res->end, len, false))
res->flags |= IORESOURCE_DISABLED;
if (write_protect == ACPI_READ_WRITE_MEMORY) if (write_protect == ACPI_READ_WRITE_MEMORY)
flags |= IORESOURCE_MEM_WRITEABLE; res->flags |= IORESOURCE_MEM_WRITEABLE;
if (window) if (window)
flags |= IORESOURCE_WINDOW; res->flags |= IORESOURCE_WINDOW;
return flags;
} }
static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len, static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len,
...@@ -56,7 +72,7 @@ static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len, ...@@ -56,7 +72,7 @@ static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len,
{ {
res->start = start; res->start = start;
res->end = start + len - 1; res->end = start + len - 1;
res->flags = acpi_dev_memresource_flags(len, write_protect, false); acpi_dev_memresource_flags(res, len, write_protect, false);
} }
/** /**
...@@ -77,24 +93,18 @@ bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res) ...@@ -77,24 +93,18 @@ bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res)
switch (ares->type) { switch (ares->type) {
case ACPI_RESOURCE_TYPE_MEMORY24: case ACPI_RESOURCE_TYPE_MEMORY24:
memory24 = &ares->data.memory24; memory24 = &ares->data.memory24;
if (!memory24->minimum && !memory24->address_length)
return false;
acpi_dev_get_memresource(res, memory24->minimum, acpi_dev_get_memresource(res, memory24->minimum,
memory24->address_length, memory24->address_length,
memory24->write_protect); memory24->write_protect);
break; break;
case ACPI_RESOURCE_TYPE_MEMORY32: case ACPI_RESOURCE_TYPE_MEMORY32:
memory32 = &ares->data.memory32; memory32 = &ares->data.memory32;
if (!memory32->minimum && !memory32->address_length)
return false;
acpi_dev_get_memresource(res, memory32->minimum, acpi_dev_get_memresource(res, memory32->minimum,
memory32->address_length, memory32->address_length,
memory32->write_protect); memory32->write_protect);
break; break;
case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
fixed_memory32 = &ares->data.fixed_memory32; fixed_memory32 = &ares->data.fixed_memory32;
if (!fixed_memory32->address && !fixed_memory32->address_length)
return false;
acpi_dev_get_memresource(res, fixed_memory32->address, acpi_dev_get_memresource(res, fixed_memory32->address,
fixed_memory32->address_length, fixed_memory32->address_length,
fixed_memory32->write_protect); fixed_memory32->write_protect);
...@@ -102,7 +112,8 @@ bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res) ...@@ -102,7 +112,8 @@ bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res)
default: default:
return false; return false;
} }
return true;
return !(res->flags & IORESOURCE_DISABLED);
} }
EXPORT_SYMBOL_GPL(acpi_dev_resource_memory); EXPORT_SYMBOL_GPL(acpi_dev_resource_memory);
...@@ -186,7 +197,6 @@ bool acpi_dev_resource_address_space(struct acpi_resource *ares, ...@@ -186,7 +197,6 @@ bool acpi_dev_resource_address_space(struct acpi_resource *ares,
acpi_status status; acpi_status status;
struct acpi_resource_address64 addr; struct acpi_resource_address64 addr;
bool window; bool window;
u64 len;
u8 io_decode; u8 io_decode;
status = acpi_resource_to_address64(ares, &addr); status = acpi_resource_to_address64(ares, &addr);
...@@ -199,10 +209,9 @@ bool acpi_dev_resource_address_space(struct acpi_resource *ares, ...@@ -199,10 +209,9 @@ bool acpi_dev_resource_address_space(struct acpi_resource *ares,
switch(addr.resource_type) { switch(addr.resource_type) {
case ACPI_MEMORY_RANGE: case ACPI_MEMORY_RANGE:
len = addr.address.maximum - addr.address.minimum + 1; acpi_dev_memresource_flags(res, addr.address.address_length,
res->flags = acpi_dev_memresource_flags(len, addr.info.mem.write_protect,
addr.info.mem.write_protect, window);
window);
break; break;
case ACPI_IO_RANGE: case ACPI_IO_RANGE:
io_decode = addr.address.granularity == 0xfff ? io_decode = addr.address.granularity == 0xfff ?
...@@ -236,7 +245,6 @@ bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares, ...@@ -236,7 +245,6 @@ bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares,
{ {
struct acpi_resource_extended_address64 *ext_addr; struct acpi_resource_extended_address64 *ext_addr;
bool window; bool window;
u64 len;
u8 io_decode; u8 io_decode;
if (ares->type != ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64) if (ares->type != ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64)
...@@ -250,10 +258,10 @@ bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares, ...@@ -250,10 +258,10 @@ bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares,
switch(ext_addr->resource_type) { switch(ext_addr->resource_type) {
case ACPI_MEMORY_RANGE: case ACPI_MEMORY_RANGE:
len = ext_addr->address.maximum - ext_addr->address.minimum + 1; acpi_dev_memresource_flags(res,
res->flags = acpi_dev_memresource_flags(len, ext_addr->address.address_length,
ext_addr->info.mem.write_protect, ext_addr->info.mem.write_protect,
window); window);
break; break;
case ACPI_IO_RANGE: case ACPI_IO_RANGE:
io_decode = ext_addr->address.granularity == 0xfff ? io_decode = ext_addr->address.granularity == 0xfff ?
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment