|
@@ -1880,6 +1880,19 @@ static int clgi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
+static int invlpga_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
|
|
|
+{
|
|
|
+ struct kvm_vcpu *vcpu = &svm->vcpu;
|
|
|
+ nsvm_printk("INVLPGA\n");
|
|
|
+
|
|
|
+ /* Let's treat INVLPGA the same as INVLPG (can be optimized!) */
|
|
|
+ kvm_mmu_invlpg(vcpu, vcpu->arch.regs[VCPU_REGS_RAX]);
|
|
|
+
|
|
|
+ svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
|
|
|
+ skip_emulated_instruction(&svm->vcpu);
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
static int invalid_op_interception(struct vcpu_svm *svm,
|
|
|
struct kvm_run *kvm_run)
|
|
|
{
|
|
@@ -2227,7 +2240,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm,
|
|
|
[SVM_EXIT_INVD] = emulate_on_interception,
|
|
|
[SVM_EXIT_HLT] = halt_interception,
|
|
|
[SVM_EXIT_INVLPG] = invlpg_interception,
|
|
|
- [SVM_EXIT_INVLPGA] = invalid_op_interception,
|
|
|
+ [SVM_EXIT_INVLPGA] = invlpga_interception,
|
|
|
[SVM_EXIT_IOIO] = io_interception,
|
|
|
[SVM_EXIT_MSR] = msr_interception,
|
|
|
[SVM_EXIT_TASK_SWITCH] = task_switch_interception,
|