Commit 65604b05 authored by Vitaly Kuznetsov's avatar Vitaly Kuznetsov Committed by Tim Gardner

Drivers: hv: balloon: don't crash when memory is added in non-sorted order

BugLink: http://bugs.launchpad.net/bugs/1616677

When we iterate through all HA regions in handle_pg_range() we have an
assumption that all these regions are sorted in the list and the
'start_pfn >= has->end_pfn' check is enough to find the proper region.
Unfortunately it's not the case with WS2016 where host can hot-add regions
in a different order. We end up modifying the wrong HA region and crashing
later on pages online. Modify the check to make sure we found the region
we were searching for while iterating. Fix the same check in pfn_covered()
as well.
Signed-off-by: default avatarVitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: default avatarK. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 77c0c973)
Signed-off-by: default avatarTim Gardner <tim.gardner@canonical.com>
Acked-by: default avatarBrad Figg <brad.figg@canonical.com>
Acked-by: default avatarKamal Mostafa <kamal@canonical.com>
parent 39d44ef9
...@@ -714,7 +714,7 @@ static bool pfn_covered(unsigned long start_pfn, unsigned long pfn_cnt) ...@@ -714,7 +714,7 @@ static bool pfn_covered(unsigned long start_pfn, unsigned long pfn_cnt)
* If the pfn range we are dealing with is not in the current * If the pfn range we are dealing with is not in the current
* "hot add block", move on. * "hot add block", move on.
*/ */
if ((start_pfn >= has->end_pfn)) if (start_pfn < has->start_pfn || start_pfn >= has->end_pfn)
continue; continue;
/* /*
* If the current hot add-request extends beyond * If the current hot add-request extends beyond
...@@ -768,7 +768,7 @@ static unsigned long handle_pg_range(unsigned long pg_start, ...@@ -768,7 +768,7 @@ static unsigned long handle_pg_range(unsigned long pg_start,
* If the pfn range we are dealing with is not in the current * If the pfn range we are dealing with is not in the current
* "hot add block", move on. * "hot add block", move on.
*/ */
if ((start_pfn >= has->end_pfn)) if (start_pfn < has->start_pfn || start_pfn >= has->end_pfn)
continue; continue;
old_covered_state = has->covered_end_pfn; old_covered_state = has->covered_end_pfn;
......
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