@@ -7664,29 +7664,78 @@ void kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip)
7664
7664
}
7665
7665
EXPORT_SYMBOL_GPL (kvm_inject_realmode_interrupt );
7666
7666
7667
- static void prepare_emulation_failure_exit (struct kvm_vcpu * vcpu )
7667
+ static void prepare_emulation_failure_exit (struct kvm_vcpu * vcpu , u64 * data ,
7668
+ u8 ndata , u8 * insn_bytes , u8 insn_size )
7668
7669
{
7669
- struct x86_emulate_ctxt * ctxt = vcpu -> arch .emulate_ctxt ;
7670
- u32 insn_size = ctxt -> fetch .end - ctxt -> fetch .data ;
7671
7670
struct kvm_run * run = vcpu -> run ;
7671
+ u64 info [5 ];
7672
+ u8 info_start ;
7673
+
7674
+ /*
7675
+ * Zero the whole array used to retrieve the exit info, as casting to
7676
+ * u32 for select entries will leave some chunks uninitialized.
7677
+ */
7678
+ memset (& info , 0 , sizeof (info ));
7679
+
7680
+ static_call (kvm_x86_get_exit_info )(vcpu , (u32 * )& info [0 ], & info [1 ],
7681
+ & info [2 ], (u32 * )& info [3 ],
7682
+ (u32 * )& info [4 ]);
7672
7683
7673
7684
run -> exit_reason = KVM_EXIT_INTERNAL_ERROR ;
7674
7685
run -> emulation_failure .suberror = KVM_INTERNAL_ERROR_EMULATION ;
7675
- run -> emulation_failure .ndata = 0 ;
7686
+
7687
+ /*
7688
+ * There's currently space for 13 entries, but 5 are used for the exit
7689
+ * reason and info. Restrict to 4 to reduce the maintenance burden
7690
+ * when expanding kvm_run.emulation_failure in the future.
7691
+ */
7692
+ if (WARN_ON_ONCE (ndata > 4 ))
7693
+ ndata = 4 ;
7694
+
7695
+ /* Always include the flags as a 'data' entry. */
7696
+ info_start = 1 ;
7676
7697
run -> emulation_failure .flags = 0 ;
7677
7698
7678
7699
if (insn_size ) {
7679
- run -> emulation_failure .ndata = 3 ;
7700
+ BUILD_BUG_ON ((sizeof (run -> emulation_failure .insn_size ) +
7701
+ sizeof (run -> emulation_failure .insn_bytes ) != 16 ));
7702
+ info_start += 2 ;
7680
7703
run -> emulation_failure .flags |=
7681
7704
KVM_INTERNAL_ERROR_EMULATION_FLAG_INSTRUCTION_BYTES ;
7682
7705
run -> emulation_failure .insn_size = insn_size ;
7683
7706
memset (run -> emulation_failure .insn_bytes , 0x90 ,
7684
7707
sizeof (run -> emulation_failure .insn_bytes ));
7685
- memcpy (run -> emulation_failure .insn_bytes ,
7686
- ctxt -> fetch .data , insn_size );
7708
+ memcpy (run -> emulation_failure .insn_bytes , insn_bytes , insn_size );
7687
7709
}
7710
+
7711
+ memcpy (& run -> internal .data [info_start ], info , sizeof (info ));
7712
+ memcpy (& run -> internal .data [info_start + ARRAY_SIZE (info )], data ,
7713
+ ndata * sizeof (data [0 ]));
7714
+
7715
+ run -> emulation_failure .ndata = info_start + ARRAY_SIZE (info ) + ndata ;
7688
7716
}
7689
7717
7718
+ static void prepare_emulation_ctxt_failure_exit (struct kvm_vcpu * vcpu )
7719
+ {
7720
+ struct x86_emulate_ctxt * ctxt = vcpu -> arch .emulate_ctxt ;
7721
+
7722
+ prepare_emulation_failure_exit (vcpu , NULL , 0 , ctxt -> fetch .data ,
7723
+ ctxt -> fetch .end - ctxt -> fetch .data );
7724
+ }
7725
+
7726
+ void __kvm_prepare_emulation_failure_exit (struct kvm_vcpu * vcpu , u64 * data ,
7727
+ u8 ndata )
7728
+ {
7729
+ prepare_emulation_failure_exit (vcpu , data , ndata , NULL , 0 );
7730
+ }
7731
+ EXPORT_SYMBOL_GPL (__kvm_prepare_emulation_failure_exit );
7732
+
7733
+ void kvm_prepare_emulation_failure_exit (struct kvm_vcpu * vcpu )
7734
+ {
7735
+ __kvm_prepare_emulation_failure_exit (vcpu , NULL , 0 );
7736
+ }
7737
+ EXPORT_SYMBOL_GPL (kvm_prepare_emulation_failure_exit );
7738
+
7690
7739
static int handle_emulation_failure (struct kvm_vcpu * vcpu , int emulation_type )
7691
7740
{
7692
7741
struct kvm * kvm = vcpu -> kvm ;
@@ -7701,16 +7750,14 @@ static int handle_emulation_failure(struct kvm_vcpu *vcpu, int emulation_type)
7701
7750
7702
7751
if (kvm -> arch .exit_on_emulation_error ||
7703
7752
(emulation_type & EMULTYPE_SKIP )) {
7704
- prepare_emulation_failure_exit (vcpu );
7753
+ prepare_emulation_ctxt_failure_exit (vcpu );
7705
7754
return 0 ;
7706
7755
}
7707
7756
7708
7757
kvm_queue_exception (vcpu , UD_VECTOR );
7709
7758
7710
7759
if (!is_guest_mode (vcpu ) && static_call (kvm_x86_get_cpl )(vcpu ) == 0 ) {
7711
- vcpu -> run -> exit_reason = KVM_EXIT_INTERNAL_ERROR ;
7712
- vcpu -> run -> internal .suberror = KVM_INTERNAL_ERROR_EMULATION ;
7713
- vcpu -> run -> internal .ndata = 0 ;
7760
+ prepare_emulation_ctxt_failure_exit (vcpu );
7714
7761
return 0 ;
7715
7762
}
7716
7763
@@ -12336,9 +12383,7 @@ int kvm_handle_memory_failure(struct kvm_vcpu *vcpu, int r,
12336
12383
* doesn't seem to be a real use-case behind such requests, just return
12337
12384
* KVM_EXIT_INTERNAL_ERROR for now.
12338
12385
*/
12339
- vcpu -> run -> exit_reason = KVM_EXIT_INTERNAL_ERROR ;
12340
- vcpu -> run -> internal .suberror = KVM_INTERNAL_ERROR_EMULATION ;
12341
- vcpu -> run -> internal .ndata = 0 ;
12386
+ kvm_prepare_emulation_failure_exit (vcpu );
12342
12387
12343
12388
return 0 ;
12344
12389
}
0 commit comments