Received: by 2002:a6b:fb09:0:0:0:0:0 with SMTP id h9csp1561625iog; Tue, 14 Jun 2022 08:26:21 -0700 (PDT) X-Google-Smtp-Source: ABdhPJytiPUvNG86B362fJSQr6zq4BjKmAy5SnczWBcXWlgegbXMREusgUz6tSQkEPE0TMcz7P/0 X-Received: by 2002:a05:6402:3489:b0:431:3565:4cb0 with SMTP id v9-20020a056402348900b0043135654cb0mr6628953edc.135.1655220381071; Tue, 14 Jun 2022 08:26:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1655220381; cv=none; d=google.com; s=arc-20160816; b=HJt5jTNXTW7B3BWNecMaSveLMzwB+sDF6kbE0S+Xwt5YsPzN15031RNT6t3w0HByKA QmMSYFZbWR7f1KYUbwR6TKnbOd9q09aKtO/WufXzNn47tPH1QVeyJcLeOaQjPIYZYWNm aRS5u/rHYJUwwTtYjhrOmDyZdBEkQBaKz4NXHqSuxver7Vj+8SbcBjkZ1r/rZIJkHUiD +ZYQrvmUtCt8jlgvEgQ/a7TDI5mOuhDY2d1PEd5aDQqHwBlrUBHJGwV1LLA4oObHV57D m63Z5j8jSSp0i1OWwZxzK4hDfClN/Igc9WoO8ZG9ulKGleOouduGrh3V/F8peI1mXtx5 wybg== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=PLJIs4OVND2eZhhcOVR8f4Au/FsbN/sqVBIt2y1QLKQ=; b=XMWGDAFctvXVZKAszam3GexGuBf2mp8e+PSQXgE54McQjFnPdT+YCikxjebZwmA9zn KlzqjeoP9dibL7zP1RXhpDAItOIsdRQq/NGpZ8Qc0JuTD+KZQX20IFi7YWJlhoW+TyQn R7fGxni3+nddvssHIY6Rr4G2kJwOiJb6hOxN5eX12T3pzY32vbVxH7D0fwgHbICPwPh3 VDBydHvrm7sEaoDADaEW2Ah9tVLFWeHxjObU//EHzUMGXWFghRv1NBwjqQhebvFdlQuB gQfphPiasmY3sK/OJiB1y3r6v6ex9BWSz7pN0b72fpmxd6aoT1cCKySCCue4jQlkQuIh lm9Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=Y2QtsKMA; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b13-20020a056402084d00b0042accc0b1basi14196315edz.546.2022.06.14.08.25.54; Tue, 14 Jun 2022 08:26:21 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=Y2QtsKMA; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1356278AbiFNPL6 (ORCPT + 99 others); Tue, 14 Jun 2022 11:11:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42122 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1356221AbiFNPLz (ORCPT ); Tue, 14 Jun 2022 11:11:55 -0400 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 377623F88B; Tue, 14 Jun 2022 08:11:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1655219514; x=1686755514; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=2aHl53WvnO/FvyT5FOpuxZQlcnfaJheQizeiOWcK4bw=; b=Y2QtsKMAd+lpqykaFHkHgDagVpreJthl3MoBa0HVQfxSAOIPxq5mzIsg rEPESjdlaTFacD+olnlaWA/iHaUbTWC65FUlh/DdZ1G4JkU2TgA+mAfGV iNkzwp6qjk3a4wO89VQLUVrrJbKl8lRApcwh+jna5FLw8k6VFryfxeZ6F LdGlRagfSG21D0o//xjmlq1aeit/qDyH+g/TA5hQYFI0LrankLzy185gr srbnsmdaiebDQxzbBRuMGRs0htuVbbVQuGMZpcG+O68NG4l2yAr4VeKn5 z2NvduUfltuqHvowTY75vGtXHmtkt5iVrT5w+1PDgzx8PxjA7QsjFNVWJ A==; X-IronPort-AV: E=McAfee;i="6400,9594,10378"; a="261673605" X-IronPort-AV: E=Sophos;i="5.91,300,1647327600"; d="scan'208";a="261673605" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Jun 2022 08:11:53 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.91,300,1647327600"; d="scan'208";a="673941779" Received: from xpf.sh.intel.com ([10.239.182.112]) by FMSMGA003.fm.intel.com with ESMTP; 14 Jun 2022 08:11:51 -0700 From: Pengfei Xu To: Shuah Khan , linux-kselftest , linux-kernel Cc: Pengfei Xu , Heng Su , Hansen Dave , Luck Tony , Mehta Sohil , Chen Yu C , Andy Lutomirski , Borislav Petkov , Thomas Gleixner , Bae Chang Seok Subject: [PATCH v9 2/2] selftests/x86/xstate: Add xstate fork test for XSAVE feature Date: Tue, 14 Jun 2022 23:11:06 +0800 Message-Id: X-Mailer: git-send-email 2.31.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-3.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In order to ensure that XSAVE works correctly, add XSAVE most basic fork test: 1. The contents of these xstates in the child process should be the same as the contents of the xstate in the parent process after the fork syscall. 2. The contents of xstates in the parent process should not change after the context switch. [ Dave Hansen; Chang S. Bae: bunches of cleanups ] Reviewed-by: Chang S. Bae Signed-off-by: Pengfei Xu --- tools/testing/selftests/x86/xstate.c | 22 ++++++++- tools/testing/selftests/x86/xstate.h | 1 + tools/testing/selftests/x86/xstate_helpers.c | 51 ++++++++++++++++++++ tools/testing/selftests/x86/xstate_helpers.h | 2 + 4 files changed, 75 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/x86/xstate.c b/tools/testing/selftests/x86/xstate.c index 05dabb4733a0..96e6b5db907b 100644 --- a/tools/testing/selftests/x86/xstate.c +++ b/tools/testing/selftests/x86/xstate.c @@ -45,7 +45,7 @@ #include "xstate_helpers.h" #include "../kselftest.h" -#define NUM_TESTS 1 +#define NUM_TESTS 3 #define xstate_test_array_init(idx, init_opt, fill_opt) \ do { \ xstate_tests[idx].init = init_opt; \ @@ -135,6 +135,25 @@ static void test_xstate_sig_handle(void) compare_buf_result(valid_xbuf, compared_xbuf, case_name1); } +static void test_xstate_fork(void) +{ + const char *case_name2 = "xstate of child process should be same as xstate of parent"; + const char *case_name3 = "parent xstate should be same after context switch"; + + ksft_print_msg("[RUN]\tParent pid:%d check xstate around fork test.\n", + getpid()); + /* Child process xstate should be same as the parent process xstate. */ + if (xstate_fork(valid_xbuf, compared_xbuf, xstate_info.mask, + xstate_size)) { + ksft_test_result_pass("The case: %s.\n", case_name2); + } else { + ksft_test_result_fail("The case: %s.\n", case_name2); + } + + /* The parent process xstate should not change after context switch. */ + compare_buf_result(valid_xbuf, compared_xbuf, case_name3); +} + static void prepare_xstate_test(void) { xstate_test_array_init(XFEATURE_FP, init_legacy_info, @@ -153,6 +172,7 @@ static void prepare_xstate_test(void) fill_pkru_xstate_buf); xstate_tests[XSTATE_CASE_SIG].xstate_case = test_xstate_sig_handle; + xstate_tests[XSTATE_CASE_FORK].xstate_case = test_xstate_fork; } static void test_xstate(void) diff --git a/tools/testing/selftests/x86/xstate.h b/tools/testing/selftests/x86/xstate.h index a60429591c49..17e0f7b17a6e 100644 --- a/tools/testing/selftests/x86/xstate.h +++ b/tools/testing/selftests/x86/xstate.h @@ -87,6 +87,7 @@ enum supportability { enum xstate_case { XSTATE_CASE_SIG, + XSTATE_CASE_FORK, XSTATE_CASE_MAX, }; diff --git a/tools/testing/selftests/x86/xstate_helpers.c b/tools/testing/selftests/x86/xstate_helpers.c index 0f88f56f839e..406d7330e2ae 100644 --- a/tools/testing/selftests/x86/xstate_helpers.c +++ b/tools/testing/selftests/x86/xstate_helpers.c @@ -158,3 +158,54 @@ bool xstate_sig_handle(void *valid_xbuf, void *compared_xbuf, uint64_t mask, return sigusr1_done; } + +bool xstate_fork(void *valid_xbuf, void *compared_xbuf, uint64_t mask, + uint32_t xstate_size) +{ + pid_t child; + int status, fd[2]; + bool child_result; + + memset(compared_xbuf, 0, xstate_size); + /* Use pipe to transfer test result to parent process. */ + if (pipe(fd) < 0) + fatal_error("create pipe failed"); + /* + * Xrstor the valid_xbuf and call syscall assembly instruction, then + * save the xstate to compared_xbuf in child process for comparison. + */ + __xrstor(valid_xbuf, mask); + child = __fork(); + if (child < 0) { + /* Fork syscall failed */ + fatal_error("fork failed"); + } else if (child == 0) { + /* Fork syscall succeeded, now in the child. */ + __xsave(compared_xbuf, mask); + + if (memcmp(valid_xbuf, compared_xbuf, xstate_size)) + child_result = false; + else + child_result = true; + + /* + * Transfer the child process test result to + * the parent process for aggregation. + */ + close(fd[0]); + if (!write(fd[1], &child_result, sizeof(child_result))) + fatal_error("write fd failed"); + _exit(0); + } else { + /* Fork syscall succeeded, now in the parent. */ + __xsave(compared_xbuf, mask); + if (waitpid(child, &status, 0) != child || !WIFEXITED(status)) { + fatal_error("Child exit with error status"); + } else { + close(fd[1]); + if (!read(fd[0], &child_result, sizeof(child_result))) + fatal_error("read fd failed"); + return child_result; + } + } +} diff --git a/tools/testing/selftests/x86/xstate_helpers.h b/tools/testing/selftests/x86/xstate_helpers.h index 1806c0bf484b..307781708ffa 100644 --- a/tools/testing/selftests/x86/xstate_helpers.h +++ b/tools/testing/selftests/x86/xstate_helpers.h @@ -6,3 +6,5 @@ extern void fill_fp_mxcsr_xstate_buf(void *buf, int xfeature_num, uint8_t ui8_fp); extern bool xstate_sig_handle(void *valid_xbuf, void *compared_xbuf, uint64_t mask, uint32_t xstate_size); +extern bool xstate_fork(void *valid_xbuf, void *compared_xbuf, + uint64_t mask, uint32_t xstate_size); -- 2.31.1