Received: by 2002:a05:6a10:af89:0:0:0:0 with SMTP id iu9csp3668578pxb; Mon, 24 Jan 2022 14:56:07 -0800 (PST) X-Google-Smtp-Source: ABdhPJyf5VlPRKACOfTnBABjeZTaU6rpvceBKamlpB1B8/f6mj0HUgvC9WAYzuhWy+yATw/skZcn X-Received: by 2002:a17:90b:3b83:: with SMTP id pc3mr410652pjb.221.1643064966799; Mon, 24 Jan 2022 14:56:06 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1643064966; cv=none; d=google.com; s=arc-20160816; b=i/5XI893NefAyx58FE3LhhO6a+CheTCBxp8fJeUS9OqEDPVz1JVEX1CwxddO23ihZ3 saA0oX+ytsEk4aoylyVPWaBX8AD92gdELiUb/A4xM8gWo4AU9i1JHmjZbNta2qYjUv/b qtU8bEEXq+CyJ7HPcUGwF5kHGPgk/kkMqfEraAO5Z/FxT//ME5RgyLjHXOtR6tsajEQG BomaW88WX6eleKDYgVCS9FpTLEHCPQyBah387mGPqILP6yEPcZOmKUt/V4VhCTrCkpZS WGAr9P+YRMqsSaTIOMwTV5ECWkcygfyxPtDhxC1p3/vKeE3UzvF9HvCoW0AAuCccK98/ ZEMQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=+KsB0j+sxn7OvhBFXUz3gDQMwaUocUvGqSgqiegi41k=; b=Kqx5a4g5GzW8LlqIUcElpQno+YDuYXXlODqp69EhZH4dsJ/eq2oLNnE7+c/2CpsisQ pW2EgXnUWONDAAGkxovyXOzkFsf//26Ha11R4PMdFhq2coSAbJ+MB1dnK0s4dgRyftiF qgofFWtUT3YF3hLcyx4qGnzWtZ4xbyOJqaebnUdD9ToYblNJQvfkaFv0k2TzAhRbXIc/ 7Pfs/1mEaM6zioa6FAiTksuovI/5H/Etw6b186+NdilSHT97b0QZZD1iMetM7Jjipoog giL0tltYSROD0WbE2Sg6ZMWq9p6pdBTMNmefpRMCZNmhhM833tbOlZHPTIih3w1Va8cN LjPA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=DZ2b1LZ6; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id n12si12507816plc.233.2022.01.24.14.55.55; Mon, 24 Jan 2022 14:56:06 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=DZ2b1LZ6; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1840070AbiAXWwd (ORCPT + 99 others); Mon, 24 Jan 2022 17:52:33 -0500 Received: from ams.source.kernel.org ([145.40.68.75]:52686 "EHLO ams.source.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1573520AbiAXVpF (ORCPT ); Mon, 24 Jan 2022 16:45:05 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id B0E54B811A9; Mon, 24 Jan 2022 21:45:03 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id C6216C340E4; Mon, 24 Jan 2022 21:45:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1643060702; bh=oA0SrxgSf2DHn1f9C5JzgLmAYlmqZ8cXWCLRmdb5jC4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DZ2b1LZ6nOzTUqF7SoZ8nfn8dQg0gkRV/JK1FdrjtPN62WwJk6z9WtgLMtLiQeCYq tzftQnpVolJgZdtmW4jbExgs93q0DY7sywmyzj3hPoAO/yfIe4d3ap8FWouLlN3huT 1z1xqHRBm29f1Y60VlxQqarnOf1o+mCReTAj7mdw= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Greg Kroah-Hartman , Vitaly Kuznetsov , Paolo Bonzini Subject: [PATCH 5.16 1035/1039] KVM: selftests: Test KVM_SET_CPUID2 after KVM_RUN Date: Mon, 24 Jan 2022 19:47:04 +0100 Message-Id: <20220124184200.082019564@linuxfoundation.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220124184125.121143506@linuxfoundation.org> References: <20220124184125.121143506@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Vitaly Kuznetsov commit ecebb966acaab2466d9857d1cc435ee1fc9eee50 upstream. KVM forbids KVM_SET_CPUID2 after KVM_RUN was performed on a vCPU unless the supplied CPUID data is equal to what was previously set. Test this. Signed-off-by: Vitaly Kuznetsov Message-Id: <20220117150542.2176196-5-vkuznets@redhat.com> Signed-off-by: Paolo Bonzini Signed-off-by: Vitaly Kuznetsov Signed-off-by: Greg Kroah-Hartman --- tools/testing/selftests/kvm/include/x86_64/processor.h | 7 +++ tools/testing/selftests/kvm/lib/x86_64/processor.c | 33 ++++++++++++++--- tools/testing/selftests/kvm/x86_64/cpuid_test.c | 30 +++++++++++++++ 3 files changed, 66 insertions(+), 4 deletions(-) --- a/tools/testing/selftests/kvm/include/x86_64/processor.h +++ b/tools/testing/selftests/kvm/include/x86_64/processor.h @@ -358,6 +358,8 @@ uint64_t kvm_get_feature_msr(uint64_t ms struct kvm_cpuid2 *kvm_get_supported_cpuid(void); struct kvm_cpuid2 *vcpu_get_cpuid(struct kvm_vm *vm, uint32_t vcpuid); +int __vcpu_set_cpuid(struct kvm_vm *vm, uint32_t vcpuid, + struct kvm_cpuid2 *cpuid); void vcpu_set_cpuid(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_cpuid2 *cpuid); @@ -402,6 +404,11 @@ void vm_set_page_table_entry(struct kvm_ uint64_t pte); /* + * get_cpuid() - find matching CPUID entry and return pointer to it. + */ +struct kvm_cpuid_entry2 *get_cpuid(struct kvm_cpuid2 *cpuid, uint32_t function, + uint32_t index); +/* * set_cpuid() - overwrites a matching cpuid entry with the provided value. * matches based on ent->function && ent->index. returns true * if a match was found and successfully overwritten. --- a/tools/testing/selftests/kvm/lib/x86_64/processor.c +++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c @@ -847,6 +847,17 @@ kvm_get_supported_cpuid_index(uint32_t f return entry; } + +int __vcpu_set_cpuid(struct kvm_vm *vm, uint32_t vcpuid, + struct kvm_cpuid2 *cpuid) +{ + struct vcpu *vcpu = vcpu_find(vm, vcpuid); + + TEST_ASSERT(vcpu != NULL, "vcpu not found, vcpuid: %u", vcpuid); + + return ioctl(vcpu->fd, KVM_SET_CPUID2, cpuid); +} + /* * VM VCPU CPUID Set * @@ -864,12 +875,9 @@ kvm_get_supported_cpuid_index(uint32_t f void vcpu_set_cpuid(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_cpuid2 *cpuid) { - struct vcpu *vcpu = vcpu_find(vm, vcpuid); int rc; - TEST_ASSERT(vcpu != NULL, "vcpu not found, vcpuid: %u", vcpuid); - - rc = ioctl(vcpu->fd, KVM_SET_CPUID2, cpuid); + rc = __vcpu_set_cpuid(vm, vcpuid, cpuid); TEST_ASSERT(rc == 0, "KVM_SET_CPUID2 failed, rc: %i errno: %i", rc, errno); @@ -1337,6 +1345,23 @@ void assert_on_unhandled_exception(struc } } +struct kvm_cpuid_entry2 *get_cpuid(struct kvm_cpuid2 *cpuid, uint32_t function, + uint32_t index) +{ + int i; + + for (i = 0; i < cpuid->nent; i++) { + struct kvm_cpuid_entry2 *cur = &cpuid->entries[i]; + + if (cur->function == function && cur->index == index) + return cur; + } + + TEST_FAIL("CPUID function 0x%x index 0x%x not found ", function, index); + + return NULL; +} + bool set_cpuid(struct kvm_cpuid2 *cpuid, struct kvm_cpuid_entry2 *ent) { --- a/tools/testing/selftests/kvm/x86_64/cpuid_test.c +++ b/tools/testing/selftests/kvm/x86_64/cpuid_test.c @@ -154,6 +154,34 @@ struct kvm_cpuid2 *vcpu_alloc_cpuid(stru return guest_cpuids; } +static void set_cpuid_after_run(struct kvm_vm *vm, struct kvm_cpuid2 *cpuid) +{ + struct kvm_cpuid_entry2 *ent; + int rc; + u32 eax, ebx, x; + + /* Setting unmodified CPUID is allowed */ + rc = __vcpu_set_cpuid(vm, VCPU_ID, cpuid); + TEST_ASSERT(!rc, "Setting unmodified CPUID after KVM_RUN failed: %d", rc); + + /* Changing CPU features is forbidden */ + ent = get_cpuid(cpuid, 0x7, 0); + ebx = ent->ebx; + ent->ebx--; + rc = __vcpu_set_cpuid(vm, VCPU_ID, cpuid); + TEST_ASSERT(rc, "Changing CPU features should fail"); + ent->ebx = ebx; + + /* Changing MAXPHYADDR is forbidden */ + ent = get_cpuid(cpuid, 0x80000008, 0); + eax = ent->eax; + x = eax & 0xff; + ent->eax = (eax & ~0xffu) | (x - 1); + rc = __vcpu_set_cpuid(vm, VCPU_ID, cpuid); + TEST_ASSERT(rc, "Changing MAXPHYADDR should fail"); + ent->eax = eax; +} + int main(void) { struct kvm_cpuid2 *supp_cpuid, *cpuid2; @@ -175,5 +203,7 @@ int main(void) for (stage = 0; stage < 3; stage++) run_vcpu(vm, VCPU_ID, stage); + set_cpuid_after_run(vm, cpuid2); + kvm_vm_free(vm); }