Skip to content

Instantly share code, notes, and snippets.

@JonathonReinhart
Created July 27, 2022 04:14
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JonathonReinhart/fdd25b716d1c567b056a6c3bb39c5807 to your computer and use it in GitHub Desktop.
Save JonathonReinhart/fdd25b716d1c567b056a6c3bb39c5807 to your computer and use it in GitHub Desktop.
KVM Emulate Flowchart

When does Linux KVM emulate instructions?

Flow Chart

graph LR

x86_emulate_instruction --> x86_emulate_insn
emulate_instruction --> x86_emulate_instruction

kvm_handle_page_fault --> kvm_mmu_page_fault
kvm_mmu_page_fault --> x86_emulate_instruction

handle_ud --> emulate_instruction




subgraph arch/x86/kvm/vmx.c
  vmx_handle_exit -- EXIT_REASON_EPT_MISCONFIG --> handle_ept_misconfig
  vmx_handle_exit -- EXIT_REASON_EPT_VIOLATION --> handle_ept_violation
  vmx_handle_exit -- EXIT_REASON_EXCEPTION_NMI --> handle_exception
  vmx_handle_exit -- EXIT_REASON_IO_INSTRUCTION --> handle_io
  vmx_handle_exit -- EXIT_REASON_GDTR_IDTR --> handle_desc
  vmx_handle_exit -- EXIT_REASON_LDTR_TR --> handle_desc
  vmx_handle_exit -- EXIT_REASON_INVD --> handle_invd
  vmx_handle_exit -- EXIT_REASON_APIC_ACCESS --> handle_apic_access
  vmx_handle_exit --> handle_invalid_guest_state
  handle_exception --> handle_rmode_exception
  kvm_arch_vcpu_ioctl_run -.-> complete_emulated_io
end
  handle_ept_misconfig --> x86_emulate_instruction
  handle_ept_misconfig --> kvm_mmu_page_fault
  handle_ept_violation --> kvm_mmu_page_fault
  handle_exception --> kvm_handle_page_fault
  handle_exception --> handle_ud
  handle_exception --> emulate_instruction
  handle_rmode_exception --> emulate_instruction
  handle_io --> emulate_instruction
  handle_desc --> emulate_instruction
  handle_invd --> emulate_instruction
  handle_apic_access --> emulate_instruction
  handle_invalid_guest_state --> emulate_instruction
  complete_emulated_io --> emulate_instruction


subgraph arch/x86/kvm/svm.c
  handle_exit -- SVM_EXIT_RSM --> rsm_interception
  handle_exit -- SVM_EXIT_NPF --> npf_interception
  handle_exit -- SVM_EXIT_EXCP_BASE + PF_VECTOR --> pf_interception
  handle_exit -- SVM_EXIT_EXCP_BASE + UD_VECTOR --> ud_interception
  handle_exit -- SVM_EXIT_EXCP_BASE + GP_VECTOR --> gp_interception
  handle_exit -- SVM_EXIT_INVLPG --> invlpg_interception
  handle_exit -- SVM_EXIT_IOIO --> io_interception
  handle_exit -- SVM_EXIT_INVD --> emulate_on_interception
  handle_exit -- SVM_EXIT_RDPMC --> rdpmc_interception
  handle_exit -- SVM_EXIT_READ_CR* --> cr_interception
  handle_exit -- SVM_EXIT_READ_DR* --> dr_interception
  handle_exit -- SVM_EXIT_AVIC_UNACCELERATED_ACCESS --> avic_unaccelerated_access_interception

  rdpmc_interception --> emulate_on_interception
  cr_interception --> emulate_on_interception
  dr_interception --> emulate_on_interception
end
  skip_emulated_instruction --> emulate_instruction
  rsm_interception --> x86_emulate_instruction
  npf_interception --> kvm_mmu_page_fault
  pf_interception --> kvm_handle_page_fault
  ud_interception --> handle_ud
  gp_interception --> emulate_instruction
  io_interception --> emulate_instruction
  invlpg_interception --> emulate_instruction
  emulate_on_interception --> emulate_instruction
  avic_unaccelerated_access_interception --> emulate_instruction

(Sorry, I lost track of the Linux kernel version from which this was derived.)

Other links

@tristone13th
Copy link

tristone13th commented Feb 2, 2023

Really helpful content! Some nits:

  • The emulate_instruction actually should be kvm_emulate_instruction.
  • The handle_exit in SVM actually should be svm_handle_exit.

@JonathonReinhart
Copy link
Author

Hi, I'm glad someone found this useful :-)

Like I said, I lost track of the Linux version on which I first mapped it out.

  • The emulate_instruction actually should be kvm_emulate_instruction.

It was renamed in August 2018:
torvalds/linux@0ce97a2: KVM: x86: Rename emulate_instruction() to kvm_emulate_instruction()

  • The handle_exit in SVM actually should be svm_handle_exit.

It was renamed in Jan 2022:
torvalds/linux@23e5092b6e2ad: KVM: SVM: Rename hook implementations to conform to kvm_x86_ops' names

I'm sure there are plenty of things wrong at this point. Before I would change these two, I would want to take a look at the whole thing (and record the version!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment