When very large regions (32GB sized in our case, PCI pass-through of GPUs)
are compared substraction result does not fit into gint.

As a result crs_replace_with_free_ranges does not get sorted ranges and
incorrectly computes PCI64 free space regions. Which then makes linux
guest complain about device and PCI64 hole intersection and device
becomes unusable.

Fix that by returning exactly fitting ranges.

Signed-off-by: Evgeny Yakovlev <wr...@yandex-team.ru>
---
 hw/i386/acpi-build.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index d281ffa..5cf88a6 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -758,7 +758,13 @@ static gint crs_range_compare(gconstpointer a, 
gconstpointer b)
      CrsRangeEntry *entry_a = *(CrsRangeEntry **)a;
      CrsRangeEntry *entry_b = *(CrsRangeEntry **)b;
 
-     return (int64_t)entry_a->base - (int64_t)entry_b->base;
+     if (entry_a->base < entry_b->base) {
+         return -1;
+     } else if (entry_a->base > entry_b->base) {
+         return 1;
+     } else {
+         return 0;
+     }
 }
 
 /*
-- 
2.7.4


Reply via email to