Merge tag 'kvm-x86-selftests-6.6' of https://github.com/kvm-x86/linux into HEAD
[platform/kernel/linux-rpi.git] / arch / x86 / kvm / x86.c
index 0145d84..94fa36e 100644 (file)
@@ -906,6 +906,22 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
 }
 EXPORT_SYMBOL_GPL(load_pdptrs);
 
+static bool kvm_is_valid_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
+{
+#ifdef CONFIG_X86_64
+       if (cr0 & 0xffffffff00000000UL)
+               return false;
+#endif
+
+       if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD))
+               return false;
+
+       if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE))
+               return false;
+
+       return static_call(kvm_x86_is_valid_cr0)(vcpu, cr0);
+}
+
 void kvm_post_set_cr0(struct kvm_vcpu *vcpu, unsigned long old_cr0, unsigned long cr0)
 {
        /*
@@ -952,20 +968,13 @@ int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
 {
        unsigned long old_cr0 = kvm_read_cr0(vcpu);
 
-       cr0 |= X86_CR0_ET;
-
-#ifdef CONFIG_X86_64
-       if (cr0 & 0xffffffff00000000UL)
+       if (!kvm_is_valid_cr0(vcpu, cr0))
                return 1;
-#endif
-
-       cr0 &= ~CR0_RESERVED_BITS;
 
-       if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD))
-               return 1;
+       cr0 |= X86_CR0_ET;
 
-       if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE))
-               return 1;
+       /* Write to CR0 reserved bits are ignored, even on Intel. */
+       cr0 &= ~CR0_RESERVED_BITS;
 
 #ifdef CONFIG_X86_64
        if ((vcpu->arch.efer & EFER_LME) && !is_paging(vcpu) &&
@@ -1607,7 +1616,7 @@ static bool kvm_is_immutable_feature_msr(u32 msr)
         ARCH_CAP_SKIP_VMENTRY_L1DFLUSH | ARCH_CAP_SSB_NO | ARCH_CAP_MDS_NO | \
         ARCH_CAP_PSCHANGE_MC_NO | ARCH_CAP_TSX_CTRL_MSR | ARCH_CAP_TAA_NO | \
         ARCH_CAP_SBDR_SSDP_NO | ARCH_CAP_FBSDP_NO | ARCH_CAP_PSDP_NO | \
-        ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO)
+        ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO | ARCH_CAP_GDS_NO)
 
 static u64 kvm_get_arch_capabilities(void)
 {
@@ -1664,6 +1673,9 @@ static u64 kvm_get_arch_capabilities(void)
                 */
        }
 
+       if (!boot_cpu_has_bug(X86_BUG_GDS) || gds_ucode_mitigated())
+               data |= ARCH_CAP_GDS_NO;
+
        return data;
 }
 
@@ -2172,6 +2184,8 @@ fastpath_t handle_fastpath_set_msr_irqoff(struct kvm_vcpu *vcpu)
        u64 data;
        fastpath_t ret = EXIT_FASTPATH_NONE;
 
+       kvm_vcpu_srcu_read_lock(vcpu);
+
        switch (msr) {
        case APIC_BASE_MSR + (APIC_ICR >> 4):
                data = kvm_read_edx_eax(vcpu);
@@ -2194,6 +2208,8 @@ fastpath_t handle_fastpath_set_msr_irqoff(struct kvm_vcpu *vcpu)
        if (ret != EXIT_FASTPATH_NONE)
                trace_kvm_msr_write(msr, data);
 
+       kvm_vcpu_srcu_read_unlock(vcpu);
+
        return ret;
 }
 EXPORT_SYMBOL_GPL(handle_fastpath_set_msr_irqoff);
@@ -10203,9 +10219,13 @@ static int kvm_check_and_inject_events(struct kvm_vcpu *vcpu,
                if (r < 0)
                        goto out;
                if (r) {
-                       kvm_queue_interrupt(vcpu, kvm_cpu_get_interrupt(vcpu), false);
-                       static_call(kvm_x86_inject_irq)(vcpu, false);
-                       WARN_ON(static_call(kvm_x86_interrupt_allowed)(vcpu, true) < 0);
+                       int irq = kvm_cpu_get_interrupt(vcpu);
+
+                       if (!WARN_ON_ONCE(irq == -1)) {
+                               kvm_queue_interrupt(vcpu, irq, false);
+                               static_call(kvm_x86_inject_irq)(vcpu, false);
+                               WARN_ON(static_call(kvm_x86_interrupt_allowed)(vcpu, true) < 0);
+                       }
                }
                if (kvm_cpu_has_injectable_intr(vcpu))
                        static_call(kvm_x86_enable_irq_window)(vcpu);
@@ -11460,7 +11480,8 @@ static bool kvm_is_valid_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
                        return false;
        }
 
-       return kvm_is_valid_cr4(vcpu, sregs->cr4);
+       return kvm_is_valid_cr4(vcpu, sregs->cr4) &&
+              kvm_is_valid_cr0(vcpu, sregs->cr0);
 }
 
 static int __set_sregs_common(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs,
@@ -12758,7 +12779,7 @@ static void kvm_mmu_slot_apply_flags(struct kvm *kvm,
                 * See is_writable_pte() for more details (the case involving
                 * access-tracked SPTEs is particularly relevant).
                 */
-               kvm_arch_flush_remote_tlbs_memslot(kvm, new);
+               kvm_flush_remote_tlbs_memslot(kvm, new);
        }
 }
 
@@ -13192,7 +13213,7 @@ EXPORT_SYMBOL_GPL(kvm_arch_has_noncoherent_dma);
 
 bool kvm_arch_has_irq_bypass(void)
 {
-       return true;
+       return enable_apicv && irq_remapping_cap(IRQ_POSTING_CAP);
 }
 
 int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons,