|
@@ -42,6 +42,7 @@
|
|
|
#include <linux/kern_levels.h>
|
|
|
|
|
|
#include <asm/page.h>
|
|
|
+#include <asm/pat.h>
|
|
|
#include <asm/cmpxchg.h>
|
|
|
#include <asm/io.h>
|
|
|
#include <asm/vmx.h>
|
|
@@ -2708,7 +2709,18 @@ static bool mmu_need_write_protect(struct kvm_vcpu *vcpu, gfn_t gfn,
|
|
|
static bool kvm_is_mmio_pfn(kvm_pfn_t pfn)
|
|
|
{
|
|
|
if (pfn_valid(pfn))
|
|
|
- return !is_zero_pfn(pfn) && PageReserved(pfn_to_page(pfn));
|
|
|
+ return !is_zero_pfn(pfn) && PageReserved(pfn_to_page(pfn)) &&
|
|
|
+ /*
|
|
|
+ * Some reserved pages, such as those from NVDIMM
|
|
|
+ * DAX devices, are not for MMIO, and can be mapped
|
|
|
+ * with cached memory type for better performance.
|
|
|
+ * However, the above check misconceives those pages
|
|
|
+ * as MMIO, and results in KVM mapping them with UC
|
|
|
+ * memory type, which would hurt the performance.
|
|
|
+ * Therefore, we check the host memory type in addition
|
|
|
+ * and only treat UC/UC-/WC pages as MMIO.
|
|
|
+ */
|
|
|
+ (!pat_enabled() || pat_pfn_immune_to_uc_mtrr(pfn));
|
|
|
|
|
|
return true;
|
|
|
}
|