From mboxrd@z Thu Jan 1 00:00:00 1970 From: KarimAllah Ahmed Subject: [PATCH v6 14/14] kvm, x86: Properly check whether a pfn is an MMIO or not Date: Thu, 31 Jan 2019 21:24:44 +0100 Message-ID: <1548966284-28642-15-git-send-email-karahmed@amazon.de> References: <1548966284-28642-1-git-send-email-karahmed@amazon.de> Cc: KarimAllah Ahmed To: x86@kernel.org, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= , Paolo Bonzini Return-path: In-Reply-To: <1548966284-28642-1-git-send-email-karahmed@amazon.de> Sender: linux-kernel-owner@vger.kernel.org List-Id: kvm.vger.kernel.org pfn_valid check is not sufficient because it only checks if a page has a struct page or not, if "mem=" was passed to the kernel some valid pages won't have a struct page. This means that if guests were assigned valid memory that lies after the mem= boundary it will be passed uncached to the guest no matter what the guest caching attributes are for this memory. Introduce a new function e820__mapped_raw_any which is equivalent to e820__mapped_any but uses the original e820 unmodified and use it to identify real *RAM*. Signed-off-by: KarimAllah Ahmed --- v1 -> v2: - Introduce e820__mapped_raw_any --- arch/x86/include/asm/e820/api.h | 1 + arch/x86/kernel/e820.c | 18 +++++++++++++++--- arch/x86/kvm/mmu.c | 5 ++++- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/e820/api.h b/arch/x86/include/asm/e820/api.h index 4562062..b3f6e89 100644 --- a/arch/x86/include/asm/e820/api.h +++ b/arch/x86/include/asm/e820/api.h @@ -12,6 +12,7 @@ extern unsigned long e820_saved_max_low_pfn; extern unsigned long pci_mem_start; +extern bool e820__mapped_raw_any(u64 start, u64 end, enum e820_type type); extern bool e820__mapped_any(u64 start, u64 end, enum e820_type type); extern bool e820__mapped_all(u64 start, u64 end, enum e820_type type); diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index ef914d0..3039659 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -75,12 +75,13 @@ EXPORT_SYMBOL(pci_mem_start); * This function checks if any part of the range is mapped * with type. */ -bool e820__mapped_any(u64 start, u64 end, enum e820_type type) +static bool _e820__mapped_any(struct e820_table *table, + u64 start, u64 end, enum e820_type type) { int i; - for (i = 0; i < e820_table->nr_entries; i++) { - struct e820_entry *entry = &e820_table->entries[i]; + for (i = 0; i < table->nr_entries; i++) { + struct e820_entry *entry = &table->entries[i]; if (type && entry->type != type) continue; @@ -90,6 +91,17 @@ bool e820__mapped_any(u64 start, u64 end, enum e820_type type) } return 0; } + +bool e820__mapped_raw_any(u64 start, u64 end, enum e820_type type) +{ + return _e820__mapped_any(e820_table_firmware, start, end, type); +} +EXPORT_SYMBOL_GPL(e820__mapped_raw_any); + +bool e820__mapped_any(u64 start, u64 end, enum e820_type type) +{ + return _e820__mapped_any(e820_table, start, end, type); +} EXPORT_SYMBOL_GPL(e820__mapped_any); /* diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index da9c423..abf6a0d 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -2875,7 +2876,9 @@ static bool kvm_is_mmio_pfn(kvm_pfn_t pfn) */ (!pat_enabled() || pat_pfn_immune_to_uc_mtrr(pfn)); - return true; + return !e820__mapped_raw_any(pfn_to_hpa(pfn), + pfn_to_hpa(pfn + 1) - 1, + E820_TYPE_RAM); } /* Bits which may be returned by set_spte() */ -- 2.7.4