Skip to content

Commit 0c55671

Browse files
KarimAllah Ahmedbonzini
authored andcommitted
kvm, x86: Properly check whether a pfn is an MMIO or not
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 <karahmed@amazon.de> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent e0bf266 commit 0c55671

File tree

3 files changed

+20
-4
lines changed

3 files changed

+20
-4
lines changed

arch/x86/include/asm/e820/api.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ extern struct e820_table *e820_table_firmware;
1010

1111
extern unsigned long pci_mem_start;
1212

13+
extern bool e820__mapped_raw_any(u64 start, u64 end, enum e820_type type);
1314
extern bool e820__mapped_any(u64 start, u64 end, enum e820_type type);
1415
extern bool e820__mapped_all(u64 start, u64 end, enum e820_type type);
1516

arch/x86/kernel/e820.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,13 @@ EXPORT_SYMBOL(pci_mem_start);
7373
* This function checks if any part of the range <start,end> is mapped
7474
* with type.
7575
*/
76-
bool e820__mapped_any(u64 start, u64 end, enum e820_type type)
76+
static bool _e820__mapped_any(struct e820_table *table,
77+
u64 start, u64 end, enum e820_type type)
7778
{
7879
int i;
7980

80-
for (i = 0; i < e820_table->nr_entries; i++) {
81-
struct e820_entry *entry = &e820_table->entries[i];
81+
for (i = 0; i < table->nr_entries; i++) {
82+
struct e820_entry *entry = &table->entries[i];
8283

8384
if (type && entry->type != type)
8485
continue;
@@ -88,6 +89,17 @@ bool e820__mapped_any(u64 start, u64 end, enum e820_type type)
8889
}
8990
return 0;
9091
}
92+
93+
bool e820__mapped_raw_any(u64 start, u64 end, enum e820_type type)
94+
{
95+
return _e820__mapped_any(e820_table_firmware, start, end, type);
96+
}
97+
EXPORT_SYMBOL_GPL(e820__mapped_raw_any);
98+
99+
bool e820__mapped_any(u64 start, u64 end, enum e820_type type)
100+
{
101+
return _e820__mapped_any(e820_table, start, end, type);
102+
}
91103
EXPORT_SYMBOL_GPL(e820__mapped_any);
92104

93105
/*

arch/x86/kvm/mmu.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include <asm/page.h>
4545
#include <asm/pat.h>
4646
#include <asm/cmpxchg.h>
47+
#include <asm/e820/api.h>
4748
#include <asm/io.h>
4849
#include <asm/vmx.h>
4950
#include <asm/kvm_page_track.h>
@@ -2892,7 +2893,9 @@ static bool kvm_is_mmio_pfn(kvm_pfn_t pfn)
28922893
*/
28932894
(!pat_enabled() || pat_pfn_immune_to_uc_mtrr(pfn));
28942895

2895-
return true;
2896+
return !e820__mapped_raw_any(pfn_to_hpa(pfn),
2897+
pfn_to_hpa(pfn + 1) - 1,
2898+
E820_TYPE_RAM);
28962899
}
28972900

28982901
/* Bits which may be returned by set_spte() */

0 commit comments

Comments
 (0)