55 lines
1.8 KiB
Diff
55 lines
1.8 KiB
Diff
|
|
From 21e2acd583126db94f6d881005cd58e835160582 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Evgeny Yakovlev <wrfsh@yandex-team.ru>
|
||
|
|
Date: Thu, 18 Jul 2019 19:14:23 +0300
|
||
|
|
Subject: [PATCH] i386/acpi: fix gint overflow in crs_range_compare
|
||
|
|
|
||
|
|
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.
|
||
|
|
|
||
|
|
Also fix indentation of an entire crs_replace_with_free_ranges to make
|
||
|
|
checkpatch happy.
|
||
|
|
|
||
|
|
Cc: qemu-stable@nongnu.org
|
||
|
|
Signed-off-by: Evgeny Yakovlev <wrfsh@yandex-team.ru>
|
||
|
|
Message-Id: <1563466463-26012-1-git-send-email-wrfsh@yandex-team.ru>
|
||
|
|
Signed-off-by: Evgeny Yakovlev <wrfsh@yandex-team.ru>
|
||
|
|
(cherry-picked from commit 21e2acd583126db94f6d881005cd58e835160582)
|
||
|
|
---
|
||
|
|
hw/i386/acpi-build.c | 12 +++++++++---
|
||
|
|
1 file changed, 9 insertions(+), 3 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
|
||
|
|
index d281ffa89e..e7b756b51b 100644
|
||
|
|
--- a/hw/i386/acpi-build.c
|
||
|
|
+++ b/hw/i386/acpi-build.c
|
||
|
|
@@ -755,10 +755,16 @@ static void crs_range_set_free(CrsRangeSet *range_set)
|
||
|
|
|
||
|
|
static gint crs_range_compare(gconstpointer a, gconstpointer b)
|
||
|
|
{
|
||
|
|
- CrsRangeEntry *entry_a = *(CrsRangeEntry **)a;
|
||
|
|
- CrsRangeEntry *entry_b = *(CrsRangeEntry **)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.19.1
|
||
|
|
|