Received: by 2002:a05:6a10:6d10:0:0:0:0 with SMTP id gq16csp356349pxb; Tue, 12 Apr 2022 03:38:58 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyV5sbrPWpU0WAy2GQlNNmaLoURNG4NF2e3slZo3vtC9oIrZ2G+n3GKT/5WNg6x/8b+RdhV X-Received: by 2002:a17:907:960f:b0:6e8:8df9:ce3a with SMTP id gb15-20020a170907960f00b006e88df9ce3amr9037990ejc.211.1649759938473; Tue, 12 Apr 2022 03:38:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1649759938; cv=none; d=google.com; s=arc-20160816; b=r6UIko0JN8Wvoi9qqpqjHKC/Up/KeRpVhL3dWEWg+HgtYltLV1aupDO1cfX0bhQcdS gRvvmmJt0iNp2y8TV7jGj7pe+GzRvAE3/qhdR5Bho9g57W/mRbI5a5G6K1uxmQCkp8U2 TA2mq546rbApZUg302yBAcaCjVOeBNUNCV/1X8KsKwqn8F5AA2bcPDmyq0rKoch5TeYF 81zxwqFMbm43sI9bZL0pwQJVLvcqNh1G5tyGVlhExryEj5xWpDZ9MIvaQC7sKR9HlN6o 8urn1M98ubPaK+lq5LeWtNh6+pPZvWRr4/J2K+u/xm76qZb8ATVvbZH9y4vx0EzScMDD 0kgw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from:dkim-signature; bh=QFD8pmjf8CqKaTO1PyVD0XtwHtr8tlRtwMx9hMErVyM=; b=BwQX9uaE7Ahi9FsTfKUXSHcDcyB0eaXrtUm5as+ZHT2tpeQ1Ya2atpbSkc+qZFb76X qWxXEekfY1KNSN8+8LGT6O1Sfm938sBc1eQgYwNTwC6pBL+RAorOn0Cxm43vaBFcpUxB Qf9jkYoBBrk6vIIGXpWrbST2Z04Z1e5f4n2J/rEYnNiYx49XsmPpLGz4M+htr8ylqxId r0AaV5fm4nIwYLQeE/oM8hUKZtvvn4RV0bIs4h3bhSijuKnTUfNAhg2rC4MSms5KSvqO Oht2pZ6d9LD2m0ei7ymxj3YpN/mLurcbn9IbmTxJmMk42k/oeA5WSgt2nesjjaWAklYZ cF/A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b="DBy/3LuS"; 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=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b9-20020a50be89000000b00418edac76afsi9340141edk.280.2022.04.12.03.38.33; Tue, 12 Apr 2022 03:38:58 -0700 (PDT) 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=@intel.com header.s=Intel header.b="DBy/3LuS"; 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=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344620AbiDKJjq (ORCPT + 99 others); Mon, 11 Apr 2022 05:39:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38414 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344576AbiDKJjg (ORCPT ); Mon, 11 Apr 2022 05:39:36 -0400 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 83594403E7; Mon, 11 Apr 2022 02:37:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1649669836; x=1681205836; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=Ac+Tj+oOHnMDyhI2NE6QYoSazPkEr2C+i7OWolZUv+E=; b=DBy/3LuSo6LwUrj+IYYXRksJa1LAi5N/ejBlIYgk+hlobRdPWxAFB4lF YM1WD4j/Yt1ZYli7SIAWEtXEhkhq8B1mi3F7iMJj4efUMPIn3eP0L53R1 OwcndjDjGxEwPl9Cq9/eFwqCHOGP6pidxteXf4sFSGKjKx9Bvrvlhmf9i Otjw2yfKNBJGaeKEIGXgSM6EmJuv9bSe1mR87CyNjgylsOPUXx8ncTUVQ Vb8EepWUluiz56CnhfCY6Y+SaDvdy9aSyBDLRZ64GNUA3x/ZHC8SNSFPD hl3esKEuRQDFCpKI8kbH/8K5gIIGvgUxaAoiTBFkS/2fpcegJdHS765ob g==; X-IronPort-AV: E=McAfee;i="6400,9594,10313"; a="243960657" X-IronPort-AV: E=Sophos;i="5.90,251,1643702400"; d="scan'208";a="243960657" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Apr 2022 02:37:15 -0700 X-IronPort-AV: E=Sophos;i="5.90,251,1643702400"; d="scan'208";a="572050604" Received: from arthur-vostro-3668.sh.intel.com ([10.239.13.120]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Apr 2022 02:37:09 -0700 From: Zeng Guang To: Paolo Bonzini , Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, Dave Hansen , Tony Luck , Kan Liang , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" , Kim Phillips , Jarkko Sakkinen , Jethro Beekman , Kai Huang Cc: x86@kernel.org, linux-kernel@vger.kernel.org, Robert Hu , Gao Chao , Zeng Guang Subject: [PATCH v8 8/9] KVM: x86: Allow userspace set maximum VCPU id for VM Date: Mon, 11 Apr 2022 17:04:46 +0800 Message-Id: <20220411090447.5928-9-guang.zeng@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220411090447.5928-1-guang.zeng@intel.com> References: <20220411090447.5928-1-guang.zeng@intel.com> X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_NONE,T_SCC_BODY_TEXT_LINE 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 Introduce new max_vcpu_ids in KVM for x86 architecture. Userspace can assign maximum possible vcpu id for current VM session using KVM_CAP_MAX_VCPU_ID of KVM_ENABLE_CAP ioctl(). This is done for x86 only because the sole use case is to guide memory allocation for PID-pointer table, a structure needed to enable VMX IPI. By default, max_vcpu_ids set as KVM_MAX_VCPU_IDS. Suggested-by: Sean Christopherson Reviewed-by: Maxim Levitsky Signed-off-by: Zeng Guang --- Documentation/virt/kvm/api.rst | 17 +++++++++++++++++ arch/x86/include/asm/kvm_host.h | 6 ++++++ arch/x86/kvm/x86.c | 18 +++++++++++++++++- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index d13fa6600467..bb0b0f3edefe 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -7136,6 +7136,23 @@ The valid bits in cap.args[0] are: IA32_MISC_ENABLE[bit 18] is cleared. =================================== ============================================ +7.32 KVM_CAP_MAX_VCPU_ID +------------------------ + +:Architectures: x86 +:Target: VM +:Parameters: args[0] - maximum APIC ID value set for current VM +:Returns: 0 on success, -EINVAL if args[0] is beyond KVM_MAX_VCPU_IDS + supported in KVM or if vCPU has been created. + +Userspace is able to calculate the limit to APIC ID values from designated CPU +topology. This capability allows userspace to specify maximum possible APIC ID +assigned for current VM session prior to the creation of vCPUs. KVM can manage +memory allocation of VM-scope structures which depends on the value of APIC ID. + +Calling KVM_CHECK_EXTENSION for this capability returns the value of maximum APIC +ID that KVM supports at runtime. It sets as KVM_MAX_VCPU_IDS in VM initialization. + 8. Other capabilities. ====================== diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index d23e80a56eb8..cdd14033988d 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1238,6 +1238,12 @@ struct kvm_arch { hpa_t hv_root_tdp; spinlock_t hv_root_tdp_lock; #endif + /* + * VM-scope maximum vCPU ID. Used to determine the size of structures + * that increase along with the maximum vCPU ID, in which case, using + * the global KVM_MAX_VCPU_IDS may lead to significant memory waste. + */ + u32 max_vcpu_ids; }; struct kvm_vm_stat { diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 0c0ca599a353..d1a39285deab 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4320,7 +4320,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) r = KVM_MAX_VCPUS; break; case KVM_CAP_MAX_VCPU_ID: - r = KVM_MAX_VCPU_IDS; + r = kvm->arch.max_vcpu_ids; break; case KVM_CAP_PV_MMU: /* obsolete */ r = 0; @@ -6064,6 +6064,18 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, } mutex_unlock(&kvm->lock); break; + case KVM_CAP_MAX_VCPU_ID: + r = -EINVAL; + if (cap->args[0] > KVM_MAX_VCPU_IDS) + break; + + mutex_lock(&kvm->lock); + if (!kvm->created_vcpus) { + kvm->arch.max_vcpu_ids = cap->args[0]; + r = 0; + } + mutex_unlock(&kvm->lock); + break; default: r = -EINVAL; break; @@ -11180,6 +11192,9 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) struct page *page; int r; + if (vcpu->vcpu_id >= vcpu->kvm->arch.max_vcpu_ids) + return -EINVAL; + vcpu->arch.last_vmentry_cpu = -1; vcpu->arch.regs_avail = ~0; vcpu->arch.regs_dirty = ~0; @@ -11704,6 +11719,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) spin_lock_init(&kvm->arch.hv_root_tdp_lock); kvm->arch.hv_root_tdp = INVALID_PAGE; #endif + kvm->arch.max_vcpu_ids = KVM_MAX_VCPU_IDS; INIT_DELAYED_WORK(&kvm->arch.kvmclock_update_work, kvmclock_update_fn); INIT_DELAYED_WORK(&kvm->arch.kvmclock_sync_work, kvmclock_sync_fn); -- 2.27.0