mmio理解
EPT页表是通过EPT violation建立起来的。EPT misconfig是用来标志MMIO访问异常。entry中的保留位(reserved bit set)被设置了就会触发EPT misconfig。即为110b时会被trigger, 可写可执行不可访问,MMIO是通过设置spte的保留位来标志的.
写这种内存页会触发EPT misconfig,比如virtio-pci的notify配置空间地址。对于violation,它主要就是缺页故障,当内存读写都不被允许时就会触发
hardware_setup->kvm_mmu_set_ept_masks->kvm_mmu_set_mmio_spte_mask
/*
* EPT Misconfigurations are generated if the value of bits 2:0
* of an EPT paging-structure entry is 110b (write/execute).
*/
kvm_mmu_set_mmio_spte_mask(VMX_EPT_MISCONFIG_WX_VALUE, VMX_EPT_RWX_MASK, 0);
VMX_EPT_MISCONFIG_WX_VALUE 表示不可读可写可执行 -> 110b
VMX_EPT_RWX_MASK 表示可读可写可执行 -> 111b
下面定义的这个宏就是 0x2ull | 0x4ull = 110b
/* The mask to use to trigger an EPT Misconfiguration in order to track MMIO */
#define VMX_EPT_MISCONFIG_WX_VALUE (VMX_EPT_WRITABLE_MASK | VMX_EPT_EXECUTABLE_MASK)
kvm处理misconfig过程
handle_ept_misconfig-> kvm_mmu_page_fault > handle_mmio_page_fault
handle_mmio_page_fault的处理条件是 “unlikely(error_code & PFERR_RSVD_MASK)”
PFERR_RSVD_MASK 的值时3
Qemu通过memory_region_init_io 标记为mmio或者pio 类型。
# cat gets.stp
#!/bin/stapprobe module("kvm").function("kvm_iodevice_write") {print_backtrace()printf("=====$$parms=%s====", $$parms)
}probe module("kvm_intel").function("handle_ept_misconfig") {print_backtrace()printf("=====$$parms=%s====", $$parms$)exit();
}probe module("kvm_intel").function("handle_ept_violation") {print_backtrace()printf("=====$$parms=%s====", $$parms$)
}
更多推荐
mmio理解
发布评论