Merge branch 'misc.namei' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[linux-2.6-microblaze.git] / arch / x86 / kvm / svm / avic.c
index 5e7e920..8052d92 100644 (file)
 #include "irq.h"
 #include "svm.h"
 
-/* enable / disable AVIC */
-bool avic;
-module_param(avic, bool, S_IRUGO);
-
 #define SVM_AVIC_DOORBELL      0xc001011b
 
 #define AVIC_HPA_MASK  ~((0xFFFULL << 52) | 0xFFF)
@@ -124,7 +120,7 @@ void avic_vm_destroy(struct kvm *kvm)
        unsigned long flags;
        struct kvm_svm *kvm_svm = to_kvm_svm(kvm);
 
-       if (!avic)
+       if (!enable_apicv)
                return;
 
        if (kvm_svm->avic_logical_id_table_page)
@@ -147,7 +143,7 @@ int avic_vm_init(struct kvm *kvm)
        struct page *l_page;
        u32 vm_id;
 
-       if (!avic)
+       if (!enable_apicv)
                return 0;
 
        /* Allocating physical APIC ID table (4KB) */
@@ -201,6 +197,8 @@ void avic_init_vmcb(struct vcpu_svm *svm)
        vmcb->control.avic_logical_id = lpa & AVIC_HPA_MASK;
        vmcb->control.avic_physical_id = ppa & AVIC_HPA_MASK;
        vmcb->control.avic_physical_id |= AVIC_MAX_PHYSICAL_ID_COUNT;
+       vmcb->control.avic_vapic_bar = APIC_DEFAULT_PHYS_BASE & VMCB_AVIC_APIC_BAR_MASK;
+
        if (kvm_apicv_activated(svm->vcpu.kvm))
                vmcb->control.int_ctl |= AVIC_ENABLE_MASK;
        else
@@ -229,31 +227,26 @@ static u64 *avic_get_physical_id_entry(struct kvm_vcpu *vcpu,
  * field of the VMCB. Therefore, we set up the
  * APIC_ACCESS_PAGE_PRIVATE_MEMSLOT (4KB) here.
  */
-static int avic_update_access_page(struct kvm *kvm, bool activate)
+static int avic_alloc_access_page(struct kvm *kvm)
 {
        void __user *ret;
        int r = 0;
 
        mutex_lock(&kvm->slots_lock);
-       /*
-        * During kvm_destroy_vm(), kvm_pit_set_reinject() could trigger
-        * APICv mode change, which update APIC_ACCESS_PAGE_PRIVATE_MEMSLOT
-        * memory region. So, we need to ensure that kvm->mm == current->mm.
-        */
-       if ((kvm->arch.apic_access_page_done == activate) ||
-           (kvm->mm != current->mm))
+
+       if (kvm->arch.apic_access_memslot_enabled)
                goto out;
 
        ret = __x86_set_memory_region(kvm,
                                      APIC_ACCESS_PAGE_PRIVATE_MEMSLOT,
                                      APIC_DEFAULT_PHYS_BASE,
-                                     activate ? PAGE_SIZE : 0);
+                                     PAGE_SIZE);
        if (IS_ERR(ret)) {
                r = PTR_ERR(ret);
                goto out;
        }
 
-       kvm->arch.apic_access_page_done = activate;
+       kvm->arch.apic_access_memslot_enabled = true;
 out:
        mutex_unlock(&kvm->slots_lock);
        return r;
@@ -274,7 +267,7 @@ static int avic_init_backing_page(struct kvm_vcpu *vcpu)
        if (kvm_apicv_activated(vcpu->kvm)) {
                int ret;
 
-               ret = avic_update_access_page(vcpu->kvm, true);
+               ret = avic_alloc_access_page(vcpu->kvm);
                if (ret)
                        return ret;
        }
@@ -569,7 +562,7 @@ int avic_init_vcpu(struct vcpu_svm *svm)
        int ret;
        struct kvm_vcpu *vcpu = &svm->vcpu;
 
-       if (!avic || !irqchip_in_kernel(vcpu->kvm))
+       if (!enable_apicv || !irqchip_in_kernel(vcpu->kvm))
                return 0;
 
        ret = avic_init_backing_page(vcpu);
@@ -591,17 +584,6 @@ void avic_post_state_restore(struct kvm_vcpu *vcpu)
        avic_handle_ldr_update(vcpu);
 }
 
-void svm_toggle_avic_for_irq_window(struct kvm_vcpu *vcpu, bool activate)
-{
-       if (!avic || !lapic_in_kernel(vcpu))
-               return;
-
-       srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
-       kvm_request_apicv_update(vcpu->kvm, activate,
-                                APICV_INHIBIT_REASON_IRQWIN);
-       vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
-}
-
 void svm_set_virtual_apic_mode(struct kvm_vcpu *vcpu)
 {
        return;
@@ -650,10 +632,10 @@ out:
 void svm_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
-       struct vmcb *vmcb = svm->vmcb;
+       struct vmcb *vmcb = svm->vmcb01.ptr;
        bool activated = kvm_vcpu_apicv_active(vcpu);
 
-       if (!avic)
+       if (!enable_apicv)
                return;
 
        if (activated) {
@@ -671,6 +653,11 @@ void svm_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu)
        }
        vmcb_mark_dirty(vmcb, VMCB_AVIC);
 
+       if (activated)
+               avic_vcpu_load(vcpu, vcpu->cpu);
+       else
+               avic_vcpu_put(vcpu);
+
        svm_set_pi_irte_mode(vcpu, activated);
 }
 
@@ -922,10 +909,6 @@ bool svm_check_apicv_inhibit_reasons(ulong bit)
        return supported & BIT(bit);
 }
 
-void svm_pre_update_apicv_exec_ctrl(struct kvm *kvm, bool activate)
-{
-       avic_update_access_page(kvm, activate);
-}
 
 static inline int
 avic_update_iommu_vcpu_affinity(struct kvm_vcpu *vcpu, int cpu, bool r)
@@ -964,9 +947,6 @@ void avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
        int h_physical_id = kvm_cpu_get_apicid(cpu);
        struct vcpu_svm *svm = to_svm(vcpu);
 
-       if (!kvm_vcpu_apicv_active(vcpu))
-               return;
-
        /*
         * Since the host physical APIC id is 8 bits,
         * we can support host APIC ID upto 255.
@@ -994,9 +974,6 @@ void avic_vcpu_put(struct kvm_vcpu *vcpu)
        u64 entry;
        struct vcpu_svm *svm = to_svm(vcpu);
 
-       if (!kvm_vcpu_apicv_active(vcpu))
-               return;
-
        entry = READ_ONCE(*(svm->avic_physical_id_cache));
        if (entry & AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK)
                avic_update_iommu_vcpu_affinity(vcpu, -1, 0);
@@ -1013,6 +990,10 @@ static void avic_set_running(struct kvm_vcpu *vcpu, bool is_run)
        struct vcpu_svm *svm = to_svm(vcpu);
 
        svm->avic_is_running = is_run;
+
+       if (!kvm_vcpu_apicv_active(vcpu))
+               return;
+
        if (is_run)
                avic_vcpu_load(vcpu, vcpu->cpu);
        else