Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp3123670rwb; Wed, 30 Nov 2022 15:56:57 -0800 (PST) X-Google-Smtp-Source: AA0mqf7463RhPbpQwADoXmhYQx/Ct0WlFPpMqPl9ol7+gzZ6h0rktLTOGjFde05Sq6pAS8ymP6up X-Received: by 2002:a17:906:fa98:b0:7c0:a8ff:3380 with SMTP id lt24-20020a170906fa9800b007c0a8ff3380mr2091536ejb.92.1669852617779; Wed, 30 Nov 2022 15:56:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669852617; cv=none; d=google.com; s=arc-20160816; b=InoLjY9FSQAZ02a45IE+EDSlI8Ud6xxcYlWqdKLGLiQaZe6LC3q18vN9uvX1LR3k3J FGiqcc6TuId1EHquWnDFvASbWblXvFUSR4QiIimZNHlJrbHLtSTIaX2Aky11l5FprUOH d5gDMmSTcLEoEMzKgjKDnJB7QJ0BSU3vyOy6qcrgdHpPoP4hihoUNQFPHD0n3Kl19+oP V/JjKghgkNqLDPiLmn5C9XG9G+X78IrlC+WVy4pllT71uXytVTnIp+A9vWlA23BHcLzK E+TRLK2uaMpF2/T0lPuQG1ZXPTZq+HZCO785HhJItttrtDYUzMHQre3KiYywhGuTtlE4 wcWQ== 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=WLPEY1JyVUKovgrvfyqFU2AVSMCiclyJ+2DT9qhmJc8=; b=XwNKwAzvnQSFCvC9l69+/0T22sNkBFhGakRrCmjiEB7oQNzv990r9fGb4bXAegC357 JhpCZu8q4QUrtns+fyu1hxarcU7srZSLlraKcbnvHFC32w3/XCqRw3ROiLzC8Qfzbu8e d+nT5qGF7G3l9wA50AcUnTUeL6yVypZExw4dA1qvfeVruZFe0dfn2ihPm5xcasDZeyrI 02+0cmNAjgjBCtDD5uVv/Im6kvpSEf3TKAUm91Yl6qxIzICEdlz8IMsOJZWRyivGA8X8 DiDXp0pqQEzCOc9zBsgpRcdunh/cHErO4Ukk2IHROoJu3m2GQs4F1jGOjDN30ppCoG+X eyBA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=D8YRDQ8z; 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 i7-20020aa7c707000000b004612915d1a0si2359905edq.507.2022.11.30.15.56.37; Wed, 30 Nov 2022 15:56:57 -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=D8YRDQ8z; 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 S230128AbiK3XRk (ORCPT + 83 others); Wed, 30 Nov 2022 18:17:40 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60016 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230172AbiK3XQS (ORCPT ); Wed, 30 Nov 2022 18:16:18 -0500 Received: from mail-pl1-x649.google.com (mail-pl1-x649.google.com [IPv6:2607:f8b0:4864:20::649]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6053E77430 for ; Wed, 30 Nov 2022 15:11:49 -0800 (PST) Received: by mail-pl1-x649.google.com with SMTP id o8-20020a170902d4c800b001898ea5e030so11315363plg.13 for ; Wed, 30 Nov 2022 15:11:48 -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=WLPEY1JyVUKovgrvfyqFU2AVSMCiclyJ+2DT9qhmJc8=; b=D8YRDQ8ziUXauvBx+ARbm7TFIG8K7whjxR1q1N+cb/wQeXeKfhINWzhaARQHkNtQ4Q /IkiRc+iCBcbWjdykCUjCkjfmBOkEmyXXZuqZ+gft9hkrhkkdMqanjtrg4ALTxlHbAys XyZFW4WpGejE/dbUyxR5jHE+duvddzg3otAhdocqYEFE0BojJYcMyB6GyJtaNLxkOiTS 6/HoCl1WQ1OC+nYzecGGIZN2fe3pbBkzvUu82a2MomMsooPz9zdPN9UTgK+KQHWv7U8y 6le7VvNBnrJaTj35gdwc23Q+wETCAHgYr/YFnbP1YFNzrxVi7lomowBDPcjY/WZjR0nW ur1w== 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=WLPEY1JyVUKovgrvfyqFU2AVSMCiclyJ+2DT9qhmJc8=; b=lxMpZZdErPx+4hzUwN5hdk7gSkL6XbTdon828Ok8/oAibMSV83lt5lu0KMoNQPHySC GzdKWbR3jRCkF87I/f61naPHt2HePU2tdJECuXSaKe1TJMKziC9lEv2Yg1HmVVkYM+H7 hJyoCMesrwUzSqTj1UlxBFh//Q5j+eTjDC3DLFhBFGhqAbd19u1Q26bIT3s06oGTDdT8 boWAYKWw92ZRRXWjRaUv9iDP70NyLrczlGJmuS2lqUxAp9sMouyuPHWIDpAAcug8lUy8 bMNIaaNemY/stM24PSEfdXECjSvS6kOMriginAH7XnQMps+KQzD1EObhiJ7NN40KfKWk Equg== X-Gm-Message-State: ANoB5plVKW27TnJjIkNX/cXAUJMGgk5L9Di3ro9p9DTXrXW0x6fjgvY8 5qPl3NWO/kftshAy+lMRNMC+TIhvWT0= X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:aa7:9ec2:0:b0:574:8995:eb7f with SMTP id r2-20020aa79ec2000000b005748995eb7fmr33643125pfq.85.1669849859262; Wed, 30 Nov 2022 15:10:59 -0800 (PST) Reply-To: Sean Christopherson Date: Wed, 30 Nov 2022 23:09:31 +0000 In-Reply-To: <20221130230934.1014142-1-seanjc@google.com> Mime-Version: 1.0 References: <20221130230934.1014142-1-seanjc@google.com> X-Mailer: git-send-email 2.38.1.584.g0f3c55d4c2-goog Message-ID: <20221130230934.1014142-48-seanjc@google.com> Subject: [PATCH v2 47/50] KVM: Make hardware_enable_failed a local variable in the "enable all" path From: Sean Christopherson To: Paolo Bonzini , Marc Zyngier , Huacai Chen , Aleksandar Markovic , Anup Patel , Paul Walmsley , Palmer Dabbelt , Albert Ou , Christian Borntraeger , Janosch Frank , Claudio Imbrenda , Matthew Rosato , Eric Farman , Sean Christopherson , Vitaly Kuznetsov , David Woodhouse , Paul Durrant Cc: James Morse , Alexandru Elisei , Suzuki K Poulose , Oliver Upton , Atish Patra , David Hildenbrand , kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, kvmarm@lists.cs.columbia.edu, linux-mips@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org, linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org, Yuan Yao , Cornelia Huck , Isaku Yamahata , "=?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?=" , Fabiano Rosas , Michael Ellerman , Kai Huang , Chao Gao , Thomas Gleixner 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 From: Isaku Yamahata Rework detecting hardware enabling errors to use a local variable in the "enable all" path to track whether or not enabling was successful across all CPUs. Using a global variable complicates paths that enable hardware only on the current CPU, e.g. kvm_resume() and kvm_online_cpu(). Opportunistically add a WARN if hardware enabling fails during kvm_resume(), KVM is all kinds of hosed if CPU0 fails to enable hardware. The WARN is largely futile in the current code, as KVM BUG()s on spurious faults on VMX instructions, e.g. attempting to run a vCPU on CPU if hardware enabling fails will explode. ------------[ cut here ]------------ kernel BUG at arch/x86/kvm/x86.c:508! invalid opcode: 0000 [#1] SMP CPU: 3 PID: 1009 Comm: CPU 4/KVM Not tainted 6.1.0-rc1+ #11 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 RIP: 0010:kvm_spurious_fault+0xa/0x10 Call Trace: vmx_vcpu_load_vmcs+0x192/0x230 [kvm_intel] vmx_vcpu_load+0x16/0x60 [kvm_intel] kvm_arch_vcpu_load+0x32/0x1f0 vcpu_load+0x2f/0x40 kvm_arch_vcpu_ioctl_run+0x19/0x9d0 kvm_vcpu_ioctl+0x271/0x660 __x64_sys_ioctl+0x80/0xb0 do_syscall_64+0x2b/0x50 entry_SYSCALL_64_after_hwframe+0x46/0xb0 But, the WARN may provide a breadcrumb to understand what went awry, and someday KVM may fix one or both of those bugs, e.g. by finding a way to eat spurious faults no matter the context (easier said than done due to side effects of certain operations, e.g. Intel's VMCLEAR). Signed-off-by: Isaku Yamahata [sean: rebase, WARN on failure in kvm_resume()] Signed-off-by: Sean Christopherson --- virt/kvm/kvm_main.c | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index c1e48c18e2d9..674a9dab5411 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -104,7 +104,6 @@ LIST_HEAD(vm_list); static DEFINE_PER_CPU(bool, hardware_enabled); static int kvm_usage_count; -static atomic_t hardware_enable_failed; static struct kmem_cache *kvm_vcpu_cache; @@ -5025,19 +5024,25 @@ static struct miscdevice kvm_dev = { &kvm_chardev_ops, }; -static void hardware_enable_nolock(void *junk) +static int __hardware_enable_nolock(void) { if (__this_cpu_read(hardware_enabled)) - return; + return 0; if (kvm_arch_hardware_enable()) { - atomic_inc(&hardware_enable_failed); pr_info("kvm: enabling virtualization on CPU%d failed\n", raw_smp_processor_id()); - return; + return -EIO; } __this_cpu_write(hardware_enabled, true); + return 0; +} + +static void hardware_enable_nolock(void *failed) +{ + if (__hardware_enable_nolock()) + atomic_inc(failed); } static int kvm_online_cpu(unsigned int cpu) @@ -5050,16 +5055,8 @@ static int kvm_online_cpu(unsigned int cpu) * errors when scheduled to this CPU. */ mutex_lock(&kvm_lock); - if (kvm_usage_count) { - WARN_ON_ONCE(atomic_read(&hardware_enable_failed)); - - hardware_enable_nolock(NULL); - - if (atomic_read(&hardware_enable_failed)) { - atomic_set(&hardware_enable_failed, 0); - ret = -EIO; - } - } + if (kvm_usage_count) + ret = __hardware_enable_nolock(); mutex_unlock(&kvm_lock); return ret; } @@ -5107,6 +5104,7 @@ static void hardware_disable_all(void) static int hardware_enable_all(void) { + atomic_t failed = ATOMIC_INIT(0); int r = 0; /* @@ -5122,10 +5120,9 @@ static int hardware_enable_all(void) kvm_usage_count++; if (kvm_usage_count == 1) { - atomic_set(&hardware_enable_failed, 0); - on_each_cpu(hardware_enable_nolock, NULL, 1); + on_each_cpu(hardware_enable_nolock, &failed, 1); - if (atomic_read(&hardware_enable_failed)) { + if (atomic_read(&failed)) { hardware_disable_all_nolock(); r = -EBUSY; } @@ -5759,7 +5756,7 @@ static void kvm_resume(void) lockdep_assert_irqs_disabled(); if (kvm_usage_count) - hardware_enable_nolock(NULL); + WARN_ON_ONCE(__hardware_enable_nolock()); } static struct syscore_ops kvm_syscore_ops = { -- 2.38.1.584.g0f3c55d4c2-goog