| From a9545779ee9e9e103648f6f2552e73cfe808d0f4 Mon Sep 17 00:00:00 2001 |
| From: Sean Christopherson <seanjc@google.com> |
| Date: Mon, 8 Feb 2021 12:19:40 -0800 |
| Subject: KVM: Use kvm_pfn_t for local PFN variable in hva_to_pfn_remapped() |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Sean Christopherson <seanjc@google.com> |
| |
| commit a9545779ee9e9e103648f6f2552e73cfe808d0f4 upstream. |
| |
| Use kvm_pfn_t, a.k.a. u64, for the local 'pfn' variable when retrieving |
| a so called "remapped" hva/pfn pair. In theory, the hva could resolve to |
| a pfn in high memory on a 32-bit kernel. |
| |
| This bug was inadvertantly exposed by commit bd2fae8da794 ("KVM: do not |
| assume PTE is writable after follow_pfn"), which added an error PFN value |
| to the mix, causing gcc to comlain about overflowing the unsigned long. |
| |
| arch/x86/kvm/../../../virt/kvm/kvm_main.c: In function ‘hva_to_pfn_remapped’: |
| include/linux/kvm_host.h:89:30: error: conversion from ‘long long unsigned int’ |
| to ‘long unsigned int’ changes value from |
| ‘9218868437227405314’ to ‘2’ [-Werror=overflow] |
| 89 | #define KVM_PFN_ERR_RO_FAULT (KVM_PFN_ERR_MASK + 2) |
| | ^ |
| virt/kvm/kvm_main.c:1935:9: note: in expansion of macro ‘KVM_PFN_ERR_RO_FAULT’ |
| |
| Cc: stable@vger.kernel.org |
| Fixes: add6a0cd1c5b ("KVM: MMU: try to fix up page faults before giving up") |
| Signed-off-by: Sean Christopherson <seanjc@google.com> |
| Message-Id: <20210208201940.1258328-1-seanjc@google.com> |
| Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
| Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| virt/kvm/kvm_main.c | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| --- a/virt/kvm/kvm_main.c |
| +++ b/virt/kvm/kvm_main.c |
| @@ -1501,7 +1501,7 @@ static int hva_to_pfn_remapped(struct vm |
| bool write_fault, bool *writable, |
| kvm_pfn_t *p_pfn) |
| { |
| - unsigned long pfn; |
| + kvm_pfn_t pfn; |
| pte_t *ptep; |
| spinlock_t *ptl; |
| int r; |