]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
KVM: SVM: Implement INVLPGA
authorAlexander Graf <agraf@suse.de>
Mon, 15 Jun 2009 13:21:24 +0000 (15:21 +0200)
committerAvi Kivity <avi@redhat.com>
Thu, 10 Sep 2009 05:32:58 +0000 (08:32 +0300)
SVM adds another way to do INVLPG by ASID which Hyper-V makes use of,
so let's implement it!

For now we just do the same thing invlpg does, as asid switching
means we flush the mmu anyways. That might change one day though.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Avi Kivity <avi@redhat.com>
arch/x86/kvm/svm.c

index 146c17d406edcc04dd7ceb859db35659c8a72701..be699795d70f48d2038a7c7d9a3aad45c1a16578 100644 (file)
@@ -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,