Add a fallback mechanism to the in-kernel instruction emulator that allows userspace the opportunity to process an instruction the emulator was unable to. When the in-kernel instruction emulator fails to process an instruction it will either inject a #UD into the guest or exit to userspace with exit reason KVM_INTERNAL_ERROR. This is because it does not know how to proceed in an appropriate manner. This feature lets userspace get involved to see if it can figure out a better path forward.
Showing the changes to include/uapi (1 of 4 files). Show all
Unified · Split
| @@ -280,6 +280,9 @@ struct kvm_xen_exit { · 279 unmodified lines | |||
| 280 | /* Encounter unexpected vm-exit reason */ | 280 | /* Encounter unexpected vm-exit reason */ |
| 281 | #define KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON 4 | 281 | #define KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON 4 |
| 282 | 282 | ||
| 283 | /* Flags that describe what fields in emulation_failure hold valid data. */ | ||
| 284 | #define KVM_INTERNAL_ERROR_EMULATION_FLAG_INSTRUCTION_BYTES (1ULL << 0) | ||
| 285 | |||
| 283 | /* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */ | 286 | /* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */ |
| 284 | struct kvm_run { | 287 | struct kvm_run { |
| 285 | /* in */ | 288 | /* in */ |
| @@ -383,6 +386,25 @@ struct kvm_run { · 97 unmodified lines | |||
| 383 | __u32 ndata; | 386 | __u32 ndata; |
| 384 | __u64 data[16]; | 387 | __u64 data[16]; |
| 385 | } internal; | 388 | } internal; |
| 389 | /* | ||
| 390 | * KVM_INTERNAL_ERROR_EMULATION | ||
| 391 | * | ||
| 392 | * "struct emulation_failure" is an overlay of "struct internal" | ||
| 393 | * that is used for the KVM_INTERNAL_ERROR_EMULATION sub-type of | ||
| 394 | * KVM_EXIT_INTERNAL_ERROR. Note, unlike other internal error | ||
| 395 | * sub-types, this struct is ABI! It also needs to be backwards | ||
| 396 | * compatible with "struct internal". Take special care that | ||
| 397 | * "ndata" is correct, that new fields are enumerated in "flags", | ||
| 398 | * and that each flag enumerates fields that are 64-bit aligned | ||
| 399 | * and sized (so that ndata+internal.data[] is valid/accurate). | ||
| 400 | */ | ||
| 401 | struct { | ||
| 402 | __u32 suberror; | ||
| 403 | __u32 ndata; | ||
| 404 | __u64 flags; | ||
| 405 | __u8 insn_size; | ||
| 406 | __u8 insn_bytes[15]; | ||
| 407 | } emulation_failure; | ||
| 386 | /* KVM_EXIT_OSI */ | 408 | /* KVM_EXIT_OSI */ |
| 387 | struct { | 409 | struct { |
| 388 | __u64 gprs[32]; | 410 | __u64 gprs[32]; |
| @@ -1088,6 +1110,7 @@ struct kvm_ppc_resize_hpt { · 699 unmodified lines | |||
| 1088 | #define KVM_CAP_EXIT_HYPERCALL 201 | 1110 | #define KVM_CAP_EXIT_HYPERCALL 201 |
| 1089 | #define KVM_CAP_PPC_RPT_INVALIDATE 202 | 1111 | #define KVM_CAP_PPC_RPT_INVALIDATE 202 |
| 1090 | #define KVM_CAP_BINARY_STATS_FD 203 | 1112 | #define KVM_CAP_BINARY_STATS_FD 203 |
| 1113 | #define KVM_CAP_EXIT_ON_EMULATION_FAILURE 204 | ||
| 1091 | 1114 | ||
| 1092 | #ifdef KVM_CAP_IRQ_ROUTING | 1115 | #ifdef KVM_CAP_IRQ_ROUTING |
| 1093 | 1116 | ||