Browse Source

KVM: MMU: Map device MMIO as UC in EPT

Software are not allow to access device MMIO using cacheable memory type, the
patch limit MMIO region with UC and WC(guest can select WC using PAT and
PCD/PWT).

Signed-off-by: Sheng Yang <sheng@linux.intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Sheng Yang 16 năm trước cách đây
mục cha
commit
2aaf69dcee
2 tập tin đã thay đổi với 8 bổ sung4 xóa
  1. 7 2
      arch/x86/kvm/mmu.c
  2. 1 2
      arch/x86/kvm/vmx.c

+ 7 - 2
arch/x86/kvm/mmu.c

@@ -1698,8 +1698,13 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
 	if (largepage)
 	if (largepage)
 		spte |= PT_PAGE_SIZE_MASK;
 		spte |= PT_PAGE_SIZE_MASK;
 	if (mt_mask) {
 	if (mt_mask) {
-		mt_mask = get_memory_type(vcpu, gfn) <<
-			  kvm_x86_ops->get_mt_mask_shift();
+		if (!kvm_is_mmio_pfn(pfn)) {
+			mt_mask = get_memory_type(vcpu, gfn) <<
+				kvm_x86_ops->get_mt_mask_shift();
+			mt_mask |= VMX_EPT_IGMT_BIT;
+		} else
+			mt_mask = MTRR_TYPE_UNCACHABLE <<
+				kvm_x86_ops->get_mt_mask_shift();
 		spte |= mt_mask;
 		spte |= mt_mask;
 	}
 	}
 
 

+ 1 - 2
arch/x86/kvm/vmx.c

@@ -3687,8 +3687,7 @@ static int __init vmx_init(void)
 	if (vm_need_ept()) {
 	if (vm_need_ept()) {
 		bypass_guest_pf = 0;
 		bypass_guest_pf = 0;
 		kvm_mmu_set_base_ptes(VMX_EPT_READABLE_MASK |
 		kvm_mmu_set_base_ptes(VMX_EPT_READABLE_MASK |
-			VMX_EPT_WRITABLE_MASK |
-			VMX_EPT_IGMT_BIT);
+			VMX_EPT_WRITABLE_MASK);
 		kvm_mmu_set_mask_ptes(0ull, 0ull, 0ull, 0ull,
 		kvm_mmu_set_mask_ptes(0ull, 0ull, 0ull, 0ull,
 				VMX_EPT_EXECUTABLE_MASK,
 				VMX_EPT_EXECUTABLE_MASK,
 				VMX_EPT_DEFAULT_MT << VMX_EPT_MT_EPTE_SHIFT);
 				VMX_EPT_DEFAULT_MT << VMX_EPT_MT_EPTE_SHIFT);