From patchwork Tue Mar 30 18:58:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Emanuele Giuseppe Esposito X-Patchwork-Id: 12173575 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 37594C433C1 for ; Tue, 30 Mar 2021 18:59:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EC9D66196A for ; Tue, 30 Mar 2021 18:59:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232965AbhC3S7J (ORCPT ); Tue, 30 Mar 2021 14:59:09 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:32919 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232968AbhC3S67 (ORCPT ); Tue, 30 Mar 2021 14:58:59 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1617130738; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=aPc+rabAZpzxBvkEBQsdws4dCgLq8Pb5mtjSkAQD3So=; b=ciGiYcZwJuzQN0RQJQzvG0GXSNDLa0GLDZ4sUC0LXJ8GPhXYC43CU2vjvEWHy6fxEqVobl MAR6g6eYg50MxxL19SzJeAdNUgmT0HQdouboPZgq+goUTRHUmykAalElgTbpdTJxCvZArs q8z5fIjDyg80wYgeajOGqkQv/iYjen8= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-285-gAWCBbpRMLS2c762orwA8w-1; Tue, 30 Mar 2021 14:58:57 -0400 X-MC-Unique: gAWCBbpRMLS2c762orwA8w-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 5CD2B8030A1; Tue, 30 Mar 2021 18:58:55 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-112-41.ams2.redhat.com [10.36.112.41]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3CEF819C44; Tue, 30 Mar 2021 18:58:50 +0000 (UTC) From: Emanuele Giuseppe Esposito To: kvm@vger.kernel.org Cc: Paolo Bonzini , Jonathan Corbet , Sean Christopherson , Vitaly Kuznetsov , Jim Mattson , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" , Shuah Khan , Alexander Graf , Andrew Jones , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH 1/4] kvm: cpuid: adjust the returned nent field of kvm_cpuid2 for KVM_GET_SUPPORTED_CPUID and KVM_GET_EMULATED_CPUID Date: Tue, 30 Mar 2021 20:58:38 +0200 Message-Id: <20210330185841.44792-2-eesposit@redhat.com> In-Reply-To: <20210330185841.44792-1-eesposit@redhat.com> References: <20210330185841.44792-1-eesposit@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Calling the kvm KVM_GET_[SUPPORTED/EMULATED]_CPUID ioctl requires a nent field inside the kvm_cpuid2 struct to be big enough to contain all entries that will be set by kvm. Therefore if the nent field is too high, kvm will adjust it to the right value. If too low, -E2BIG is returned. However, when filling the entries do_cpuid_func() requires an additional entry, so if the right nent is known in advance, giving the exact number of entries won't work because it has to be increased by one. Signed-off-by: Emanuele Giuseppe Esposito --- arch/x86/kvm/cpuid.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 6bd2f8b830e4..5412b48b9103 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -975,6 +975,12 @@ int kvm_dev_ioctl_get_cpuid(struct kvm_cpuid2 *cpuid, if (cpuid->nent < 1) return -E2BIG; + + /* if there are X entries, we need to allocate at least X+1 + * entries but return the actual number of entries + */ + cpuid->nent++; + if (cpuid->nent > KVM_MAX_CPUID_ENTRIES) cpuid->nent = KVM_MAX_CPUID_ENTRIES; From patchwork Tue Mar 30 18:58:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Emanuele Giuseppe Esposito X-Patchwork-Id: 12173577 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C6E66C433E3 for ; Tue, 30 Mar 2021 18:59:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A3E2A61985 for ; Tue, 30 Mar 2021 18:59:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232985AbhC3S7K (ORCPT ); Tue, 30 Mar 2021 14:59:10 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:21364 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232973AbhC3S7G (ORCPT ); Tue, 30 Mar 2021 14:59:06 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1617130746; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=i9iBaLNrNdHy5Myw5Ru7jrMYIVd0xBvqef8GrfatpKg=; b=GftTuSjMhBXLkFcwu1yDKIQcoVItt/KC1HAN9FvZsmXbOrb8hPJ0t1Ut9MU0V2ltgNLReo duSrwDefIVFFzsWGIO8mKJH0s07YNP1um94aYXpfSuz/gPS6r056vQgGkTUXc7UcWs/woO ob1TdxFTdDut4nchx1a6IvJHUjX3Lxs= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-571-fdhN6NBVMuyp-UEVFAw1iw-1; Tue, 30 Mar 2021 14:59:04 -0400 X-MC-Unique: fdhN6NBVMuyp-UEVFAw1iw-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 0FBE18030BB; Tue, 30 Mar 2021 18:59:02 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-112-41.ams2.redhat.com [10.36.112.41]) by smtp.corp.redhat.com (Postfix) with ESMTP id C468719C44; Tue, 30 Mar 2021 18:58:56 +0000 (UTC) From: Emanuele Giuseppe Esposito To: kvm@vger.kernel.org Cc: Paolo Bonzini , Jonathan Corbet , Sean Christopherson , Vitaly Kuznetsov , Jim Mattson , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" , Shuah Khan , Alexander Graf , Andrew Jones , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH 2/4] Documentation: kvm: update KVM_GET_EMULATED_CPUID ioctl description Date: Tue, 30 Mar 2021 20:58:39 +0200 Message-Id: <20210330185841.44792-3-eesposit@redhat.com> In-Reply-To: <20210330185841.44792-1-eesposit@redhat.com> References: <20210330185841.44792-1-eesposit@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org KVM_GET_EMULATED_CPUID returns -E2BIG if the nent field of struct kvm_cpuid2 is smaller than the actual entries, while it adjusts nent if the provided amount is bigger than the actual amount. Update documentation accordingly. ENOMEM is just returned if the allocation fails, like all other calls. Signed-off-by: Emanuele Giuseppe Esposito --- Documentation/virt/kvm/api.rst | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 307f2fcf1b02..8ba23bc2a625 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -3404,12 +3404,10 @@ which features are emulated by kvm instead of being present natively. Userspace invokes KVM_GET_EMULATED_CPUID by passing a kvm_cpuid2 structure with the 'nent' field indicating the number of entries in -the variable-size array 'entries'. If the number of entries is too low -to describe the cpu capabilities, an error (E2BIG) is returned. If the -number is too high, the 'nent' field is adjusted and an error (ENOMEM) -is returned. If the number is just right, the 'nent' field is adjusted -to the number of valid entries in the 'entries' array, which is then -filled. +the variable-size array 'entries'. +If the number of entries is too low to describe the cpu +capabilities, an error (E2BIG) is returned. If the number is too high, +the 'nent' field is adjusted and the entries array is filled. The entries returned are the set CPUID bits of the respective features which kvm emulates, as returned by the CPUID instruction, with unknown From patchwork Tue Mar 30 18:58:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Emanuele Giuseppe Esposito X-Patchwork-Id: 12173581 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 37E16C433E3 for ; Tue, 30 Mar 2021 19:00:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EE24261985 for ; Tue, 30 Mar 2021 19:00:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233024AbhC3S7m (ORCPT ); Tue, 30 Mar 2021 14:59:42 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:29487 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232986AbhC3S7L (ORCPT ); Tue, 30 Mar 2021 14:59:11 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1617130750; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=84Zr99k/BLMEUkVeh+jVwwXBIWqAlip0+t5vxhNu95E=; b=d+KyKqUL06jb2RaMNVBUQ1VpDv87vpDxv9bmyyKrom5xeZ31IDrOti19/GIVitehErdpgn z/UN3qef2D1+HSLb7tkI2ggmqMzNJWuT1r19Bd4gb4UYp/eK+6vuq9KXuw6a3N6PAxtq7J bWwMondrPp76a31wlMlM6rdE1oedN3c= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-78-mqI_QNfmOumQG9reoZ_7yA-1; Tue, 30 Mar 2021 14:59:08 -0400 X-MC-Unique: mqI_QNfmOumQG9reoZ_7yA-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D3D5F911E3; Tue, 30 Mar 2021 18:59:06 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-112-41.ams2.redhat.com [10.36.112.41]) by smtp.corp.redhat.com (Postfix) with ESMTP id 826F019C44; Tue, 30 Mar 2021 18:59:02 +0000 (UTC) From: Emanuele Giuseppe Esposito To: kvm@vger.kernel.org Cc: Paolo Bonzini , Jonathan Corbet , Sean Christopherson , Vitaly Kuznetsov , Jim Mattson , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" , Shuah Khan , Alexander Graf , Andrew Jones , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH 3/4] selftests: add kvm_get_emulated_cpuid Date: Tue, 30 Mar 2021 20:58:40 +0200 Message-Id: <20210330185841.44792-4-eesposit@redhat.com> In-Reply-To: <20210330185841.44792-1-eesposit@redhat.com> References: <20210330185841.44792-1-eesposit@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org As the similar kvm_get_supported_cpuid, allocates and gets the struct kvm_cpuid2 filled with emulated features. Signed-off-by: Emanuele Giuseppe Esposito --- .../selftests/kvm/include/x86_64/processor.h | 1 + .../selftests/kvm/lib/x86_64/processor.c | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h b/tools/testing/selftests/kvm/include/x86_64/processor.h index 0b30b4e15c38..ae1b9530e187 100644 --- a/tools/testing/selftests/kvm/include/x86_64/processor.h +++ b/tools/testing/selftests/kvm/include/x86_64/processor.h @@ -353,6 +353,7 @@ void vcpu_load_state(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_msr_list *kvm_get_msr_index_list(void); uint64_t kvm_get_feature_msr(uint64_t msr_index); struct kvm_cpuid2 *kvm_get_supported_cpuid(void); +struct kvm_cpuid2 *kvm_get_emulated_cpuid(void); struct kvm_cpuid2 *vcpu_get_cpuid(struct kvm_vm *vm, uint32_t vcpuid); void vcpu_set_cpuid(struct kvm_vm *vm, uint32_t vcpuid, diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c index e676fe40bfe6..2ea14421bdfe 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/processor.c +++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c @@ -669,6 +669,39 @@ struct kvm_cpuid2 *kvm_get_supported_cpuid(void) return cpuid; } +/* + * KVM Emulated CPUID Get + * + * Input Args: None + * + * Output Args: + * + * Return: The emulated KVM CPUID + * + * Get the guest CPUID emulated by KVM. + */ +struct kvm_cpuid2 *kvm_get_emulated_cpuid(void) +{ + static struct kvm_cpuid2 *cpuid; + int ret; + int kvm_fd; + + if (cpuid) + return cpuid; + + cpuid = allocate_kvm_cpuid2(); + kvm_fd = open(KVM_DEV_PATH, O_RDONLY); + if (kvm_fd < 0) + exit(KSFT_SKIP); + + ret = ioctl(kvm_fd, KVM_GET_EMULATED_CPUID, cpuid); + TEST_ASSERT(ret == 0, "KVM_GET_EMULATED_CPUID failed %d %d\n", + ret, errno); + + close(kvm_fd); + return cpuid; +} + /* * KVM Get MSR * From patchwork Tue Mar 30 18:58:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Emanuele Giuseppe Esposito X-Patchwork-Id: 12173583 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 70F4CC433E2 for ; Tue, 30 Mar 2021 19:00:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 50D3C619C2 for ; Tue, 30 Mar 2021 19:00:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233043AbhC3S7o (ORCPT ); Tue, 30 Mar 2021 14:59:44 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:28393 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232972AbhC3S7S (ORCPT ); Tue, 30 Mar 2021 14:59:18 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1617130758; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9rovFwqHnWbHsNU90FkcQMMDk//e8S7lckbsm+eNrNY=; b=PLdkNGEETAZKPXFVvyE0369d35T2/4ry7feLPT691paqoZPgzFIeariUAa0+G3VU/ou1E9 nLsvER09Ca0a+M/s6J+QpcrG1H4veSpTC3Va3GYG4hzEgIEb//NX5mDfalx9fEh+rPMQUk eDG5u6KmOYGXw7EHVpoNwLNqWC2iXRk= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-427-qdOTxoRKPayrOKdSUkE8gA-1; Tue, 30 Mar 2021 14:59:13 -0400 X-MC-Unique: qdOTxoRKPayrOKdSUkE8gA-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id BB721911E2; Tue, 30 Mar 2021 18:59:11 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-112-41.ams2.redhat.com [10.36.112.41]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5B8B519C44; Tue, 30 Mar 2021 18:59:07 +0000 (UTC) From: Emanuele Giuseppe Esposito To: kvm@vger.kernel.org Cc: Paolo Bonzini , Jonathan Corbet , Sean Christopherson , Vitaly Kuznetsov , Jim Mattson , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" , Shuah Khan , Alexander Graf , Andrew Jones , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH 4/4] selftests: kvm: add get_emulated_cpuid test Date: Tue, 30 Mar 2021 20:58:41 +0200 Message-Id: <20210330185841.44792-5-eesposit@redhat.com> In-Reply-To: <20210330185841.44792-1-eesposit@redhat.com> References: <20210330185841.44792-1-eesposit@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Introduce a new selftest for the KVM_GET_EMULATED_CPUID ioctl. Since the behavior and functionality is similar to get_cpuid_test, the test checks: 1) checks for corner case in the nent field of the struct kvm_cpuid2. 2) sets and gets it as cpuid from the guest VM Signed-off-by: Emanuele Giuseppe Esposito --- tools/testing/selftests/kvm/.gitignore | 1 + tools/testing/selftests/kvm/Makefile | 1 + .../selftests/kvm/x86_64/get_emulated_cpuid.c | 183 ++++++++++++++++++ 3 files changed, 185 insertions(+) create mode 100644 tools/testing/selftests/kvm/x86_64/get_emulated_cpuid.c diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore index 7bd7e776c266..f1523f3bfd04 100644 --- a/tools/testing/selftests/kvm/.gitignore +++ b/tools/testing/selftests/kvm/.gitignore @@ -8,6 +8,7 @@ /x86_64/debug_regs /x86_64/evmcs_test /x86_64/get_cpuid_test +x86_64/get_emulated_cpuid /x86_64/get_msr_index_features /x86_64/kvm_pv_test /x86_64/hyperv_clock diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index 67eebb53235f..0d8d3bd5a7c7 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -40,6 +40,7 @@ LIBKVM_s390x = lib/s390x/processor.c lib/s390x/ucall.c lib/s390x/diag318_test_ha TEST_GEN_PROGS_x86_64 = x86_64/cr4_cpuid_sync_test TEST_GEN_PROGS_x86_64 += x86_64/get_msr_index_features +TEST_GEN_PROGS_x86_64 += x86_64/get_emulated_cpuid TEST_GEN_PROGS_x86_64 += x86_64/evmcs_test TEST_GEN_PROGS_x86_64 += x86_64/get_cpuid_test TEST_GEN_PROGS_x86_64 += x86_64/hyperv_clock diff --git a/tools/testing/selftests/kvm/x86_64/get_emulated_cpuid.c b/tools/testing/selftests/kvm/x86_64/get_emulated_cpuid.c new file mode 100644 index 000000000000..f5294dc4b8ff --- /dev/null +++ b/tools/testing/selftests/kvm/x86_64/get_emulated_cpuid.c @@ -0,0 +1,183 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2021, Red Hat Inc. + * + * Generic tests for KVM CPUID set/get ioctls + */ +#include +#include +#include + +#include "test_util.h" +#include "kvm_util.h" +#include "processor.h" + +#define VCPU_ID 0 +#define MAX_NENT 1000 + +/* CPUIDs known to differ */ +struct { + u32 function; + u32 index; +} mangled_cpuids[] = { + {.function = 0xd, .index = 0}, +}; + +static void guest_main(void) +{ + +} + +static bool is_cpuid_mangled(struct kvm_cpuid_entry2 *entrie) +{ + int i; + + for (i = 0; i < sizeof(mangled_cpuids); i++) { + if (mangled_cpuids[i].function == entrie->function && + mangled_cpuids[i].index == entrie->index) + return true; + } + + return false; +} + +static void check_cpuid(struct kvm_cpuid2 *cpuid, struct kvm_cpuid_entry2 *entrie) +{ + int i; + + for (i = 0; i < cpuid->nent; i++) { + if (cpuid->entries[i].function == entrie->function && + cpuid->entries[i].index == entrie->index) { + if (is_cpuid_mangled(entrie)) + return; + + TEST_ASSERT(cpuid->entries[i].eax == entrie->eax && + cpuid->entries[i].ebx == entrie->ebx && + cpuid->entries[i].ecx == entrie->ecx && + cpuid->entries[i].edx == entrie->edx, + "CPUID 0x%x.%x differ: 0x%x:0x%x:0x%x:0x%x vs 0x%x:0x%x:0x%x:0x%x", + entrie->function, entrie->index, + cpuid->entries[i].eax, cpuid->entries[i].ebx, + cpuid->entries[i].ecx, cpuid->entries[i].edx, + entrie->eax, entrie->ebx, entrie->ecx, entrie->edx); + return; + } + } + + TEST_ASSERT(false, "CPUID 0x%x.%x not found", entrie->function, entrie->index); +} + +static void compare_cpuids(struct kvm_cpuid2 *cpuid1, + struct kvm_cpuid2 *cpuid2) +{ + int i; + + for (i = 0; i < cpuid1->nent; i++) + check_cpuid(cpuid2, &cpuid1->entries[i]); + + for (i = 0; i < cpuid2->nent; i++) + check_cpuid(cpuid1, &cpuid2->entries[i]); +} + +struct kvm_cpuid2 *vcpu_alloc_cpuid(struct kvm_vm *vm, vm_vaddr_t *p_gva, struct kvm_cpuid2 *cpuid) +{ + int size = sizeof(*cpuid) + cpuid->nent * sizeof(cpuid->entries[0]); + vm_vaddr_t gva = vm_vaddr_alloc(vm, size, + getpagesize(), 0, 0); + struct kvm_cpuid2 *guest_cpuids = addr_gva2hva(vm, gva); + + memcpy(guest_cpuids, cpuid, size); + + *p_gva = gva; + return guest_cpuids; +} + +static struct kvm_cpuid2 *alloc_custom_kvm_cpuid2(int nent) +{ + struct kvm_cpuid2 *cpuid; + size_t size; + + size = sizeof(*cpuid); + size += nent * sizeof(struct kvm_cpuid_entry2); + cpuid = calloc(1, size); + if (!cpuid) { + perror("malloc"); + abort(); + } + + cpuid->nent = nent; + + return cpuid; +} + +static void test_emulated_entries(struct kvm_vm *vm) +{ + int res, right_nent; + struct kvm_cpuid2 *cpuid; + + cpuid = alloc_custom_kvm_cpuid2(MAX_NENT); + + /* 0 nent, return E2BIG */ + cpuid->nent = 0; + res = _kvm_ioctl(vm, KVM_GET_EMULATED_CPUID, cpuid); + TEST_ASSERT(res == -1 && errno == E2BIG, + "KVM_GET_EMULATED_CPUID should fail E2BIG with nent=0"); + + /* high nent, set the entries and adjust */ + cpuid->nent = MAX_NENT; + res = _kvm_ioctl(vm, KVM_GET_EMULATED_CPUID, cpuid); + printf("%d %d\n", res, errno); + TEST_ASSERT(res == 0, + "KVM_GET_EMULATED_CPUID should not fail with nent > actual nent"); + right_nent = cpuid->nent; + + /* high nent, set the entries and adjust */ + cpuid->nent++; + res = _kvm_ioctl(vm, KVM_GET_EMULATED_CPUID, cpuid); + TEST_ASSERT(res == 0, + "KVM_GET_EMULATED_CPUID should not fail with nent > actual nent"); + TEST_ASSERT(right_nent == cpuid->nent, + "KVM_GET_EMULATED_CPUID nent should be always the same"); + + /* low nent, return E2BIG */ + if (right_nent > 1) { + cpuid->nent = 1; + res = _kvm_ioctl(vm, KVM_GET_EMULATED_CPUID, cpuid); + TEST_ASSERT(res == -1 && errno == E2BIG, + "KVM_GET_EMULATED_CPUID should fail with nent=1"); + } + + /* exact nent */ + cpuid->nent = right_nent; + res = _kvm_ioctl(vm, KVM_GET_EMULATED_CPUID, cpuid); + TEST_ASSERT(res == 0, + "KVM_GET_EMULATED_CPUID should not fail with nent == actual nent"); + TEST_ASSERT(cpuid->nent == right_nent, + "KVM_GET_EMULATED_CPUID should be invaried when nent is exact"); + + free(cpuid); +} + +// emulated is all emulated +// supported is only hw + kvm +int main(void) +{ + struct kvm_cpuid2 *emul_cpuid, *cpuid2; + struct kvm_vm *vm; + + if (!kvm_check_cap(KVM_CAP_EXT_EMUL_CPUID)) { + print_skip("KVM_GET_EMULATED_CPUID not available"); + return 0; + } + + vm = vm_create_default(VCPU_ID, 0, guest_main); + + emul_cpuid = kvm_get_emulated_cpuid(); + vcpu_set_cpuid(vm, VCPU_ID, emul_cpuid); + cpuid2 = vcpu_get_cpuid(vm, VCPU_ID); + + test_emulated_entries(vm); + compare_cpuids(emul_cpuid, cpuid2); + + kvm_vm_free(vm); +}