Skip to the content.

x86 emulate

x86 kvm 代码行数统计,显然 emulate.c 是添加上很多的代码的, 所以,自然我们会问,为什么会这么复杂?

📂  vmx                18413      27.02 %
📂  svm                10906      16.35 %
💻  x86.c              10208      14.27 %
📂  mmu                8400       13.91 %
💻  emulate.c          4375       5.55 %
💻  lapic.c            2504       3.57 %
💻  hyperv.c           2174       2.88 %
💻  xen.c              1595       2.31 %
💻  cpuid.c            1477       2.14 %

整体印象

对应 : EMULTYPE_PF

./emulate-insn.bt 统计可以获取

emulate-insn-results.txt

什么触发了 instruction emulation

从 EMULTYPE_NO_DECODE

MMIO/PIO 是设备访问事件;EMULTYPE_* 是模拟器的执行标志,两者没有一一对应关系。

脚本只挂了 kvm_mmio、kvm_pio 两种设备访问 tracepoint,所以设备事件只显示这两类;但 CALL 中的 emulation_type 会记录所有标志。

其他标志需要特定条件:

标志 为什么本次没有看到 ━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ TRAP_UD 没有捕获到触发该入口的 #UD ──────────────── ─────────────────────────────────────────────────────── SKIP 普通 VMX exit 已提供指令长度,通常直接更新 RIP ──────────────── ─────────────────────────────────────────────────────── ALLOW_RETRY_PF 主要用于 shadow 写保护故障;MMIO 无法通过拆表重试解决 ──────────────── ─────────────────────────────────────────────────────── TRAP_UD_FORCED 需要启用强制模拟前缀;当前宿主配置为 0 ──────────────── ─────────────────────────────────────────────────────── VMWARE_GP 需要 VMware backdoor 兼容访问;当前宿主配置为 N

场景 为什么需要模拟 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 被模拟的 MMIO 完成访问设备的普通访存指令 ───────────────────────────────── ────────────────────────────────────────── INS/OUTS、REP 字符串 I/O 同时处理端口、内存、重复次数和寄存器更新 ───────────────────────────────── ────────────────────────────────────────── 写受保护的 guest 页表 完成写入,同时维护 shadow 页表 ───────────────────────────────── ────────────────────────────────────────── 旧 VMX 硬件的状态限制 软件执行到能够重新进入硬件运行的状态 ───────────────────────────────── ────────────────────────────────────────── 特定 #UD、UMIP、VMware 兼容路径 补充特定指令行为或异常语义

MMIO

guest 执行 mov dword ptr [rbx], eax:

尤其是 MMIO 读:KVM 需要先退出到 QEMU 取得数据,再通过 EMULTYPE_NO_DECODE 继续完成同一条指令。 这也是你看到大量 complete_emulated_io() 调用的原因;

KVM API 说明 (https://docs.kernel.org/virt/kvm/api.html#the-kvm-run-structure)

其他场景

采集字段 描述什么 例子
CALL 的 emulation_type 模拟入口的特殊标志 PF、NO_DECODE、TRAP_UD、SKIP
CALL 的 exit_reason 最近一次硬件 VM exit 原因 EPT_VIOLATION、EPT_MISCONFIG、IO_INSTRUCTION、APIC_ACCESS
MMIO/PIO 记录 模拟过程中或专用 I/O 路径发生的设备访问 设备 GPA、端口、宽度、数据
emulation_type 次数 含义
64 = 0x40 = EMULTYPE_PF 35089 经 MMU 页故障路径触发,本次样本中对应 MMIO
1 = EMULTYPE_NO_DECODE 1510 已解码指令的用户态 I/O 续接
0 55 完整模拟,没有设置特殊标志:48 次 string PIO、7 次 APIC access
场景 为什么需要模拟 当前源码入口
INS/OUTS,包括 REP 字符串 I/O 同时涉及端口、guest 内存、RSI/RDI、RCX、DF、权限及部分完成 vmx/vmx.c 的 handle_io()
guest 写被跟踪的页表/内存 KVM 要拦住写入并维护 shadow 页表或 page tracking,不能直接放开所有写入 mmu/mmu.c 的 kvm_mmu_write_protect_fault()、page_fault_handle_page_track()
APIC access exit 需要完成实际访问 APIC 页的指令;部分 EOI 写有专用快速路径 vmx/vmx.c 的 handle_apic_access()
VMX guest 状态不满足旧硬件 VM-entry 约束 先用软件执行,使状态回到能进入硬件执行的范围 vmx/vmx.c 的 handle_invalid_guest_state()
旧 VMX 的 real-mode/VM86 回退 例如某些合法 real-mode 指令在用于回退的 VM86 环境中产生 #GP/#SS vmx/vmx.c 的 handle_rmode_exception()
某些被截获的 #UD 模拟特定兼容指令或 hypercall,而不是直接向 guest 注入 #UD x86.c 的 handle_ud(),emulate.c 的 EmulateOnUD
UMIP 的软件实现 拦截描述符表相关指令,在 guest CPL 等条件下实现应有的效果/异常 vmx/vmx.c 的 handle_desc()
VMware backdoor 兼容 接管特定 #GP,放行约定的 IN/OUT、INS/OUTS、RDPMC EMULTYPE_VMWARE_GP、is_vmware_backdoor_opcode()
硬件没有提供足够的 decode assist 无法直接确定操作或下一 RIP,需要软件解码/执行 svm/svm.c 的 invlpg_interception()、__svm_skip_emulated_instruction()

MMIO

2.3 实际入口

arch/x86/kvm/vmx/vmx.c、vmx/common.h 和 mmu/mmu.c 中的主路径:

handle_ept_violation()
  -> __vmx_handle_ept_violation()
     -> kvm_mmu_page_fault()
        -> MMU 判定需要 RET_PF_EMULATE
           -> x86_emulate_instruction(..., EMULTYPE_PF, ...)

EMULTYPE_PF 表示传入的 CR2/GPA 有效,不表示所有缺页都需要模拟。

kvm_mmu_page_fault() 只有在处理结果是 RET_PF_EMULATE 时才调用模拟器。 正常 RAM 映射修复、重试或真正的 guest 页表权限错误,都有自己的处理结果。 尤其在通常的 EPT 配置下,guest 自己的普通 #PF 由硬件交给 guest,不必先退出到 KVM。

MMIO 还可能走另一条入口:

handle_ept_misconfig()
  -> kvm_mmu_page_fault(..., PFERR_RSVD_MASK, ...)
     -> handle_mmio_page_fault()
        -> x86_emulate_instruction()

这是因为 KVM 可以用特殊的 MMIO SPTE 缓存“该 GPA 是 MMIO”,主动构造会引起 EPT misconfiguration 的条目。这个场景中的 misconfig 不一定是页表出错。

PIO

不是所有的 io 都是经过:

  static int handle_io(struct kvm_vcpu *vcpu)
  {
      ...
      string = (exit_qualification & 16) != 0;   // 是否为串 I/O (rep ins/outs)

      if (string)
          return kvm_emulate_instruction(vcpu, 0);  // 走完整模拟 → 有 CALL/RETURN

      ...
      return kvm_fast_pio(vcpu, size, port, in);    // 走 fast PIO 路径 → 无 CALL/RETURN
  }

KVM 有两条 PIO 路径:

  1. 串 I/O(rep ins/rep outs):kvm_emulate_instruction() → x86_emulate_instruction(),fentry/fexit 探针命 中 → 产生 CALL/INSN/RETURN;模拟器内部回调 emulator_pio_in_emulated/emulator_pio_out_emulated 时 trace_kvm_pio 触发 → PIO 落在窗口内。

  2. 非串 I/O(单条 in/out):kvm_fast_pio() → kvm_fast_pio_in/out() → 直接调 emulator_pio_in()/emulator_pio_out()(arch/x86/kvm/x86.c),这两个函数内部 trace_kvm_pio() 直接触发,根 本不经过 x86_emulate_instruction,所以没有 CALL/RETURN。

基本流程

如果检测到虚拟机中存在大量的这种调用,这市场不正常的

@[
        perf_trace_kvm_mmio+16
        vcpu_mmio_write+234
        emulator_read_write_onepage+170
        emulator_read_write+283
        x86_emulate_insn+1446
        x86_emulate_instruction+670
        vmx_handle_exit+18
        vcpu_enter_guest.constprop.0+2069
        vcpu_run+50
        kvm_arch_vcpu_ioctl_run+398
        kvm_vcpu_ioctl+879
        __x64_sys_ioctl+185
        do_syscall_64+226
        entry_SYSCALL_64_after_hwframe+118
]: 13218
         - 15.70% __x64_sys_ioctl                                                                                                                                                                                                                            ▒
            - 14.45% kvm_vcpu_ioctl                                                                                                                                                                                                                          ▒
               - 13.98% kvm_arch_vcpu_ioctl_run                                                                                                                                                                                                              ▒
                  - 5.44% vmx_handle_exit                                                                                                                                                                                                                    ▒
                     - 5.06% x86_emulate_instruction                                                                                                                                                                                                         ▒
                        - 3.13% x86_decode_emulated_instruction                                                                                                                                                                                              ▒
                           - 2.86% x86_decode_insn                                                                                                                                                                                                           ▒
                              - 2.28% __do_insn_fetch_bytes                                                                                                                                                                                                  ▒
                                 - 1.94% kvm_fetch_guest_virt                                                                                                                                                                                                ▒
                                    - 1.23% paging64_gva_to_gpa                                                                                                                                                                                              ▒
                                         1.06% paging64_walk_addr_generic                                                                                                                                                                                    ▒
                        - 1.66% x86_emulate_insn                                                                                                                                                                                                             ▒
                           - 0.72% emulator_read_write                                                                                                                                                                                                       ▒
                              - emulator_read_write_onepage                                                                                                                                                                                                  ▒
                                   0.52% write_mmio                                                                                                                                                                                                          ▒
                  - 2.17% vmx_vcpu_run                                                                                                                                                                                                                       ▒
                       0.53% native_write_msr                                                                                                                                                                                                                ▒
                  - 1.50% vmx_prepare_switch_to_guest                                                                                                                                                                                                        ▒
                     - 0.80% kvm_set_user_return_msr                                                                                                                                                                                                         ▒
                          0.55% native_write_msr_safe                                                                                                                                                                                                        ▒
                  - 1.49% fpu_swap_kvm_fpstate                                                                                                                                                                                                               ▒
                       0.76% restore_fpregs_from_fpstate                                                                                                                                                                                                     ▒
                  - 1.02% vcpu_put                                                                                                                                                                                                                           ▒
                     - 0.99% kvm_arch_vcpu_put                                                                                                                                                                                                               ▒
                          vmx_vcpu_put                                                                                                                                                                                                                       ▒
                  - 0.68% vcpu_load                                                                                                                                                                                                                          ▒
                       0.65% kvm_arch_vcpu_load                                                                                                                                                                                                              ▒
            - 0.64% kvm_vm_ioctl                                                                                                                                                                                                                             ▒
               - 0.56% kvm_send_userspace_msi                                                                                                                                                                                                                ▒
                  - 0.53% kvm_set_msi                                                                                                                                                                                                                        ▒
                       0.51% kvm_irq_delivery_to_apic

是不是因为需要处理变长指令 ?

	/* If guest state is invalid, start emulating.  L2 is handled above. */
	if (vmx->emulation_required)
		return handle_invalid_guest_state(vcpu);

并不是原因,因为 vmx_emulation_required 总是返回 0

bool vmx_emulation_required(struct kvm_vcpu *vcpu)
{
	return emulate_invalid_guest_state && !vmx_guest_state_valid(vcpu);
}

主要的调用源头为:

mmio 的两阶段运行

@[
    bpf_prog_815d6551cd4d7b0b_sd_fw_ingress+163
    bpf_prog_815d6551cd4d7b0b_sd_fw_ingress+163
    bpf_trampoline_354334906189+87
    x86_emulate_instruction+9
    kvm_arch_vcpu_ioctl_run+3265
    kvm_vcpu_ioctl+587
    __x64_sys_ioctl+148
    do_syscall_64+59
    entry_SYSCALL_64_after_hwframe+110
]: 78833
@[
    x86_emulate_instruction+9
    vmx_handle_exit+2034
    kvm_arch_vcpu_ioctl_run+1701
    kvm_vcpu_ioctl+587
    __x64_sys_ioctl+148
    do_syscall_64+59
    entry_SYSCALL_64_after_hwframe+110
]: 122776

3. I/O completion 为什么又进入模拟器

以 MMIO 读为例:

mov eax, dword ptr [rbx]

KVM 在拿到设备返回值之前,无法完成 EAX 写回。设备在用户态时,指令执行需要暂停:

sequenceDiagram
    participant CPU as Guest CPU
    participant KVM as KVM
    participant QEMU as QEMU
    CPU->>KVM: MMIO 触发 EPT VM exit
    KVM->>KVM: 解码指令,保留模拟上下文
    KVM->>QEMU: KVM_RUN 返回 KVM_EXIT_MMIO
    QEMU->>QEMU: 读取虚拟设备
    QEMU->>KVM: 填写 mmio.data,再调用 KVM_RUN
    KVM->>KVM: complete_emulated_mmio()
    KVM->>KVM: 用 EMULTYPE_NO_DECODE 继续模拟
    KVM->>CPU: 完成寄存器和 RIP 更新,恢复执行

对应 arch/x86/kvm/x86.c 的调用关系:

kvm_arch_vcpu_ioctl_run()
  -> vcpu->arch.complete_userspace_io()
     -> complete_emulated_mmio() / complete_emulated_pio()
        -> complete_emulated_io()
           -> kvm_emulate_instruction(..., EMULTYPE_NO_DECODE)

EMULTYPE_NO_DECODE 复用之前的模式、解码结果和读缓存,不重新取指。 emulate.c 的 read_emulated() 按顺序使用已完成的读结果; x86.c 的 emulator_read_write() 处理 mmio_read_completed。 这是继续完成同一条指令,不能算成 guest 又执行了一条新指令。

读和写还不对称:

所以,complete_emulated_mmio() 被调用,并不必然意味着下一步就是 EMULTYPE_NO_DECODE;要看读写方向和 fragment 是否全部完成。

KVM ABI 要求用户态重新进入 KVM_RUN 完成未结束的 I/O,不能因为已经收到一次 KVM_EXIT_MMIO 就认定操作全部结束。参见 KVM API 的 KVM_RUN / KVM_EXIT_MMIO 说明。

NO_DECODE 的含义

• NO_DECODE 的意思是:这条指令已经解码过了,复用解码结果,再执行模拟阶段。 用户态 I/O 续接是它最常见的用途。

这里的 exit_reason 指脚本保存的 @exit_reason[tid],它只在 硬件 VM exit 时更新。

假设 guest 执行:

mov eax, dword ptr [rbx] ; 从 QEMU 模拟的设备读取数据

整个过程如下:

① guest 执行 MOV,访问 MMIO → 硬件产生 EPT_MISCONFIG VM exit → 探针保存 @exit_reason[tid] = 49

② x86_emulate_instruction(PF) → 解码:知道这是 MOV,读 4 字节,结果写入 EAX → 执行模拟:发现需要 QEMU 提供设备数据 → 保存模拟上下文 → KVM_RUN 返回到 QEMU

③ QEMU 读取设备,填写 mmio.data → 再次调用 KVM_RUN

④ complete_emulated_mmio() → x86_emulate_instruction(NO_DECODE) → 复用之前的解码结果 → 使用已经返回的设备数据完成 MOV → 写回 EAX,推进 RIP → 恢复 guest 执行

③ 到 ④ 期间,guest 没有执行,也就没有发生新的硬件 VM exit。 所以探针的 @exit_reason[tid] 仍然是第①步保存的 49。

你因此会看到类似记录:

CALL … emulation_type=64 exit_reason=49 # 首次模拟,PF INSN … mov eax,[rbx] RETURN … 0 # 需要用户态 I/O

CALL … emulation_type=1 exit_reason=49 # 续接,NO_DECODE MMIO … read … RETURN … 1 # 已完成

这里有两次模拟器调用,却只有一次对应的硬件 VM exit。

在 /home/martins3/data/kernel/linux-drm/arch/x86/kvm/x86.c 的 x86_emulate_instruction() 中,可以把逻辑理解成:

if (!(emulation_type & EMULTYPE_NO_DECODE)) x86_decode_emulated_instruction(…);

x86_emulate_insn(…);

所以 NO_DECODE 仍然会执行模拟。它复用指令、操作数和读缓存,完成剩余效果,避免重新取指解码、重复读取已经返回的数据。它也不是恢复之前暂停的 C 调用栈,而 是再次调用模拟执行函数。

INSN tracepoint 在解码阶段发出,因此这次续接通常有 CALL/RETURN,却没有新的 INSN 记录。

2026-10-01 不过,还是有东西对不上,记录的 backtrace 的数量,这个 completes 机制 此外,complate 机制本身也是需要继续思考下的。

有趣的东西

• 每秒 14~15 次的来源已经查到了:3 台 Linux VM 的 virtio-gpu 周期性刷新,主要对应文本控制台光标闪烁。

我在当前机器上采样了 10 秒:

虚拟机 vcpu_mmio_write 次数 写入的 guest 物理地址 ━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━ oe2403 48 0x4800017000 ────────── ────────────────────── ─────────────────────── virtme/t 48 0x4800023000 ────────── ────────────────────── ─────────────────────── yyds-fs 48 0xe0212027000 ────────── ────────────────────── ─────────────────────── 合计 144 约 14.4 次/秒

这三个地址都是各自 virtio-gpu 的 queue notify 寄存器,每次写 2 字节,值为 0,即通知控制队列。

在 oe2403 guest 内进一步采样 5 秒,结果是:

fb_flashcursor 24 次 virtio_gpu_notify 24 次

Linux 的 fbcon.c (/home/martins3/data/kernel/linux/drivers/video/fbdev/core/fbcon.c) 中,fbcon_open() 将光标闪烁 间隔初始化为 HZ / 5,fb_flashcursor() 周期性更新光标。更新经过显示驱动,最终通过 MMIO 通知 virtio-gpu:

光标闪烁 → 更新画面 → virtio_gpu_notify() → 写 queue notify → host 的 vcpu_mmio_write()

因此,每台约 5 次/秒,3 台合计约 15 次/秒。延迟工作调度及统计窗口边界使实际显示在 14、15 之间变化。这个数字来自 当前 guest 的活动,并非 KVM 固定每秒执行 15 次。

Windows 启动后突然升高,需要采集新增访问的地址才能确定具体来源。 当前 Windows 没运行,所以这部分还没有实测结论。

ioeventfd 的优化

  1. virtio-blk/net 也要写 MMIO,为什么没出现在这个计数里

是的。现代 virtio-pci 的典型过程是:

将描述符、数据放入 guest RAM 中的 virtqueue → 更新 available ring → 必要时写 MMIO notify 寄存器,通知设备处理

数据通过共享内存队列传递,MMIO 写主要负责通知。 通知还可以合并、抑制,因此不必每个请求都写一次。Virtio 官方内核文档 (https://cdn.kernel.org/doc/html/latest/driver-api/virtio/virtio.html)

我通过 QMP 查询了当前 Windows 的实际设备属性:

设备 ioeventfd ━━━━━━━━━━━━ ━━━━━━━━━━━ virtio-vga false ──────────── ─────────── virtio-blk true ──────────── ─────────── virtio-net true

这造成了本机两条不同的处理路径:

virtio-gpu 通知: MMIO 写 → VM exit → 指令模拟 → vcpu_mmio_write() → 返回 QEMU 处理

启用 ioeventfd 的 blk/net 通知,快速路径命中时: MMIO 写 → VM exit → handle_ept_misconfig() → KVM_FAST_MMIO_BUS → eventfd 通知后端

第二条路径跳过了完整指令模拟,也跳过了 vcpu_mmio_write()。 它仍然发生硬件 VM exit,只是 KVM 能更快处理;后端可以 是 QEMU 的 I/O 线程,也可以是 vhost。

这次也实际采到了 blk/net 的 kvm_fast_mmio 事件。例如 0x380800007030 落在启动盘的通知区域,0x38080000f004 落在网 卡的通知区域。

对应源码是 vmx.c (/home/martins3/data/kernel/linux/arch/x86/kvm/vmx/vmx.c) 中的 handle_ept_misconfig(),以及 virtio-pci.c (/home/martins3/data/qemu/hw/virtio/virtio-pci.c) 中的 virtio_pci_ioeventfd_assign()。后者为现代通 知地址注册不匹配长度和数据值的 eventfd,使 KVM 能仅凭访问地址完成通知。

因此,观察 virtio 通知时,应同时看 vcpu_mmio_write 和 kvm:kvm_fast_mmio;只看前者,会漏掉大量磁盘和网络通知。 Windows 目前保持运行。

[ ] 这里还有网络和 virtio-blk 的差别

差不多是这个意思了吧

x86.c 的 vcpu_mmio_read()/vcpu_mmio_write() 会尝试内核 APIC 模型与 KVM_MMIO_BUS。总线上的设备包括可以通知 eventfd 的 ioeventfd: virt/kvm/eventfd.c 的 ioeventfd_write() 匹配地址、长度以及可选的数据值后, 直接调用 eventfd_signal()。

因此,有些访问仍需要模拟指令以得到写入值和宽度,但设备侧已经在内核处理完, 不产生 KVM_EXIT_MMIO。普通 PIO 也会通过 KVM_PIO_BUS 尝试内核处理。

还有更专门的优化:仅匹配地址的 MMIO ioeventfd(注册长度为 0,不能设置 DATAMATCH) 同时注册到 KVM_FAST_MMIO_BUS。非 nested guest 的 handle_ept_misconfig() 可以先尝试这个总线;匹配成功后通知 eventfd 并跳过指令,省去完整模拟。 handle_apic_access() 的部分 EOI 写也有绕过通用模拟的快速路径。

“设备在内核处理”“需要指令模拟”“需要退出到 QEMU”应当分别判断。

附录

/*
 * EMULTYPE_NO_DECODE - Set when re-emulating an instruction (after completing
 *			userspace I/O) to indicate that the emulation context
 *			should be reused as is, i.e. skip initialization of
 *			emulation context, instruction fetch and decode.
 *
 * EMULTYPE_TRAP_UD - Set when emulating an intercepted #UD from hardware.
 *		      Indicates that only select instructions (tagged with
 *		      EmulateOnUD) should be emulated (to minimize the emulator
 *		      attack surface).  See also EMULTYPE_TRAP_UD_FORCED.
 *
 * EMULTYPE_SKIP - Set when emulating solely to skip an instruction, i.e. to
 *		   decode the instruction length.  For use *only* by
 *		   kvm_x86_ops.skip_emulated_instruction() implementations if
 *		   EMULTYPE_COMPLETE_USER_EXIT is not set.
 *
 * EMULTYPE_ALLOW_RETRY_PF - Set when the emulator should resume the guest to
 *			     retry native execution under certain conditions,
 *			     Can only be set in conjunction with EMULTYPE_PF.
 *
 * EMULTYPE_TRAP_UD_FORCED - Set when emulating an intercepted #UD that was
 *			     triggered by KVM's magic "force emulation" prefix,
 *			     which is opt in via module param (off by default).
 *			     Bypasses EmulateOnUD restriction despite emulating
 *			     due to an intercepted #UD (see EMULTYPE_TRAP_UD).
 *			     Used to test the full emulator from userspace.
 *
 * EMULTYPE_VMWARE_GP - Set when emulating an intercepted #GP for VMware
 *			backdoor emulation, which is opt in via module param.
 *			VMware backdoor emulation handles select instructions
 *			and reinjects the #GP for all other cases.
 *
 * EMULTYPE_PF - Set when an intercepted #PF triggers the emulation, in which case
 *		 the CR2/GPA value pass on the stack is valid.
 *
 * EMULTYPE_COMPLETE_USER_EXIT - Set when the emulator should update interruptibility
 *				 state and inject single-step #DBs after skipping
 *				 an instruction (after completing userspace I/O).
 *
 * EMULTYPE_WRITE_PF_TO_SP - Set when emulating an intercepted page fault that
 *			     is attempting to write a gfn that contains one or
 *			     more of the PTEs used to translate the write itself,
 *			     and the owning page table is being shadowed by KVM.
 *			     If emulation of the faulting instruction fails and
 *			     this flag is set, KVM will exit to userspace instead
 *			     of retrying emulation as KVM cannot make forward
 *			     progress.
 *
 *			     If emulation fails for a write to guest page tables,
 *			     KVM unprotects (zaps) the shadow page for the target
 *			     gfn and resumes the guest to retry the non-emulatable
 *			     instruction (on hardware).  Unprotecting the gfn
 *			     doesn't allow forward progress for a self-changing
 *			     access because doing so also zaps the translation for
 *			     the gfn, i.e. retrying the instruction will hit a
 *			     !PRESENT fault, which results in a new shadow page
 *			     and sends KVM back to square one.
 *
 * EMULTYPE_SKIP_SOFT_INT - Set in combination with EMULTYPE_SKIP to only skip
 *                          an instruction if it could generate a given software
 *                          interrupt, which must be encoded via
 *                          EMULTYPE_SET_SOFT_INT_VECTOR().
 */
#define EMULTYPE_NO_DECODE	    (1 << 0)
#define EMULTYPE_TRAP_UD	    (1 << 1)
#define EMULTYPE_SKIP		    (1 << 2)
#define EMULTYPE_ALLOW_RETRY_PF	    (1 << 3)
#define EMULTYPE_TRAP_UD_FORCED	    (1 << 4)
#define EMULTYPE_VMWARE_GP	    (1 << 5)
#define EMULTYPE_PF		    (1 << 6)
#define EMULTYPE_COMPLETE_USER_EXIT (1 << 7)
#define EMULTYPE_WRITE_PF_TO_SP	    (1 << 8)
#define EMULTYPE_SKIP_SOFT_INT	    (1 << 9)

这是 flags ,不是种类的意思

好玩的东西

codex resume 01a143d4-19a6-7430-ab1a-efe2365ecb69

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。