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 A8709C54E41 for ; Mon, 4 Mar 2024 09:17:06 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 0C5EB6B009F; Mon, 4 Mar 2024 04:17:06 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 076F86B00A0; Mon, 4 Mar 2024 04:17:06 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id E7E186B00A1; Mon, 4 Mar 2024 04:17:05 -0500 (EST) 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 CBAF86B009F for ; Mon, 4 Mar 2024 04:17:05 -0500 (EST) Received: from smtpin28.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay03.hostedemail.com (Postfix) with ESMTP id 8E718A09B8 for ; Mon, 4 Mar 2024 09:17:05 +0000 (UTC) X-FDA: 81858802410.28.B45DD08 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.14]) by imf29.hostedemail.com (Postfix) with ESMTP id 2B2CF120009 for ; Mon, 4 Mar 2024 09:17:02 +0000 (UTC) Authentication-Results: imf29.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b=mNCCQ9uf; dmarc=pass (policy=none) header.from=intel.com; spf=none (imf29.hostedemail.com: domain of binbin.wu@linux.intel.com has no SPF policy when checking 198.175.65.14) smtp.mailfrom=binbin.wu@linux.intel.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1709543823; 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=HT6amlzwnuFo47clLHSWzS2YBWX/K6wdGX2YWcHJC2Q=; b=DhfC3DM5JFDyCK2w0hj5IkPaP43vLkOFN9dLXmc1Eb1W3cs5kxUFcns+c1PVEa7ZACsEcZ C21NCw627kyRPrR2wtQ0y4iop2uxx80YTH1ZrSo4F9Y2GLJNt16uBF3JIkE2Lmb2Q8TcXV blr0Cp28HclkNLV3C3k4arsKOBXWfR8= ARC-Authentication-Results: i=1; imf29.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b=mNCCQ9uf; dmarc=pass (policy=none) header.from=intel.com; spf=none (imf29.hostedemail.com: domain of binbin.wu@linux.intel.com has no SPF policy when checking 198.175.65.14) smtp.mailfrom=binbin.wu@linux.intel.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1709543823; a=rsa-sha256; cv=none; b=u4U0CKJYlKnDvoR8rMX83ti2e5n604osAQLbp8hbZs1YfOIaAaF6GDQ98srVCnI6xPlMdR TzuoeYWzUjRlsOlE+EQvxoINjVttFxgDwWBEOMVksrZKEtaHpF/opqLDtQYmO6HzqA7zbs 12XSju2IhGnLyZhoB/U3rm6koKqLxOg= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1709543824; x=1741079824; h=message-id:date:mime-version:subject:to:cc:references: from:in-reply-to:content-transfer-encoding; bh=3DwW30fbFMvQ2ySHnVA3fgbqopvn+6yGmMXD+bUNixc=; b=mNCCQ9ufKU5uz2tf67gVIZkNTY0aUyHUHCxbWi0a2Qe7sSd7PPnaHfe5 EBM5CkfxPxamlPPGWzavvhMTLR9JFFLOYjfGfJMP7vPyHuyzLh7NFFNPC EJpqx9ugQyRRRsYCtsRlmMkC68qRnot/TiuKPyXWazfX7UGoJOxhMjeYq 83uK5PXbKXL9xOQqg+JiZaqsIZs44PtPeGlBi6frnqiL07+q6YyD5zppn r6Fi293IYR0bd7gIb1RLTMXk8xGWvTPoZeMf8JQuucPXdMBL7vuBSzpPf svoSo2k7b76xZTNePj2WPH0kKkZ875qE0T+dZcEMionsfRYPlMBFgcKhH Q==; X-IronPort-AV: E=McAfee;i="6600,9927,11002"; a="7833986" X-IronPort-AV: E=Sophos;i="6.06,203,1705392000"; d="scan'208";a="7833986" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by orvoesa106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Mar 2024 01:17:00 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.06,203,1705392000"; d="scan'208";a="8838530" Received: from binbinwu-mobl.ccr.corp.intel.com (HELO [10.238.8.218]) ([10.238.8.218]) by fmviesa009-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Mar 2024 01:16:55 -0800 Message-ID: <0344d85f-d6ab-4d78-abac-d0293d71ef91@linux.intel.com> Date: Mon, 4 Mar 2024 17:16:53 +0800 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [RFC PATCH v5 10/29] KVM: selftests: TDX: Adding test case for TDX port IO To: Yan Zhao , Sagi Shahar Cc: linux-kselftest@vger.kernel.org, Ackerley Tng , Ryan Afranji , Erdem Aktas , Isaku Yamahata , 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-11-sagis@google.com> From: Binbin Wu In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Rspam-User: X-Stat-Signature: mk3n6kkaawhaugmuxxrznfbzdc7paruz X-Rspamd-Server: rspam07 X-Rspamd-Queue-Id: 2B2CF120009 X-HE-Tag: 1709543822-170285 X-HE-Meta: U2FsdGVkX18wrPMLQDvWeM/XCxJYXwprxqzPkhRqmhu6F8eG7v/2bRJ8D+eIUs4h6CUkGhN0ubwwunHSUE+dLFKSTNZFuecZCvtIpQZdllUtzY02n60Zn6vrzLc4XFrEMrEzNa1Jjc2cUyfbiBx9KRb5mubBv2aoLbzYp0NaDVFNPUpF4ZXVQDMZvL+a+li9cdi4a9rjOBnwZgoqjYZeiZuJUEDikJR6Y+Vm4ErWz7/glkb4aCOyVPRRO4zWg3wECNWgr8Ij9VOdI+MJvX0JJ2qIBx9Moxn2co/KsaIDUvoKXZeGANnH4QUeI+DA8kbwXpW/9u18akwPH8VAWV2sHXikYhnq4ieWu5LKZsh6Jlh7Qrn1uL1L48+qOT8Gwq4yi9ErWUWQnMMaexKzL6Pj6i1Lt2cLVYpbcY5l2k6gosvNv1807H8jEvgXsVC7sSKz9ztE9JBm8DcuupPHz7rA7yvTULB8SRwp2dWyXY4mjOS+7TzvaC7VbzMa0qVhQuFh4qQWwDsVpqRaelNb27mpUB+/vAKLAV5EV5UnJJALNaJzWP77xxzNYlhcYmtOkV9F6hfmIVi91jvhd+tbxqE2PYNQ0OosFxvVUsRFy5ZgkJpNNm4iErk2fi1mzDH6KoSFtRwm0O/LNGVrtRF4NSYbNiCxssD/CYcvQItAX/58QnpIdQPPa72VP8h/d4Vq5fygEr8nk7WRXAe8bPd1wPYS6PPt3lT7Qx34zArseiy0F1FtkaRqL4uPKBEnl0mP06guzaMYkCrlK4HQk9I2Y0amQ+f3Zbu5Ig3MzD4UGt0rT8HHnfCkS03K2zdH6YOkXsLRvDpHfkHpvZP4gubVtp8nhtYo8OazkgA0/LY2lQTvArdcF9KpCv8GXA== 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 3/4/2024 10:19 AM, Yan Zhao wrote: > On Tue, Dec 12, 2023 at 12:46:25PM -0800, Sagi Shahar wrote: >> From: Erdem Aktas >> >> Verifies TDVMCALL READ and WRITE operations. >> >> Signed-off-by: Erdem Aktas >> Signed-off-by: Sagi Shahar >> Signed-off-by: Ackerley Tng >> Signed-off-by: Ryan Afranji >> --- >> .../kvm/include/x86_64/tdx/test_util.h | 34 ++++++++ >> .../selftests/kvm/x86_64/tdx_vm_tests.c | 82 +++++++++++++++++++ >> 2 files changed, 116 insertions(+) >> >> diff --git a/tools/testing/selftests/kvm/include/x86_64/tdx/test_util.h b/tools/testing/selftests/kvm/include/x86_64/tdx/test_util.h >> index 6d69921136bd..95a5d5be7f0b 100644 >> --- a/tools/testing/selftests/kvm/include/x86_64/tdx/test_util.h >> +++ b/tools/testing/selftests/kvm/include/x86_64/tdx/test_util.h >> @@ -9,6 +9,40 @@ >> #define TDX_TEST_SUCCESS_PORT 0x30 >> #define TDX_TEST_SUCCESS_SIZE 4 >> >> +/** >> + * Assert that some IO operation involving tdg_vp_vmcall_instruction_io() was >> + * called in the guest. >> + */ >> +#define TDX_TEST_ASSERT_IO(VCPU, PORT, SIZE, DIR) \ >> + do { \ >> + TEST_ASSERT((VCPU)->run->exit_reason == KVM_EXIT_IO, \ >> + "Got exit_reason other than KVM_EXIT_IO: %u (%s)\n", \ >> + (VCPU)->run->exit_reason, \ >> + exit_reason_str((VCPU)->run->exit_reason)); \ >> + \ >> + TEST_ASSERT(((VCPU)->run->exit_reason == KVM_EXIT_IO) && \ >> + ((VCPU)->run->io.port == (PORT)) && \ >> + ((VCPU)->run->io.size == (SIZE)) && \ >> + ((VCPU)->run->io.direction == (DIR)), \ >> + "Got unexpected IO exit values: %u (%s) %d %d %d\n", \ >> + (VCPU)->run->exit_reason, \ >> + exit_reason_str((VCPU)->run->exit_reason), \ >> + (VCPU)->run->io.port, (VCPU)->run->io.size, \ >> + (VCPU)->run->io.direction); \ >> + } while (0) >> + >> +/** >> + * Check and report if there was some failure in the guest, either an exception >> + * like a triple fault, or if a tdx_test_fatal() was hit. >> + */ >> +#define TDX_TEST_CHECK_GUEST_FAILURE(VCPU) \ >> + do { \ >> + if ((VCPU)->run->exit_reason == KVM_EXIT_SYSTEM_EVENT) \ >> + TEST_FAIL("Guest reported error. error code: %lld (0x%llx)\n", \ >> + (VCPU)->run->system_event.data[1], \ >> + (VCPU)->run->system_event.data[1]); \ >> + } while (0) >> + >> /** >> * Assert that tdx_test_success() was called in the guest. >> */ >> 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 8638c7bbedaa..75467c407ca7 100644 >> --- a/tools/testing/selftests/kvm/x86_64/tdx_vm_tests.c >> +++ b/tools/testing/selftests/kvm/x86_64/tdx_vm_tests.c >> @@ -2,6 +2,7 @@ >> >> #include >> #include "kvm_util_base.h" >> +#include "tdx/tdcall.h" >> #include "tdx/tdx.h" >> #include "tdx/tdx_util.h" >> #include "tdx/test_util.h" >> @@ -74,6 +75,86 @@ void verify_report_fatal_error(void) >> printf("\t ... PASSED\n"); >> } >> >> +#define TDX_IOEXIT_TEST_PORT 0x50 >> + >> +/* >> + * Verifies IO functionality by writing a |value| to a predefined port. >> + * Verifies that the read value is |value| + 1 from the same port. >> + * If all the tests are passed then write a value to port TDX_TEST_PORT >> + */ >> +void guest_ioexit(void) >> +{ >> + uint64_t data_out, data_in, delta; >> + uint64_t ret; >> + >> + data_out = 0xAB; >> + ret = tdg_vp_vmcall_instruction_io(TDX_IOEXIT_TEST_PORT, 1, >> + TDG_VP_VMCALL_INSTRUCTION_IO_WRITE, >> + &data_out); >> + if (ret) >> + tdx_test_fatal(ret); >> + >> + ret = tdg_vp_vmcall_instruction_io(TDX_IOEXIT_TEST_PORT, 1, >> + TDG_VP_VMCALL_INSTRUCTION_IO_READ, >> + &data_in); >> + if (ret) >> + tdx_test_fatal(ret); >> + >> + delta = data_in - data_out; >> + if (delta != 1) >> + tdx_test_fatal(ret); >> + >> + tdx_test_success(); >> +} >> + >> +void verify_td_ioexit(void) >> +{ >> + struct kvm_vm *vm; >> + struct kvm_vcpu *vcpu; >> + >> + uint32_t port_data; >> + >> + vm = td_create(); >> + td_initialize(vm, VM_MEM_SRC_ANONYMOUS, 0); >> + vcpu = td_vcpu_add(vm, 0, guest_ioexit); >> + td_finalize(vm); >> + >> + printf("Verifying TD IO Exit:\n"); >> + >> + /* Wait for guest to do a IO write */ >> + td_vcpu_run(vcpu); >> + TDX_TEST_CHECK_GUEST_FAILURE(vcpu); > This check is a vain, because the first VMExit from vcpu run is always > KVM_EXIT_IO caused by tdg_vp_vmcall_instruction_io(). I think tdg_vp_vmcall_instruction_io() could fail if RCX (GPR select) doesn't meet the requirement (some bits must be 0). Although RCX is set by guest code (in selftest, it set in __tdx_hypercall()) and it will not trigger the error, it still can be used as a guard to make sure guest doesn't pass a invalid RCX. > > >> + TDX_TEST_ASSERT_IO(vcpu, TDX_IOEXIT_TEST_PORT, 1, >> + TDG_VP_VMCALL_INSTRUCTION_IO_WRITE); >> + port_data = *(uint8_t *)((void *)vcpu->run + vcpu->run->io.data_offset); >> + >> + printf("\t ... IO WRITE: OK\n"); > So, even if there's an error in emulating writing of TDX_IOEXIT_TEST_PORT, > and guest would then find a failure and trigger tdx_test_fatal(), this line > will still print "IO WRITE: OK", which is not right. > >> + >> + /* >> + * Wait for the guest to do a IO read. Provide the previous written data >> + * + 1 back to the guest >> + */ >> + td_vcpu_run(vcpu); >> + TDX_TEST_CHECK_GUEST_FAILURE(vcpu); > This check is a vain, too, as in write case. > >> + TDX_TEST_ASSERT_IO(vcpu, TDX_IOEXIT_TEST_PORT, 1, >> + TDG_VP_VMCALL_INSTRUCTION_IO_READ); >> + *(uint8_t *)((void *)vcpu->run + vcpu->run->io.data_offset) = port_data + 1; >> + >> + printf("\t ... IO READ: OK\n"); > Same as in write case, this line should not be printed until after guest > finishing checking return code. > >> + >> + /* >> + * Wait for the guest to complete execution successfully. The read >> + * value is checked within the guest. >> + */ >> + td_vcpu_run(vcpu); >> + TDX_TEST_CHECK_GUEST_FAILURE(vcpu); >> + TDX_TEST_ASSERT_SUCCESS(vcpu); >> + >> + printf("\t ... IO verify read/write values: OK\n"); >> + kvm_vm_free(vm); >> + printf("\t ... PASSED\n"); >> +} >> + >> int main(int argc, char **argv) >> { >> setbuf(stdout, NULL); >> @@ -85,6 +166,7 @@ int main(int argc, char **argv) >> >> run_in_new_process(&verify_td_lifecycle); >> run_in_new_process(&verify_report_fatal_error); >> + run_in_new_process(&verify_td_ioexit); >> >> return 0; >> } >> -- >> 2.43.0.472.g3155946c3a-goog >> >>