From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 81688C6FD1F for ; Thu, 21 Mar 2024 23:40:50 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id EC90A6B0088; Thu, 21 Mar 2024 19:40:49 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id E7A666B008A; Thu, 21 Mar 2024 19:40:49 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id D41116B008C; Thu, 21 Mar 2024 19:40:49 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0017.hostedemail.com [216.40.44.17]) by kanga.kvack.org (Postfix) with ESMTP id C10EF6B0088 for ; Thu, 21 Mar 2024 19:40:49 -0400 (EDT) Received: from smtpin19.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay03.hostedemail.com (Postfix) with ESMTP id 6E6EFA0490 for ; Thu, 21 Mar 2024 23:40:49 +0000 (UTC) X-FDA: 81922668618.19.8D1759E Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.20]) by imf20.hostedemail.com (Postfix) with ESMTP id 036151C0012 for ; Thu, 21 Mar 2024 23:40:46 +0000 (UTC) Authentication-Results: imf20.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b=a3kGJGSX; dmarc=pass (policy=none) header.from=intel.com; spf=pass (imf20.hostedemail.com: domain of dongsheng.x.zhang@intel.com designates 198.175.65.20 as permitted sender) smtp.mailfrom=dongsheng.x.zhang@intel.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1711064447; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=x66mfbmADULql2WPDLuoe3lbFrTcEsN00WdULJH38qg=; b=yr4ps8csnr2b4vDU7EJyqjIvxQibOLNhZ6hA0ZckZ40lGd83Y0hVU2nr6ajXTwKj0n+zf7 5sd+h1jj+jcEeKozLmwXq1lUWRxgN6HL1e2P/1ia5UJ18I09MvxT7yQm0qp5kZzV0jJcrP 5BTetJ4VFiCSbGXc5zid420BBL3qFTE= ARC-Authentication-Results: i=1; imf20.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b=a3kGJGSX; dmarc=pass (policy=none) header.from=intel.com; spf=pass (imf20.hostedemail.com: domain of dongsheng.x.zhang@intel.com designates 198.175.65.20 as permitted sender) smtp.mailfrom=dongsheng.x.zhang@intel.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1711064447; a=rsa-sha256; cv=none; b=O8Qu/S+uGfvSf8qjKoPdX9D+Sxg5JoiCVZ4sqOaN4OMmBzwfSiAki0o1KP0NmgL/TKTUuX Rfnf7Se/4Cwg3RGZkjENvY4tktaYwGLm9OfnSyQWd5arcTxlpaJiNYuQYPTZXNJKt3Xd4D oGrUy2SvzGnqAVLz5Ad3f9whWwk3D54= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1711064448; x=1742600448; h=message-id:date:mime-version:subject:to:cc:references: from:in-reply-to:content-transfer-encoding; bh=lmPYeGS+4lUFLmzt/61FUNZFXKxXzVkv+EU4SNg+F+g=; b=a3kGJGSXwEOcsEf+JUHhFDh+++tEmWk5xi+4tOpKMb7XnkCb3J43nJAc SWb+5rPVG+t0O2jK6YAl1KhWV6wJj9cDJGoUy4I6g8quqbq+GUtijMnBb sbelnqvbo0T9PdU35kZrPtO+JnIduVsNq4YvxfDZsrUbQsik265XPXjc0 qPBeD52ocYBHh0dvAOCJdlGoTfgSYv5r3sL6poJJa+i5ifGy8NpnAvk/a TRbnwjysrs6da34BQ//eoZV7mZsPthlFgw2+5DYtcJoCdZM6HJ1JnmLFc TEYzfzgpomK04yIcJ0sW3P57Gz98eV3kevE5j4hqwydRDT7sM4jqHTJFd w==; X-IronPort-AV: E=McAfee;i="6600,9927,11020"; a="5989910" X-IronPort-AV: E=Sophos;i="6.07,144,1708416000"; d="scan'208";a="5989910" Received: from orviesa009.jf.intel.com ([10.64.159.149]) by orvoesa112.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Mar 2024 16:40:46 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,144,1708416000"; d="scan'208";a="14687751" Received: from dongshen-mobl1.amr.corp.intel.com (HELO [10.212.116.150]) ([10.212.116.150]) by orviesa009-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Mar 2024 16:40:45 -0700 Message-ID: Date: Thu, 21 Mar 2024 16:40:44 -0700 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [RFC PATCH v5 15/29] KVM: selftests: TDX: Add TDX MSR read/write tests To: Sagi Shahar , linux-kselftest@vger.kernel.org, Ackerley Tng , Ryan Afranji , Erdem Aktas , Isaku Yamahata Cc: Sean Christopherson , Paolo Bonzini , Shuah Khan , Peter Gonda , Haibo Xu , Chao Peng , Vishal Annapurve , Roger Wang , Vipin Sharma , jmattson@google.com, dmatlack@google.com, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-mm@kvack.org References: <20231212204647.2170650-1-sagis@google.com> <20231212204647.2170650-16-sagis@google.com> Content-Language: en-US From: "Zhang, Dongsheng X" In-Reply-To: <20231212204647.2170650-16-sagis@google.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Rspamd-Queue-Id: 036151C0012 X-Rspam-User: X-Rspamd-Server: rspam04 X-Stat-Signature: r7qqyck7kewcyccthsz8ot68cmndmjie X-HE-Tag: 1711064446-575498 X-HE-Meta: U2FsdGVkX185iC8MrspL2JdMBsHnKDHS0IFZ2abgn4pvoBoT7AnAYPdmIa4kFyMXgWAeXsBz7frPfS5tt9np/BZV0IRDVkpsgUKHFKtxBwETGhE4o7mZ6k/kR9WsAX2AUzErdb8hhPRSG9gW3+5aA+YSpVcRLqpnrnS71xcwcTDvKiPB1t7Pfs4XtMzCemmRnnl7uq2DvU3+5LX1FE/zUfL0ITIe2ztlKwP7wCZtXT6IW6H7XaJOP9bnIN5l5ojCKc+diS+MJjBAOVH7rD3X1A3YQ+FRak5IBrzEv7gULWpLvB9uqMCimugkEJ1CbWKWKXnE6/i0EfQVctVs4LBGz/AhZ6v2w1KQxJ7ZHNR/tXxlbgzFH/KMjNi9wrDCKRJ9cO97mKyQ6OK+8vMGAOFy0pcTf0i6NW6jlkOoqI6fio39b9KSc6+3zhdXnxayT5k24ngqqR5lblX3TjDIOLs+TwKxUhQJHOwf2K+SgHUrgKBED6MZ4wkaFVzBH1924xlLaXJ3WHHMhxWpUQ3PK6XA9JbHB9UCab9x4LihCGZjxy0o5EIe0WhQ4rWR5KNCndMz+qaTy4Eo5IjAW5aO+cRiNq/Cq1HuxYkbZYydjaI1afI48srP+qOn6DqaYsjPD2UHQWCU7vbwTxGBi9mc0XZqxwjG3qiVGdDwWTQDy9j6/VmpXJh2V4Dz5wda6XdUBGwUd9q0LmnbrpUmArnDbkyPvAFHrHJK865yTu0TgQPXficenou/wsuDE4nogsBWwGkSHXrC2pdOMnUSDbGcmn5ymeIRWh6dWv6oiTo8xaZDmJ3uOKLNg9H4/86JGHyhcs0zVYpp3mh1YSEasz0rmad9t6fO7Oay+e05kwXdMn2t//GA4s+Xdj5vVlPsgCU8LHFh/EZ/i8g+A//9fPQO+zJl15awAM8MV/n1CpPyLBd59GaSLts9vSYG0C14F4I5qy5OtQKBZS37TgOtLK3ZnTS TqF+dPX8 ls3UocjfPR15oEBo3NtcHTPx4Pr+zg/DyX0ebcIBPT3SPQTAasMUOm9S1sT/yfGANJIJspYl4yQ2pSNlvLM0Nwyacq9F7S+P15ja59+5/j3LZMaFSx9cTeHE/v9K7Oi9n6EVkdnstSqKBwTAtnksb0yqWnOZ44UAtMRaHZnGY/H9085i2oUhb/qJzXR4duHOQWX+/XBFVwaG55ew= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: On 12/12/2023 12:46 PM, Sagi Shahar wrote: > The test verifies reads and writes for MSR registers with different access > level. > > Signed-off-by: Sagi Shahar > Signed-off-by: Ackerley Tng > Signed-off-by: Ryan Afranji > --- > .../selftests/kvm/include/x86_64/tdx/tdx.h | 5 + > .../selftests/kvm/lib/x86_64/tdx/tdx.c | 27 +++ > .../selftests/kvm/x86_64/tdx_vm_tests.c | 209 ++++++++++++++++++ > 3 files changed, 241 insertions(+) > > diff --git a/tools/testing/selftests/kvm/include/x86_64/tdx/tdx.h b/tools/testing/selftests/kvm/include/x86_64/tdx/tdx.h > index 63788012bf94..85ba6aab79a7 100644 > --- a/tools/testing/selftests/kvm/include/x86_64/tdx/tdx.h > +++ b/tools/testing/selftests/kvm/include/x86_64/tdx/tdx.h > @@ -9,11 +9,16 @@ > #define TDG_VP_VMCALL_REPORT_FATAL_ERROR 0x10003 > > #define TDG_VP_VMCALL_INSTRUCTION_IO 30 > +#define TDG_VP_VMCALL_INSTRUCTION_RDMSR 31 > +#define TDG_VP_VMCALL_INSTRUCTION_WRMSR 32 Nit: "arch/x86/include/uapi/asm/vmx.h" already defined the following defs: #define EXIT_REASON_IO_INSTRUCTION 30 #define EXIT_REASON_MSR_READ 31 #define EXIT_REASON_MSR_WRITE 32 > + > void handle_userspace_tdg_vp_vmcall_exit(struct kvm_vcpu *vcpu); > uint64_t tdg_vp_vmcall_instruction_io(uint64_t port, uint64_t size, > uint64_t write, uint64_t *data); > void tdg_vp_vmcall_report_fatal_error(uint64_t error_code, uint64_t data_gpa); > uint64_t tdg_vp_vmcall_get_td_vmcall_info(uint64_t *r11, uint64_t *r12, > uint64_t *r13, uint64_t *r14); > +uint64_t tdg_vp_vmcall_instruction_rdmsr(uint64_t index, uint64_t *ret_value); > +uint64_t tdg_vp_vmcall_instruction_wrmsr(uint64_t index, uint64_t value); > > #endif // SELFTEST_TDX_TDX_H > diff --git a/tools/testing/selftests/kvm/lib/x86_64/tdx/tdx.c b/tools/testing/selftests/kvm/lib/x86_64/tdx/tdx.c > index e5a9e13c62e2..88ea6f2a6469 100644 > --- a/tools/testing/selftests/kvm/lib/x86_64/tdx/tdx.c > +++ b/tools/testing/selftests/kvm/lib/x86_64/tdx/tdx.c > @@ -87,3 +87,30 @@ uint64_t tdg_vp_vmcall_get_td_vmcall_info(uint64_t *r11, uint64_t *r12, > > return ret; > } > + > +uint64_t tdg_vp_vmcall_instruction_rdmsr(uint64_t index, uint64_t *ret_value) > +{ > + uint64_t ret; > + struct tdx_hypercall_args args = { > + .r11 = TDG_VP_VMCALL_INSTRUCTION_RDMSR, > + .r12 = index, > + }; > + > + ret = __tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT); > + > + if (ret_value) > + *ret_value = args.r11; > + > + return ret; > +} > + > +uint64_t tdg_vp_vmcall_instruction_wrmsr(uint64_t index, uint64_t value) > +{ > + struct tdx_hypercall_args args = { > + .r11 = TDG_VP_VMCALL_INSTRUCTION_WRMSR, > + .r12 = index, > + .r13 = value, > + }; > + > + return __tdx_hypercall(&args, 0); > +} > diff --git a/tools/testing/selftests/kvm/x86_64/tdx_vm_tests.c b/tools/testing/selftests/kvm/x86_64/tdx_vm_tests.c > index 699cba36e9ce..5db3701cc6d9 100644 > --- a/tools/testing/selftests/kvm/x86_64/tdx_vm_tests.c > +++ b/tools/testing/selftests/kvm/x86_64/tdx_vm_tests.c > @@ -515,6 +515,213 @@ void verify_guest_reads(void) > printf("\t ... PASSED\n"); > } > > +/* > + * Define a filter which denies all MSR access except the following: > + * MSR_X2APIC_APIC_ICR: Allow read/write access (allowed by default) > + * MSR_IA32_MISC_ENABLE: Allow read access > + * MSR_IA32_POWER_CTL: Allow write access > + */ > +#define MSR_X2APIC_APIC_ICR 0x830 > +static u64 tdx_msr_test_allow_bits = 0xFFFFFFFFFFFFFFFF; Nit: 0xFFFFFFFFFFFFFFFF is error prone to define? the following? static u64 tdx_msr_test_allow_bits = ~0ULL; > +struct kvm_msr_filter tdx_msr_test_filter = { > + .flags = KVM_MSR_FILTER_DEFAULT_DENY, > + .ranges = { > + { > + .flags = KVM_MSR_FILTER_READ, > + .nmsrs = 1, > + .base = MSR_IA32_MISC_ENABLE, > + .bitmap = (uint8_t *)&tdx_msr_test_allow_bits, > + }, { > + .flags = KVM_MSR_FILTER_WRITE, > + .nmsrs = 1, > + .base = MSR_IA32_POWER_CTL, > + .bitmap = (uint8_t *)&tdx_msr_test_allow_bits, > + }, > + }, > +}; > + > +/* > + * Verifies MSR read functionality. > + */ > +void guest_msr_read(void) > +{ > + uint64_t data; > + uint64_t ret; > + > + ret = tdg_vp_vmcall_instruction_rdmsr(MSR_X2APIC_APIC_ICR, &data); > + if (ret) > + tdx_test_fatal(ret); > + > + ret = tdx_test_report_64bit_to_user_space(data); > + if (ret) > + tdx_test_fatal(ret); > + > + ret = tdg_vp_vmcall_instruction_rdmsr(MSR_IA32_MISC_ENABLE, &data); > + if (ret) > + tdx_test_fatal(ret); > + > + ret = tdx_test_report_64bit_to_user_space(data); > + if (ret) > + tdx_test_fatal(ret); > + > + /* We expect this call to fail since MSR_IA32_POWER_CTL is write only */ > + ret = tdg_vp_vmcall_instruction_rdmsr(MSR_IA32_POWER_CTL, &data); > + if (ret) { > + ret = tdx_test_report_64bit_to_user_space(ret); > + if (ret) > + tdx_test_fatal(ret); > + } else { > + tdx_test_fatal(-99); > + } > + > + tdx_test_success(); > +} > + > +void verify_guest_msr_reads(void) > +{ > + struct kvm_vm *vm; > + struct kvm_vcpu *vcpu; > + > + uint64_t data; > + int ret; > + > + vm = td_create(); > + td_initialize(vm, VM_MEM_SRC_ANONYMOUS, 0); > + > + /* > + * Set explicit MSR filter map to control access to the MSR registers > + * used in the test. > + */ > + printf("\t ... Setting test MSR filter\n"); > + ret = kvm_check_cap(KVM_CAP_X86_USER_SPACE_MSR); > + TEST_ASSERT(ret, "KVM_CAP_X86_USER_SPACE_MSR is unavailable"); > + vm_enable_cap(vm, KVM_CAP_X86_USER_SPACE_MSR, KVM_MSR_EXIT_REASON_FILTER); > + > + ret = kvm_check_cap(KVM_CAP_X86_MSR_FILTER); > + TEST_ASSERT(ret, "KVM_CAP_X86_MSR_FILTER is unavailable"); > + > + ret = ioctl(vm->fd, KVM_X86_SET_MSR_FILTER, &tdx_msr_test_filter); > + TEST_ASSERT(ret == 0, > + "KVM_X86_SET_MSR_FILTER failed, ret: %i errno: %i (%s)", > + ret, errno, strerror(errno)); > + > + vcpu = td_vcpu_add(vm, 0, guest_msr_read); > + td_finalize(vm); > + > + printf("Verifying guest msr reads:\n"); > + > + printf("\t ... Setting test MSR values\n"); > + /* Write arbitrary to the MSRs. */ > + vcpu_set_msr(vcpu, MSR_X2APIC_APIC_ICR, 4); > + vcpu_set_msr(vcpu, MSR_IA32_MISC_ENABLE, 5); > + vcpu_set_msr(vcpu, MSR_IA32_POWER_CTL, 6); > + > + printf("\t ... Running guest\n"); > + td_vcpu_run(vcpu); > + TDX_TEST_CHECK_GUEST_FAILURE(vcpu); > + data = tdx_test_read_64bit_report_from_guest(vcpu); > + TEST_ASSERT_EQ(data, 4); > + > + td_vcpu_run(vcpu); > + TDX_TEST_CHECK_GUEST_FAILURE(vcpu); > + data = tdx_test_read_64bit_report_from_guest(vcpu); > + TEST_ASSERT_EQ(data, 5); > + > + td_vcpu_run(vcpu); > + TDX_TEST_CHECK_GUEST_FAILURE(vcpu); > + data = tdx_test_read_64bit_report_from_guest(vcpu); > + TEST_ASSERT_EQ(data, TDG_VP_VMCALL_INVALID_OPERAND); > + > + td_vcpu_run(vcpu); > + TDX_TEST_ASSERT_SUCCESS(vcpu); > + > + kvm_vm_free(vm); > + printf("\t ... PASSED\n"); > +} > + > +/* > + * Verifies MSR write functionality. > + */ > +void guest_msr_write(void) > +{ > + uint64_t ret; > + > + ret = tdg_vp_vmcall_instruction_wrmsr(MSR_X2APIC_APIC_ICR, 4); > + if (ret) > + tdx_test_fatal(ret); > + > + /* We expect this call to fail since MSR_IA32_MISC_ENABLE is read only */ > + ret = tdg_vp_vmcall_instruction_wrmsr(MSR_IA32_MISC_ENABLE, 5); > + if (ret) { > + ret = tdx_test_report_64bit_to_user_space(ret); > + if (ret) > + tdx_test_fatal(ret); > + } else { > + tdx_test_fatal(-99); > + } > + > + > + ret = tdg_vp_vmcall_instruction_wrmsr(MSR_IA32_POWER_CTL, 6); > + if (ret) > + tdx_test_fatal(ret); > + > + tdx_test_success(); > +} > + > +void verify_guest_msr_writes(void) > +{ > + struct kvm_vcpu *vcpu; > + struct kvm_vm *vm; > + > + uint64_t data; > + int ret; > + > + vm = td_create(); > + td_initialize(vm, VM_MEM_SRC_ANONYMOUS, 0); > + > + /* > + * Set explicit MSR filter map to control access to the MSR registers > + * used in the test. > + */ > + printf("\t ... Setting test MSR filter\n"); > + ret = kvm_check_cap(KVM_CAP_X86_USER_SPACE_MSR); > + TEST_ASSERT(ret, "KVM_CAP_X86_USER_SPACE_MSR is unavailable"); > + vm_enable_cap(vm, KVM_CAP_X86_USER_SPACE_MSR, KVM_MSR_EXIT_REASON_FILTER); > + > + ret = kvm_check_cap(KVM_CAP_X86_MSR_FILTER); > + TEST_ASSERT(ret, "KVM_CAP_X86_MSR_FILTER is unavailable"); > + > + ret = ioctl(vm->fd, KVM_X86_SET_MSR_FILTER, &tdx_msr_test_filter); > + TEST_ASSERT(ret == 0, > + "KVM_X86_SET_MSR_FILTER failed, ret: %i errno: %i (%s)", > + ret, errno, strerror(errno)); > + > + vcpu = td_vcpu_add(vm, 0, guest_msr_write); > + td_finalize(vm); > + > + printf("Verifying guest msr writes:\n"); > + > + printf("\t ... Running guest\n"); > + /* Only the write to MSR_IA32_MISC_ENABLE should trigger an exit */ > + td_vcpu_run(vcpu); > + TDX_TEST_CHECK_GUEST_FAILURE(vcpu); > + data = tdx_test_read_64bit_report_from_guest(vcpu); > + TEST_ASSERT_EQ(data, TDG_VP_VMCALL_INVALID_OPERAND); > + > + td_vcpu_run(vcpu); > + TDX_TEST_ASSERT_SUCCESS(vcpu); > + > + printf("\t ... Verifying MSR values writen by guest\n"); > + > + TEST_ASSERT_EQ(vcpu_get_msr(vcpu, MSR_X2APIC_APIC_ICR), 4); > + TEST_ASSERT_EQ(vcpu_get_msr(vcpu, MSR_IA32_MISC_ENABLE), 0x1800); > + TEST_ASSERT_EQ(vcpu_get_msr(vcpu, MSR_IA32_POWER_CTL), 6); > + > + kvm_vm_free(vm); > + printf("\t ... PASSED\n"); > +} > + > + > int main(int argc, char **argv) > { > setbuf(stdout, NULL); > @@ -531,6 +738,8 @@ int main(int argc, char **argv) > run_in_new_process(&verify_get_td_vmcall_info); > run_in_new_process(&verify_guest_writes); > run_in_new_process(&verify_guest_reads); > + run_in_new_process(&verify_guest_msr_writes); > + run_in_new_process(&verify_guest_msr_reads); > > return 0; > }