Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp2841001pxj; Sun, 23 May 2021 12:42:00 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxP/z0yxnOomJGmF1Ri40yYldeG6ylzgG1QwMf8//Ii9gLT1qRF+F+d8KD2hBu1hGmYiBbm X-Received: by 2002:a02:aa85:: with SMTP id u5mr21143016jai.75.1621798920141; Sun, 23 May 2021 12:42:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621798920; cv=none; d=google.com; s=arc-20160816; b=neNpm1KOlMMudeAdLlzzx96Nyijzo7cRA+Hjk+GpYbHcg/cGY/m6W24nJwdZabfbtH mtR0MSy7Ut/W599O+0MhNA/HGoW5BI7vVm0/Mtk0UtLrVf72Qs8+2UmO+Tdn6O4AKjox KODBZD72vq6oqvUvu2gPEHhcc0ym3oJ05Ck3xbKz+T1v5ARpk0A3ZUncqyM3D2RLGJGa cwy44hj2A940Qw3Uu6n+ESCeGyDpvk6ZovOfsIEq6mJ/xgMLwbgFiuDobzlFUbrW19Qn MnWC4jVAMH/NiXbD69NrX2grJQs4uuSBW5QM4E/G6I5T5iX7eUwlkDg0NH763BAVzEfO IhNA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from:ironport-sdr:ironport-sdr; bh=I+5feIt4r5lUdzc9krVIcPvY7doH2FEzPM2pp+bWuLE=; b=K4DRDDiKrgAj3b5+y7o3PxJrk0XfMEFNu1r5+3kXY0oxIkMLp/8hZlCJYBmmKC2PiD DnnqIzDRU4BUf0iPKKf5EH2EgQpjHY6yIvzoXDgwzNGDbbmwF0JLCt/+gbur690Z3vMI TFtsNgxka3wRatKmRY6lOOloxdaUWoVEfMe8wwzU59c+T7KAZ85MsWeQXTt4wxFlLVOy eBEbBxbNK46EsHMINz2h/V5Xk+fYqUvZlus3FCX/NC4jQDL9l7b4ZRLamidSSZweA4vf df4hgc3xSVhBPzwitcfy2eva35HjOEv7j6Q0OS/s+7GZosUERYy0pxmuzk633DEzmr4M WjzA== ARC-Authentication-Results: i=1; mx.google.com; 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=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id j22si4735879jat.22.2021.05.23.12.41.47; Sun, 23 May 2021 12:42:00 -0700 (PDT) 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; 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=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232333AbhEWTky (ORCPT + 99 others); Sun, 23 May 2021 15:40:54 -0400 Received: from mga11.intel.com ([192.55.52.93]:32000 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232002AbhEWTj6 (ORCPT ); Sun, 23 May 2021 15:39:58 -0400 IronPort-SDR: 03jaEIoJwxFsz+5d7GFC8cl4wMViHAsZG3wZCsCjjd6/U+d2ev0kxzwuhsOa4lwCaX1BV3/c2p 9eElUdPmZ6CQ== X-IronPort-AV: E=McAfee;i="6200,9189,9993"; a="198740688" X-IronPort-AV: E=Sophos;i="5.82,319,1613462400"; d="scan'208";a="198740688" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 May 2021 12:38:30 -0700 IronPort-SDR: gdaFYesCiXuhSHARjLHPrjWPQ4SKnYxedOUGqBoDhH3KMOjs1IoWTekLYsIoRi7aXEGgP5dNJA DGygdcfyox4A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.82,319,1613462400"; d="scan'208";a="407467146" Received: from chang-linux-3.sc.intel.com ([172.25.66.175]) by fmsmga007.fm.intel.com with ESMTP; 23 May 2021 12:38:29 -0700 From: "Chang S. Bae" To: bp@suse.de, luto@kernel.org, tglx@linutronix.de, mingo@kernel.org, x86@kernel.org Cc: len.brown@intel.com, dave.hansen@intel.com, jing2.liu@intel.com, ravi.v.shankar@intel.com, linux-kernel@vger.kernel.org, chang.seok.bae@intel.com, linux-kselftest@vger.kernel.org Subject: [PATCH v5 26/28] selftest/x86/amx: Test case for AMX state copy optimization in signal delivery Date: Sun, 23 May 2021 12:32:57 -0700 Message-Id: <20210523193259.26200-27-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210523193259.26200-1-chang.seok.bae@intel.com> References: <20210523193259.26200-1-chang.seok.bae@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add a test case to verify that unused states are excluded, by leaving a known pattern on the signal stack and verifying that it is still intact after taking a subsequent signal. Signed-off-by: Chang S. Bae Reviewed-by: Len Brown Cc: x86@kernel.org Cc: linux-kernel@vger.kernel.org Cc: linux-kselftest@vger.kernel.org --- Changes from v4: * Separated out as a new patch. * Improved the test routine by explicitly checking sigframe write. --- tools/testing/selftests/x86/amx.c | 137 ++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/tools/testing/selftests/x86/amx.c b/tools/testing/selftests/x86/amx.c index 7d177c03cdcf..c5a5582e2b6f 100644 --- a/tools/testing/selftests/x86/amx.c +++ b/tools/testing/selftests/x86/amx.c @@ -562,6 +562,142 @@ static void test_ptrace(void) test_tile_write(); } +/* Signal handling test */ + +static bool init_tiledata_state_before_signal; +static bool load_tiledata_at_first; +static bool sigalarmed, sigused; + +#define SIGFRAME_TILEDATA_SIGNATURE 0xFF + +static void handle_sigusr1(int sig, siginfo_t *info, void *ctx_void) +{ + void *xsave = ((ucontext_t *)ctx_void)->uc_mcontext.fpregs; + + memset(xsave + xsave_xtiledata_offset, SIGFRAME_TILEDATA_SIGNATURE, xsave_xtiledata_size); + + sigused = true; +} + +static void handle_sigalrm(int sig, siginfo_t *info, void *ctx_void) +{ + void *xsave = ((ucontext_t *)ctx_void)->uc_mcontext.fpregs; + char d = SIGFRAME_TILEDATA_SIGNATURE; + bool written = false; + int i; + + for (i = 0; i < xsave_xtiledata_size; i++) { + written = memcmp(xsave + xsave_xtiledata_offset + i, &d, 1); + if (written) + break; + } + + if (__xgetbv(1) & XFEATURE_MASK_XTILEDATA) + err(1, "tile data state at signal delivery"); + + if (init_tiledata_state_before_signal && written) { + errs++; + printf("[FAIL]\tTile data was %swritten on sigframe.\n", !written ? "not " : ""); + } + + set_xstatebv(xsave_buffer, XFEATURE_MASK_XTILEDATA); + set_tiledata(xsave_buffer + xsave_xtiledata_offset); + xrstor(xsave_buffer, -1, -1); + sigalarmed = true; +} + +static void test_signal_handling(void) +{ + pid_t child; + + sigalarmed = false; + sigused = false; + + child = fork(); + if (child < 0) { + err(1, "fork"); + } else if (child > 0) { + do { + int status; + + wait(&status); + if (WIFSTOPPED(status)) + kill(child, SIGCONT); + else if (WIFEXITED(status) && !WEXITSTATUS(status)) + break; + else + err(1, "signal test child"); + } while (1); + return; + } + + printf("\tBefore signal, load tile data -- %s, re-initialized -- %s:\n", + load_tiledata_at_first ? "yes" : "no", + init_tiledata_state_before_signal ? "yes" : "no"); + + syscall(SYS_arch_prctl, ARCH_GET_XSTATE, XFEATURE_MASK_XTILE); + + raise(SIGUSR1); + if (!sigused) + err(1, "SIGUSR1"); + + if (load_tiledata_at_first) { + set_xstatebv(xsave_buffer, XFEATURE_MASK_XTILEDATA); + set_tiledata(xsave_buffer + xsave_xtiledata_offset); + xrstor(xsave_buffer, -1, -1); + memcpy(tiledata, xsave_buffer + xsave_xtiledata_offset, xsave_xtiledata_size); + } + + if (init_tiledata_state_before_signal) { + set_xstatebv(xsave_buffer, 0); + xrstor(xsave_buffer, -1, -1); + memset(tiledata, 0, xsave_xtiledata_size); + } + + raise(SIGALRM); + if (!sigalarmed) + err(1, "SIGALRM"); + + __xsave(xsave_buffer, XFEATURE_MASK_XTILEDATA, 0); + if (memcmp(tiledata, xsave_buffer + xsave_xtiledata_offset, xsave_xtiledata_size)) { + errs++; + printf("[FAIL]\tTile data was not restored at sigreturn\n"); + } + + if (errs) + nerrs++; + else + printf("[OK]\tTile data was %swritten on sigframe and restored at sigreturn\n", + init_tiledata_state_before_signal ? "not " : ""); + _exit(0); +} + +static void test_signal(void) +{ + printf("[RUN]\tCheck tile data state in signal path:\n"); + + sethandler(SIGALRM, handle_sigalrm, 0); + sethandler(SIGUSR1, handle_sigusr1, 0); + + load_tiledata_at_first = false; + init_tiledata_state_before_signal = true; + errs = 0; + test_signal_handling(); + + load_tiledata_at_first = true; + init_tiledata_state_before_signal = false; + errs = 0; + test_signal_handling(); + + load_tiledata_at_first = true; + init_tiledata_state_before_signal = true; + errs = 0; + test_signal_handling(); + + clearhandler(SIGALRM); + clearhandler(SIGUSR1); +} + int main(void) { /* Check hardware availability at first */ @@ -592,6 +728,7 @@ int main(void) test_fork(); test_context_switch(); test_ptrace(); + test_signal(); clearhandler(SIGSEGV); -- 2.17.1