History

kvm: x86: Allow userspace to handle emulation errors

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.

Aaron Lewis committed 5 years ago

Commit 19238e71 parent 27de9254 files · +85 −4Browse files

Showing the changes to include/uapi (1 of 4 files). Show all

Unified · Split

include/uapi/linux/kvm.h+23−0
@@ -280,6 +280,9 @@ struct kvm_xen_exit { · 279 unmodified lines
280280 /* Encounter unexpected vm-exit reason */
281281 #define KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON 4
282282
283+/* Flags that describe what fields in emulation_failure hold valid data. */
284+#define KVM_INTERNAL_ERROR_EMULATION_FLAG_INSTRUCTION_BYTES (1ULL << 0)
285+
283286 /* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */
284287 struct kvm_run {
285288 /* in */
@@ -383,6 +386,25 @@ struct kvm_run { · 97 unmodified lines
383386 __u32 ndata;
384387 __u64 data[16];
385388 } 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;
386408 /* KVM_EXIT_OSI */
387409 struct {
388410 __u64 gprs[32];
@@ -1088,6 +1110,7 @@ struct kvm_ppc_resize_hpt { · 699 unmodified lines
10881110 #define KVM_CAP_EXIT_HYPERCALL 201
10891111 #define KVM_CAP_PPC_RPT_INVALIDATE 202
10901112 #define KVM_CAP_BINARY_STATS_FD 203
1113+#define KVM_CAP_EXIT_ON_EMULATION_FAILURE 204
10911114
10921115 #ifdef KVM_CAP_IRQ_ROUTING
10931116