[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190830061540.211072-1-Tianyu.Lan@microsoft.com>
Date: Fri, 30 Aug 2019 14:15:40 +0800
From: lantianyu1986@...il.com
To: kys@...rosoft.com, haiyangz@...rosoft.com, sthemmin@...rosoft.com,
sashal@...nel.org, tglx@...utronix.de, mingo@...hat.com,
bp@...en8.de, hpa@...or.com, x86@...nel.org,
gregkh@...uxfoundation.org, alex.williamson@...hat.com,
cohuck@...hat.com, michael.h.kelley@...rosoft.com
Cc: Tianyu Lan <Tianyu.Lan@...rosoft.com>,
linux-hyperv@...r.kernel.org, linux-kernel@...r.kernel.org,
kvm@...r.kernel.org
Subject: [PATCH] x86/Hyper-V: Fix overflow issue in the fill_gva_list()
From: Tianyu Lan <Tianyu.Lan@...rosoft.com>
fill_gva_list() populates gva list and adds offset
HV_TLB_FLUSH_UNIT(0x1000000) to variable "cur"
in the each loop. When diff between "end" and "cur" is
less than HV_TLB_FLUSH_UNIT, the gva entry should
be the last one and the loop should be end.
If cur is equal or greater than 0xFF000000 on 32-bit
mode, "cur" will be overflow after adding HV_TLB_FLUSH_UNIT.
Its value will be wrapped and less than "end". fill_gva_list()
falls into an infinite loop and fill gva list out of
border finally.
Set "cur" to be "end" to make loop end when diff is
less than HV_TLB_FLUSH_UNIT and add HV_TLB_FLUSH_UNIT to
"cur" when diff is equal or greater than HV_TLB_FLUSH_UNIT.
Fix the overflow issue.
Reported-by: Jong Hyun Park <park.jonghyun@...sei.ac.kr>
Signed-off-by: Tianyu Lan <Tianyu.Lan@...rosoft.com>
Fixes: 2ffd9e33ce4a ("x86/hyper-v: Use hypercall for remote
TLB flush")
---
arch/x86/hyperv/mmu.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
index e65d7fe6489f..5208ba49c89a 100644
--- a/arch/x86/hyperv/mmu.c
+++ b/arch/x86/hyperv/mmu.c
@@ -37,12 +37,14 @@ static inline int fill_gva_list(u64 gva_list[], int offset,
* Lower 12 bits encode the number of additional
* pages to flush (in addition to the 'cur' page).
*/
- if (diff >= HV_TLB_FLUSH_UNIT)
+ if (diff >= HV_TLB_FLUSH_UNIT) {
gva_list[gva_n] |= ~PAGE_MASK;
- else if (diff)
+ cur += HV_TLB_FLUSH_UNIT;
+ } else if (diff) {
gva_list[gva_n] |= (diff - 1) >> PAGE_SHIFT;
+ cur = end;
+ }
- cur += HV_TLB_FLUSH_UNIT;
gva_n++;
} while (cur < end);
--
2.14.5
Powered by blists - more mailing lists