From patchwork Tue Dec 12 20:46:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sagi Shahar X-Patchwork-Id: 13489870 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 E8622C4332F for ; Tue, 12 Dec 2023 20:47:29 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 2FE956B0378; Tue, 12 Dec 2023 15:47:22 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 2B10D6B037A; Tue, 12 Dec 2023 15:47:22 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 0D8DB6B037B; Tue, 12 Dec 2023 15:47:21 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id E62856B0378 for ; Tue, 12 Dec 2023 15:47:21 -0500 (EST) Received: from smtpin05.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id BC15E120A30 for ; Tue, 12 Dec 2023 20:47:21 +0000 (UTC) X-FDA: 81559351482.05.F497D7F Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.202]) by imf18.hostedemail.com (Postfix) with ESMTP id ED4861C0025 for ; Tue, 12 Dec 2023 20:47:19 +0000 (UTC) Authentication-Results: imf18.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=DGsw+EcY; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf18.hostedemail.com: domain of 31cZ4ZQUKCHgoWceockkcha.Ykihejqt-iigrWYg.knc@flex--sagis.bounces.google.com designates 209.85.128.202 as permitted sender) smtp.mailfrom=31cZ4ZQUKCHgoWceockkcha.Ykihejqt-iigrWYg.knc@flex--sagis.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1702414040; 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: in-reply-to:in-reply-to:references:references:dkim-signature; bh=yeLWUyiP/wO8xtMoo+vlGGvYyGcJ6kthyZbia5KZ2g4=; b=2EaMsDbwbyjvJrhs/+E8J526YWYakpb+5vAB0pLBlGagHCm0GWE4H7UKmzeUF3cCwmEo5N izvBdmMw87n1GBSkxwtuOEl9RQEKFm1u7cwHEfZdHmJboTdpUtI0oLm2fJghaHMU6pApHV IrIGklLbMGS/hXI+gjHaO1K922mQ1Uo= ARC-Authentication-Results: i=1; imf18.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=DGsw+EcY; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf18.hostedemail.com: domain of 31cZ4ZQUKCHgoWceockkcha.Ykihejqt-iigrWYg.knc@flex--sagis.bounces.google.com designates 209.85.128.202 as permitted sender) smtp.mailfrom=31cZ4ZQUKCHgoWceockkcha.Ykihejqt-iigrWYg.knc@flex--sagis.bounces.google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1702414040; a=rsa-sha256; cv=none; b=WH/Vz3MHkIMIPLzdUjqAFSojL1RiyU2WgJdPNofycA/PqpM/IeqOqedY9wQbUhkjdNGfcG Ec7RghcZ86wPqqwpcUq+r6MJS+uEhTqzv03CPsIdbyHiUzDW6b7tvXk8E0xmKMCluSBCwt Svx5WHijaUlf9ZJz96xN1uuVSlZg36w= Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-5e20c9c4080so11326997b3.3 for ; Tue, 12 Dec 2023 12:47:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1702414039; x=1703018839; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=yeLWUyiP/wO8xtMoo+vlGGvYyGcJ6kthyZbia5KZ2g4=; b=DGsw+EcYELdfhZj59+Xtw3xfrvNu1aiO+oHdvrhsOYLXEucz7kA6MCE+zo2xpuxPmX Qr+jUww6IGOnr4EcvNZdSBMM3sc5mdTWNZfkLAQJC7ODOpRKo4D1/LOl1FnzhUEVIqsL 5NWgygPcuuKLGP0IUQbZBMjvCE+DdReAPSUes61q1tlDM8/iWoIHmpOoG/kv/AJHOQhu OK5kC3UxtBgoHXN8DXYaPlx9+p/DPVa+C7D9P4gbNwrgLy99qzDK8dBpHgDVAfdz4sbM ViIOma5To0qDeNsfUHKKiz3z8EgfjAqCC7+vgGRePVPpS5dkaadCWN5YQEPreJb1OrDK nibA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702414039; x=1703018839; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=yeLWUyiP/wO8xtMoo+vlGGvYyGcJ6kthyZbia5KZ2g4=; b=hujX5fld5VDKOZQhnJ4F/sXD7TsxCTtTlDAuC42GvHmxQVJFeiDJxTQGWKBnktcaR5 kvH8+lrR8obaVwh4ryI9kkP1Xx3O1pPWP24+eBlu13pd+r0LtXvIJC0dDYLVI7R6mvaa 3+UFqogQ6IAcC+4rP+CEOZI+R6BYi/o650Putb051Lg8ZoappcuC/SHllYUG9zB/mBZX qADDBCBj4v7AnrSRtoCxLXYsFTNNnngraAbVMesvaZE+xtAtlTft3SWpUkMZ9av3LGJX sfDnpbbnfgBd9kTAyMhxxuakM/E2DCx2YQrK6Rxyn/mpNxRNs+WJcF+mklXgG89FqdlF APsA== X-Gm-Message-State: AOJu0Yx+MH/4KLAfWklsZ4LRWzisCvjrOgCm41x37pjONbbbDxFIZ5dx WYATZf0WTvJw31R0IZqvH6W7pl5PfA== X-Google-Smtp-Source: AGHT+IE5N+kuLbahhMDX59Z0zuObBfc5I7jEWD21qixoGjX8y/mofmjWwRaghUF2QwlVYLPSt8arVNojlg== X-Received: from sagi.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:241b]) (user=sagis job=sendgmr) by 2002:a05:690c:c09:b0:5d3:3aa4:6f3a with SMTP id cl9-20020a05690c0c0900b005d33aa46f3amr68898ywb.3.1702414037003; Tue, 12 Dec 2023 12:47:17 -0800 (PST) Date: Tue, 12 Dec 2023 12:46:26 -0800 In-Reply-To: <20231212204647.2170650-1-sagis@google.com> Mime-Version: 1.0 References: <20231212204647.2170650-1-sagis@google.com> X-Mailer: git-send-email 2.43.0.472.g3155946c3a-goog Message-ID: <20231212204647.2170650-12-sagis@google.com> Subject: [RFC PATCH v5 11/29] KVM: selftests: TDX: Add basic TDX CPUID test From: Sagi Shahar To: linux-kselftest@vger.kernel.org, Ackerley Tng , Ryan Afranji , Erdem Aktas , Sagi Shahar , 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 X-Rspamd-Queue-Id: ED4861C0025 X-Rspam-User: X-Rspamd-Server: rspam05 X-Stat-Signature: k4xz3efwz9gccm5wssrgsncbyramwygz X-HE-Tag: 1702414039-26755 X-HE-Meta: U2FsdGVkX1/O632U4T2Vt1TauZ5TiAK/vfT7Lukhw1jym+f6qcEUe5RI7kN+6aLuHExZrrT8LeSx4H3hvhU0D4bXmjxSJb1p5/POwaoiUlG3CL37wvjS2TrfH0TqNhTc9tI2oY9PtGzfMi84iVMz37UfBu5i0CSXLdmg0fA5NpWlHAD+gRmAQstbo3AhyVue3LiElfYGQOSLbFVi30wAI9XI0BtnaUC35MybS6hQfOnEX9QE/d8nDnP1G816+0eCE98/mEJxWTocUlngvWoay4H+BR+pJcT+5+ox/5JdpAOdfunVDSXjnt8fJ+jMjp3om8ajAoa0N0GeoXt6PuBsrbBg8Qopx/dM2QHcr05mZt/HdQS5liIdCz4YBOQHxh28h5+dQ/j9IX5INhIn8l69Sj+ri6F3prjjDQtL2YbVB9UP/7RIUYN8LvdjgWW2/FBNMcMWfkORj2Zfw/tIMr6JJS7LPyOYDAr8ltrmONcbCrj0Cb46wBer4IXmTUfroXE7PDOsOI0Ektg6ag1PHlFIVvVqHiYJ8DmSJp1i8SXYjc7GCziPGSwq1bx+3kn5v14WqNqCoolLvI0t1wxEobv+7nb/xXJkA4S+UtEoCwCpXPv7mnTwWCu5P4o78BdrBzUNGu84OPBilc+YveB2ijZiGt5TCDd66Ma0gAnIV7VCC6JVtmipGjY+lwR/BjuOGfzmggDdn7yPGHraCy/Cb/Xd8j9Ogn9f+RLZihOREYdEdtF7olx8r7tPZbWsbvxVSu/r9KGrY7HygDsxfExEIAkRkHc/lh8RRbLq/tlqBQ92yWvoUuDOeuWi34QpY7EcCMNafoY6BokTcL5AeRIRyrhUZSTFFlu7P4I03HBC750tWRFUDSqqG1QSNEGPp+xHTYt1NIO3AYTcorMN2QI+RXPyonqZDI2RwHo+i4syCobPD2i8nCoi/VVMKWkSvPUuXJecB0IcfuYs7HwEz3jopBQ HlHqlj97 DcHV7nqdGcRkvL5UYc3pcs3dtPmxeG+GWofVIlWjZuC2SGlhlGYkOj96up1cW2B/Z1YKDNd7t+y+GJZm40ue7v2jdOoi7cgpwwTDnmim5h++c4wCsbs5vd+18vo+PfXmWZ8Q9WTbGHLbqtb6LkGekyeC91BrXBUCSADvx5F80pvaKudsIlNXEQl+xhQZPKovhsRcznL6uXc2FWEmWZZybgdccVv1ByFCxw/hL0satKN+RBI97eGMLpedlL8hdXFcSTKABLBlzNv36cFuAIpEapYXuJdcKbi1AzUdzKuReAWw3Pf964LIzuZQaug32OgR84ud6XgcMRIzrjnZz+5+LelCmvSn7exR7Hz7Pu48QfeoMzis/q3rm5nEF6NfNvPyhVu7oqtdfRzIq3OVrgv/VtvhGoPhd9iE6KeOz5BGJC5FAmHuHMqN8hzlzQ6kCNPx3oG/ncnkXNCgW4wVHpqUbfxG8ZxCXXGJRDrIRif34YWP75rpCevkWTxoqOYh/ZIKW9jgHOuvJa9YzHKGUKuuMjivuK1kVvaoYGlaXyHzBU3N7yru6z8bc+wgWQ+4FCiFph4+NZbKjkpufWA5/ERhy5yvFf3ClnhjkcTip 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: The test reads CPUID values from inside a TD VM and compare them to expected values. The test targets CPUID values which are virtualized as "As Configured", "As Configured (if Native)", "Calculated", "Fixed" and "Native" according to the TDX spec. Signed-off-by: Sagi Shahar Signed-off-by: Ackerley Tng Signed-off-by: Ryan Afranji --- .../kvm/include/x86_64/tdx/test_util.h | 9 ++ .../selftests/kvm/lib/x86_64/tdx/test_util.c | 11 ++ .../selftests/kvm/x86_64/tdx_vm_tests.c | 106 ++++++++++++++++++ 3 files changed, 126 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 95a5d5be7f0b..af0ddbfe8d71 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,9 @@ #define TDX_TEST_SUCCESS_PORT 0x30 #define TDX_TEST_SUCCESS_SIZE 4 +#define TDX_TEST_REPORT_PORT 0x31 +#define TDX_TEST_REPORT_SIZE 4 + /** * Assert that some IO operation involving tdg_vp_vmcall_instruction_io() was * called in the guest. @@ -102,4 +105,10 @@ void tdx_test_fatal(uint64_t error_code); */ void tdx_test_fatal_with_data(uint64_t error_code, uint64_t data_gpa); +/** + * Report a 32 bit value from the guest to user space using TDG.VP.VMCALL + * call. Data is reported on port TDX_TEST_REPORT_PORT. + */ +uint64_t tdx_test_report_to_user_space(uint32_t data); + #endif // SELFTEST_TDX_TEST_UTIL_H diff --git a/tools/testing/selftests/kvm/lib/x86_64/tdx/test_util.c b/tools/testing/selftests/kvm/lib/x86_64/tdx/test_util.c index 7f3cd8089cea..55c5a1e634df 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/tdx/test_util.c +++ b/tools/testing/selftests/kvm/lib/x86_64/tdx/test_util.c @@ -42,3 +42,14 @@ void tdx_test_fatal(uint64_t error_code) { tdx_test_fatal_with_data(error_code, 0); } + +uint64_t tdx_test_report_to_user_space(uint32_t data) +{ + /* Upcast data to match tdg_vp_vmcall_instruction_io signature */ + uint64_t data_64 = data; + + return tdg_vp_vmcall_instruction_io(TDX_TEST_REPORT_PORT, + TDX_TEST_REPORT_SIZE, + TDG_VP_VMCALL_INSTRUCTION_IO_WRITE, + &data_64); +} 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 75467c407ca7..1b30e6f5a569 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 "processor.h" #include "tdx/tdcall.h" #include "tdx/tdx.h" #include "tdx/tdx_util.h" @@ -155,6 +156,110 @@ void verify_td_ioexit(void) printf("\t ... PASSED\n"); } +/* + * Verifies CPUID functionality by reading CPUID values in guest. The guest + * will then send the values to userspace using an IO write to be checked + * against the expected values. + */ +void guest_code_cpuid(void) +{ + uint64_t err; + uint32_t ebx, ecx; + + /* Read CPUID leaf 0x1 */ + asm volatile ( + "cpuid" + : "=b" (ebx), "=c" (ecx) + : "a" (0x1) + : "edx"); + + err = tdx_test_report_to_user_space(ebx); + if (err) + tdx_test_fatal(err); + + err = tdx_test_report_to_user_space(ecx); + if (err) + tdx_test_fatal(err); + + tdx_test_success(); +} + +void verify_td_cpuid(void) +{ + struct kvm_vm *vm; + struct kvm_vcpu *vcpu; + + uint32_t ebx, ecx; + const struct kvm_cpuid_entry2 *cpuid_entry; + uint32_t guest_clflush_line_size; + uint32_t guest_max_addressable_ids, host_max_addressable_ids; + uint32_t guest_sse3_enabled; + uint32_t guest_fma_enabled; + uint32_t guest_initial_apic_id; + + vm = td_create(); + td_initialize(vm, VM_MEM_SRC_ANONYMOUS, 0); + vcpu = td_vcpu_add(vm, 0, guest_code_cpuid); + td_finalize(vm); + + printf("Verifying TD CPUID:\n"); + + /* Wait for guest to report ebx value */ + td_vcpu_run(vcpu); + TDX_TEST_CHECK_GUEST_FAILURE(vcpu); + TDX_TEST_ASSERT_IO(vcpu, TDX_TEST_REPORT_PORT, 4, + TDG_VP_VMCALL_INSTRUCTION_IO_WRITE); + ebx = *(uint32_t *)((void *)vcpu->run + vcpu->run->io.data_offset); + + /* Wait for guest to report either ecx value or error */ + td_vcpu_run(vcpu); + TDX_TEST_CHECK_GUEST_FAILURE(vcpu); + TDX_TEST_ASSERT_IO(vcpu, TDX_TEST_REPORT_PORT, 4, + TDG_VP_VMCALL_INSTRUCTION_IO_WRITE); + ecx = *(uint32_t *)((void *)vcpu->run + vcpu->run->io.data_offset); + + /* Wait for guest to complete execution */ + td_vcpu_run(vcpu); + TDX_TEST_CHECK_GUEST_FAILURE(vcpu); + TDX_TEST_ASSERT_SUCCESS(vcpu); + + /* Verify the CPUID values we got from the guest. */ + printf("\t ... Verifying CPUID values from guest\n"); + + /* Get KVM CPUIDs for reference */ + cpuid_entry = get_cpuid_entry(kvm_get_supported_cpuid(), 1, 0); + TEST_ASSERT(cpuid_entry, "CPUID entry missing\n"); + + host_max_addressable_ids = (cpuid_entry->ebx >> 16) & 0xFF; + + guest_sse3_enabled = ecx & 0x1; // Native + guest_clflush_line_size = (ebx >> 8) & 0xFF; // Fixed + guest_max_addressable_ids = (ebx >> 16) & 0xFF; // As Configured + guest_fma_enabled = (ecx >> 12) & 0x1; // As Configured (if Native) + guest_initial_apic_id = (ebx >> 24) & 0xFF; // Calculated + + TEST_ASSERT_EQ(guest_sse3_enabled, 1); + TEST_ASSERT_EQ(guest_clflush_line_size, 8); + TEST_ASSERT_EQ(guest_max_addressable_ids, host_max_addressable_ids); + + /* TODO: This only tests the native value. To properly test + * "As Configured (if Native)" we need to override this value + * in the TD params + */ + TEST_ASSERT_EQ(guest_fma_enabled, 1); + + /* TODO: guest_initial_apic_id is calculated based on the number of + * VCPUs in the TD. From the spec: "Virtual CPU index, starting from 0 + * and allocated sequentially on each successful TDH.VP.INIT" + * To test non-trivial values we either need a TD with multiple VCPUs + * or to pick a different calculated value. + */ + TEST_ASSERT_EQ(guest_initial_apic_id, 0); + + kvm_vm_free(vm); + printf("\t ... PASSED\n"); +} + int main(int argc, char **argv) { setbuf(stdout, NULL); @@ -167,6 +272,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); + run_in_new_process(&verify_td_cpuid); return 0; }