Received: by 2002:a05:6358:16cc:b0:ea:6187:17c9 with SMTP id r12csp1661098rwl; Thu, 5 Jan 2023 17:40:18 -0800 (PST) X-Google-Smtp-Source: AMrXdXuia2BU7w2ucKrtkVYEBlzbuukG12E577U5IJ0QsYhLnwv09vALtMw2CwkLOdgClLYYFRy/ X-Received: by 2002:a05:6a21:998a:b0:b0:1aa9:25bb with SMTP id ve10-20020a056a21998a00b000b01aa925bbmr83608319pzb.60.1672969218137; Thu, 05 Jan 2023 17:40:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672969218; cv=none; d=google.com; s=arc-20160816; b=tNg21fflhA8D78/gpF0xb403m0ngFtWRI1/8BcWSBaHIhbbGL/sm6/m8Ihw+UJsAQ9 HIReF4SRweVzzLJxq47bKm/VEUptPhYYCnnqIsXvURcqC4toZ98kque2y7RDI0//1duR C/Q9avO9uBR3gH1oOIs2Z04VorxUwgnjmE04sSBjvGA9LqA0daHab81+YGKKcApWIU4d BSisComRLmKJ+fMJMRfxAxLxrbo++c5xyIVvionsw5aCXqKsOliYY9MI4EyoB5wLIU1K nzAMGizttPwtfHJxgw6e3dkmbmp1R4Kzk8dEoT9MJjQvnyAKVOru+5A8Byu1dCvjBn77 iv3w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:reply-to:dkim-signature; bh=mau3/kl+h/eXbbhdIv+Q9nrr9eoqBg2GeLPH+58IXTM=; b=jYfFKU3fIIBJVroJWD8hHomlIXp7aooipzWfj8fB1xfT2SAOHEgClJuhmO01nzpIy9 31YmbJRh5DOrDxfnZBSe/i8Q2IchL2q9ujSh6sbqCbEc4IeNPRsBD7GLDzQaasbuIMJg mxWrTY5c+BUQKDBNo27SwTrLRbMWvzsxFt4yylC4J2tT1lqLVAOHViN1iGjR+JtkMLZ0 tPSpULLyYkyo7n9wUtQiD7dFMCwh6egqOGGPCba5UxaaXxQsxfCxHC3ooZzTY5L/QbTG QwEWk8PoM85aGpDTk6eAM7Yk9ajG5WhyXhHBArdhAd29OdMfZnsMvuXwG+tjbI+Hpijf WvhQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=MuWW2qpJ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id m14-20020a170902f64e00b001929101a655si27019112plg.248.2023.01.05.17.40.07; Thu, 05 Jan 2023 17:40:18 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=MuWW2qpJ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236874AbjAFBOH (ORCPT + 55 others); Thu, 5 Jan 2023 20:14:07 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37302 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236708AbjAFBN2 (ORCPT ); Thu, 5 Jan 2023 20:13:28 -0500 Received: from mail-pj1-x104a.google.com (mail-pj1-x104a.google.com [IPv6:2607:f8b0:4864:20::104a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4BA0F71FFF for ; Thu, 5 Jan 2023 17:13:27 -0800 (PST) Received: by mail-pj1-x104a.google.com with SMTP id r17-20020a17090aa09100b0021903e75f14so35032pjp.9 for ; Thu, 05 Jan 2023 17:13:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=mau3/kl+h/eXbbhdIv+Q9nrr9eoqBg2GeLPH+58IXTM=; b=MuWW2qpJuc98zl/fk2bBGCoFbQUn8ySbzjYk2e+aQt/pYvBHlalQf9JAEiYDfakLuC FPDKX6vcfTIEvyBDDFD3eqeJCy8L/kjshK79uiq9izQdHi4QTYdjVALwTSrPX5c31maW 6ocE9I3gWdUjBMlcCvPCCehjYDH8PfRDlnC3AofHAR1hg/KVKRDJgdXM/T8H/cjfLdYI soK+Cv8sVX/0oHlmt5ip06ahzTp52VL997D/yMr7mqIpFZsF/biOBOinhjpbNOMu3DWw ouGZbYzHIRGScKW38SoFVYKCoYqBQh4nxrCJtVpfWPOuPmbDZ8vAawybfCn0EVWkI2gu W3OQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=mau3/kl+h/eXbbhdIv+Q9nrr9eoqBg2GeLPH+58IXTM=; b=VeZv2kUOqc8ulfTtP5DLweRKTDr6UwZqk1pKd82D2V66zTAheMgyztYhoEVrq9uOEo hp9IqPQsQItyxflYPe+e3/4jMGuR+KZTo6chmt8vCmzIQBfDko5fydzomLiYtlz8XIQx +4ugz8jRsfwTQzau9846dXg8iokOm9zr7TjbOJulC5gOUgahaY6XmarQtwAyK+6W8cGT Av6tCNKXLmvSMbAzBsijvjVSlxekfW4dDiqVeckIEzPiB9/bX9iPuikrwmwuhX/aZsKi oypvy+LeJxl+VxHewsZ2aYaRBRNHHKkSc6Sd7D4ukwE4Plwh8g3zf+0IT4y/ZY65eWYX dLWQ== X-Gm-Message-State: AFqh2kqQe42ZjDYnZmY0sy4IcHuoHils7qq+kBgElYni5ikjD4eXCRV4 AFYbq+tny1wN4ImrHnn1JAB0GUCjz8A= X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a17:90a:fa49:b0:226:ce49:3df6 with SMTP id dt9-20020a17090afa4900b00226ce493df6mr249539pjb.61.1672967606965; Thu, 05 Jan 2023 17:13:26 -0800 (PST) Reply-To: Sean Christopherson Date: Fri, 6 Jan 2023 01:12:40 +0000 In-Reply-To: <20230106011306.85230-1-seanjc@google.com> Mime-Version: 1.0 References: <20230106011306.85230-1-seanjc@google.com> X-Mailer: git-send-email 2.39.0.314.g84b9a713c41-goog Message-ID: <20230106011306.85230-8-seanjc@google.com> Subject: [PATCH v5 07/33] KVM: SVM: Don't put/load AVIC when setting virtual APIC mode From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Alejandro Jimenez , Maxim Levitsky , Suravee Suthikulpanit , Li RongQing , Greg Edwards Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Move the VMCB updates from avic_refresh_apicv_exec_ctrl() into avic_set_virtual_apic_mode() and invert the dependency being said functions to avoid calling avic_vcpu_{load,put}() and avic_set_pi_irte_mode() when "only" setting the virtual APIC mode. avic_set_virtual_apic_mode() is invoked from common x86 with preemption enabled, which makes avic_vcpu_{load,put}() unhappy. Luckily, calling those and updating IRTE stuff is unnecessary as the only reason avic_set_virtual_apic_mode() is called is to handle transitions between xAPIC and x2APIC that don't also toggle APICv activation. And if activation doesn't change, there's no need to fiddle with the physical APIC ID table or update IRTE. The "full" refresh is guaranteed to be called if activation changes in this case as the only call to the "set" path is: kvm_vcpu_update_apicv(vcpu); static_call_cond(kvm_x86_set_virtual_apic_mode)(vcpu); and kvm_vcpu_update_apicv() invokes the refresh if activation changes: if (apic->apicv_active == activate) goto out; apic->apicv_active = activate; kvm_apic_update_apicv(vcpu); static_call(kvm_x86_refresh_apicv_exec_ctrl)(vcpu); Rename the helper to reflect that it is also called during "refresh". WARNING: CPU: 183 PID: 49186 at arch/x86/kvm/svm/avic.c:1081 avic_vcpu_put+0xde/0xf0 [kvm_amd] CPU: 183 PID: 49186 Comm: stable Tainted: G O 6.0.0-smp--fcddbca45f0a-sink #34 Hardware name: Google, Inc. Arcadia_IT_80/Arcadia_IT_80, BIOS 10.48.0 01/27/2022 RIP: 0010:avic_vcpu_put+0xde/0xf0 [kvm_amd] avic_refresh_apicv_exec_ctrl+0x142/0x1c0 [kvm_amd] avic_set_virtual_apic_mode+0x5a/0x70 [kvm_amd] kvm_lapic_set_base+0x149/0x1a0 [kvm] kvm_set_apic_base+0x8f/0xd0 [kvm] kvm_set_msr_common+0xa3a/0xdc0 [kvm] svm_set_msr+0x364/0x6b0 [kvm_amd] __kvm_set_msr+0xb8/0x1c0 [kvm] kvm_emulate_wrmsr+0x58/0x1d0 [kvm] msr_interception+0x1c/0x30 [kvm_amd] svm_invoke_exit_handler+0x31/0x100 [kvm_amd] svm_handle_exit+0xfc/0x160 [kvm_amd] vcpu_enter_guest+0x21bb/0x23e0 [kvm] vcpu_run+0x92/0x450 [kvm] kvm_arch_vcpu_ioctl_run+0x43e/0x6e0 [kvm] kvm_vcpu_ioctl+0x559/0x620 [kvm] Fixes: 05c4fe8c1bd9 ("KVM: SVM: Refresh AVIC configuration when changing APIC mode") Cc: stable@vger.kernel.org Cc: Suravee Suthikulpanit Reviewed-by: Maxim Levitsky Signed-off-by: Sean Christopherson --- arch/x86/kvm/svm/avic.c | 31 +++++++++++++++---------------- arch/x86/kvm/svm/svm.c | 2 +- arch/x86/kvm/svm/svm.h | 2 +- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c index 3b2c88b168ba..97ad0661f963 100644 --- a/arch/x86/kvm/svm/avic.c +++ b/arch/x86/kvm/svm/avic.c @@ -747,18 +747,6 @@ void avic_apicv_post_state_restore(struct kvm_vcpu *vcpu) avic_handle_ldr_update(vcpu); } -void avic_set_virtual_apic_mode(struct kvm_vcpu *vcpu) -{ - if (!lapic_in_kernel(vcpu) || avic_mode == AVIC_MODE_NONE) - return; - - if (kvm_get_apic_mode(vcpu) == LAPIC_MODE_INVALID) { - WARN_ONCE(true, "Invalid local APIC state (vcpu_id=%d)", vcpu->vcpu_id); - return; - } - avic_refresh_apicv_exec_ctrl(vcpu); -} - static int avic_set_pi_irte_mode(struct kvm_vcpu *vcpu, bool activate) { int ret = 0; @@ -1100,17 +1088,18 @@ void avic_vcpu_put(struct kvm_vcpu *vcpu) WRITE_ONCE(*(svm->avic_physical_id_cache), entry); } - -void avic_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu) +void avic_refresh_virtual_apic_mode(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); struct vmcb *vmcb = svm->vmcb01.ptr; - bool activated = kvm_vcpu_apicv_active(vcpu); + + if (!lapic_in_kernel(vcpu) || avic_mode == AVIC_MODE_NONE) + return; if (!enable_apicv) return; - if (activated) { + if (kvm_vcpu_apicv_active(vcpu)) { /** * During AVIC temporary deactivation, guest could update * APIC ID, DFR and LDR registers, which would not be trapped @@ -1124,6 +1113,16 @@ void avic_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu) avic_deactivate_vmcb(svm); } vmcb_mark_dirty(vmcb, VMCB_AVIC); +} + +void avic_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu) +{ + bool activated = kvm_vcpu_apicv_active(vcpu); + + if (!enable_apicv) + return; + + avic_refresh_virtual_apic_mode(vcpu); if (activated) avic_vcpu_load(vcpu, vcpu->cpu); diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 6ffadbd57744..26044e1d2422 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -4771,7 +4771,7 @@ static struct kvm_x86_ops svm_x86_ops __initdata = { .enable_nmi_window = svm_enable_nmi_window, .enable_irq_window = svm_enable_irq_window, .update_cr8_intercept = svm_update_cr8_intercept, - .set_virtual_apic_mode = avic_set_virtual_apic_mode, + .set_virtual_apic_mode = avic_refresh_virtual_apic_mode, .refresh_apicv_exec_ctrl = avic_refresh_apicv_exec_ctrl, .check_apicv_inhibit_reasons = avic_check_apicv_inhibit_reasons, .apicv_post_state_restore = avic_apicv_post_state_restore, diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index 4826e6cc611b..d0ed3f595229 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -648,7 +648,7 @@ void avic_vcpu_blocking(struct kvm_vcpu *vcpu); void avic_vcpu_unblocking(struct kvm_vcpu *vcpu); void avic_ring_doorbell(struct kvm_vcpu *vcpu); unsigned long avic_vcpu_get_apicv_inhibit_reasons(struct kvm_vcpu *vcpu); -void avic_set_virtual_apic_mode(struct kvm_vcpu *vcpu); +void avic_refresh_virtual_apic_mode(struct kvm_vcpu *vcpu); /* sev.c */ -- 2.39.0.314.g84b9a713c41-goog