ACPI / LPIT: Correct LPIT end address for lpit_process()

Correct the LPIT end address which is passed into lpit_process()
and the end address limit test in lpit_process().

The LPI state descriptor subtables follow the fixed sized
acpi_lpit_header up to the end of the LPIT. The last LPI state
descriptor can end at exactly the end of the LPIT.

Note that this is a fix to a latent problem. Although incorrect,
the unpatched version works because the passed in end address
is just slightly beyond the actual end of the LPIT and the size
of the ACPI LPIT header is smaller than the size of the only
currently defined LPI state descriptor, acpi_lpit_native.

Signed-off-by: Lenny Szubowicz <lszubowi@redhat.com>
Reviewed-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
Lenny Szubowicz 2019-05-02 16:00:52 -04:00 committed by Rafael J. Wysocki
parent cd6c84d8f0
commit 32865e3e01
1 changed files with 3 additions and 4 deletions

View File

@ -137,7 +137,7 @@ static void lpit_update_residency(struct lpit_residency_info *info,
static void lpit_process(u64 begin, u64 end) static void lpit_process(u64 begin, u64 end)
{ {
while (begin + sizeof(struct acpi_lpit_native) < end) { while (begin + sizeof(struct acpi_lpit_native) <= end) {
struct acpi_lpit_native *lpit_native = (struct acpi_lpit_native *)begin; struct acpi_lpit_native *lpit_native = (struct acpi_lpit_native *)begin;
if (!lpit_native->header.type && !lpit_native->header.flags) { if (!lpit_native->header.type && !lpit_native->header.flags) {
@ -156,7 +156,6 @@ static void lpit_process(u64 begin, u64 end)
void acpi_init_lpit(void) void acpi_init_lpit(void)
{ {
acpi_status status; acpi_status status;
u64 lpit_begin;
struct acpi_table_lpit *lpit; struct acpi_table_lpit *lpit;
status = acpi_get_table(ACPI_SIG_LPIT, 0, (struct acpi_table_header **)&lpit); status = acpi_get_table(ACPI_SIG_LPIT, 0, (struct acpi_table_header **)&lpit);
@ -164,6 +163,6 @@ void acpi_init_lpit(void)
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
return; return;
lpit_begin = (u64)lpit + sizeof(*lpit); lpit_process((u64)lpit + sizeof(*lpit),
lpit_process(lpit_begin, lpit_begin + lpit->header.length); (u64)lpit + lpit->header.length);
} }