From nobody Sun Feb 8 12:20:22 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E967EC6FD1C for ; Wed, 22 Mar 2023 18:09:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230463AbjCVSJP (ORCPT ); Wed, 22 Mar 2023 14:09:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52172 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230375AbjCVSJK (ORCPT ); Wed, 22 Mar 2023 14:09:10 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B7EF464A98; Wed, 22 Mar 2023 11:09:07 -0700 (PDT) Date: Wed, 22 Mar 2023 18:09:04 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1679508545; h=from:from:sender:sender:reply-to: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; bh=SG/WFdrtGeY3OOZAAMBgQN8FHAobrrdu1VyyimCtxig=; b=UeBIyCkn3wsOjYm5QViLum6ho1kuOhNulszBT+JCn40RhWrpObTOATRT1NVJha+hDXGxaV QlzZzuyxiiHC6enpNcUNVzvQ9cHZzo5IE6QRJ9ezFHaoMXCLQPG7Nkua//D1xyP1h2rrpx x9ESMejXjinJRhh6vhkH2X/JwzAX20Eh9Vg7PCTxxYIv70q638uUp12Ttc09hG84Y6aWG4 qFLGdOe0lFNIi8kOI8nvWD4UulLA/uTYIBh7sPz1A/ECFMyY5NT49/AKF7N6BhQDkuOay9 gLj85K6Wc4ve5fEkqbuTY5ajln27Xwb0Gksfsyx4URzZ19jabNJjAYrwnk/nVg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1679508545; h=from:from:sender:sender:reply-to: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; bh=SG/WFdrtGeY3OOZAAMBgQN8FHAobrrdu1VyyimCtxig=; b=mvcukl2sdYRGUpH1qz6sUiI6hkUojdkTNGzeG4Hrzepo6TokurMUKUWr8UmaGJLpwAixL4 NHx/bK3MGYpMysCw== From: "tip-bot2 for Chang S. Bae" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: x86/urgent] selftests/x86/amx: Add a ptrace test Cc: "Chang S. Bae" , Dave Hansen , stable@vger.kernel.org, x86@kernel.org, linux-kernel@vger.kernel.org MIME-Version: 1.0 Message-ID: <167950854480.5837.16057789901697956970.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The following commit has been merged into the x86/urgent branch of tip: Commit-ID: 62faca1ca10cc84e99ae7f38aa28df2bc945369b Gitweb: https://git.kernel.org/tip/62faca1ca10cc84e99ae7f38aa28df2bc= 945369b Author: Chang S. Bae AuthorDate: Mon, 27 Feb 2023 13:05:04 -08:00 Committer: Dave Hansen CommitterDate: Wed, 22 Mar 2023 11:00:49 -07:00 selftests/x86/amx: Add a ptrace test Include a test case to validate the XTILEDATA injection to the target. Also, it ensures the kernel's ability to copy states between different XSAVE formats. Refactor the memcmp() code to be usable for the state validation. Signed-off-by: Chang S. Bae Signed-off-by: Dave Hansen Cc: stable@vger.kernel.org Link: https://lore.kernel.org/all/20230227210504.18520-3-chang.seok.bae%40i= ntel.com --- tools/testing/selftests/x86/amx.c | 108 ++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/x86/amx.c b/tools/testing/selftests/x8= 6/amx.c index 625e429..d884fd6 100644 --- a/tools/testing/selftests/x86/amx.c +++ b/tools/testing/selftests/x86/amx.c @@ -14,8 +14,10 @@ #include #include #include +#include #include #include +#include =20 #include "../kselftest.h" /* For __cpuid_count() */ =20 @@ -583,6 +585,13 @@ static void test_dynamic_state(void) _exit(0); } =20 +static inline int __compare_tiledata_state(struct xsave_buffer *xbuf1, str= uct xsave_buffer *xbuf2) +{ + return memcmp(&xbuf1->bytes[xtiledata.xbuf_offset], + &xbuf2->bytes[xtiledata.xbuf_offset], + xtiledata.size); +} + /* * Save current register state and compare it to @xbuf1.' * @@ -599,9 +608,7 @@ static inline bool __validate_tiledata_regs(struct xsav= e_buffer *xbuf1) fatal_error("failed to allocate XSAVE buffer\n"); =20 xsave(xbuf2, XFEATURE_MASK_XTILEDATA); - ret =3D memcmp(&xbuf1->bytes[xtiledata.xbuf_offset], - &xbuf2->bytes[xtiledata.xbuf_offset], - xtiledata.size); + ret =3D __compare_tiledata_state(xbuf1, xbuf2); =20 free(xbuf2); =20 @@ -826,6 +833,99 @@ static void test_context_switch(void) free(finfo); } =20 +/* Ptrace test */ + +/* + * Make sure the ptracee has the expanded kernel buffer on the first + * use. Then, initialize the state before performing the state + * injection from the ptracer. + */ +static inline void ptracee_firstuse_tiledata(void) +{ + load_rand_tiledata(stashed_xsave); + init_xtiledata(); +} + +/* + * Ptracer injects the randomized tile data state. It also reads + * before and after that, which will execute the kernel's state copy + * functions. So, the tester is advised to double-check any emitted + * kernel messages. + */ +static void ptracer_inject_tiledata(pid_t target) +{ + struct xsave_buffer *xbuf; + struct iovec iov; + + xbuf =3D alloc_xbuf(); + if (!xbuf) + fatal_error("unable to allocate XSAVE buffer"); + + printf("\tRead the init'ed tiledata via ptrace().\n"); + + iov.iov_base =3D xbuf; + iov.iov_len =3D xbuf_size; + + memset(stashed_xsave, 0, xbuf_size); + + if (ptrace(PTRACE_GETREGSET, target, (uint32_t)NT_X86_XSTATE, &iov)) + fatal_error("PTRACE_GETREGSET"); + + if (!__compare_tiledata_state(stashed_xsave, xbuf)) + printf("[OK]\tThe init'ed tiledata was read from ptracee.\n"); + else + printf("[FAIL]\tThe init'ed tiledata was not read from ptracee.\n"); + + printf("\tInject tiledata via ptrace().\n"); + + load_rand_tiledata(xbuf); + + memcpy(&stashed_xsave->bytes[xtiledata.xbuf_offset], + &xbuf->bytes[xtiledata.xbuf_offset], + xtiledata.size); + + if (ptrace(PTRACE_SETREGSET, target, (uint32_t)NT_X86_XSTATE, &iov)) + fatal_error("PTRACE_SETREGSET"); + + if (ptrace(PTRACE_GETREGSET, target, (uint32_t)NT_X86_XSTATE, &iov)) + fatal_error("PTRACE_GETREGSET"); + + if (!__compare_tiledata_state(stashed_xsave, xbuf)) + printf("[OK]\tTiledata was correctly written to ptracee.\n"); + else + printf("[FAIL]\tTiledata was not correctly written to ptracee.\n"); +} + +static void test_ptrace(void) +{ + pid_t child; + int status; + + child =3D fork(); + if (child < 0) { + err(1, "fork"); + } else if (!child) { + if (ptrace(PTRACE_TRACEME, 0, NULL, NULL)) + err(1, "PTRACE_TRACEME"); + + ptracee_firstuse_tiledata(); + + raise(SIGTRAP); + _exit(0); + } + + do { + wait(&status); + } while (WSTOPSIG(status) !=3D SIGTRAP); + + ptracer_inject_tiledata(child); + + ptrace(PTRACE_DETACH, child, NULL, NULL); + wait(&status); + if (!WIFEXITED(status) || WEXITSTATUS(status)) + err(1, "ptrace test"); +} + int main(void) { /* Check hardware availability at first */ @@ -846,6 +946,8 @@ int main(void) ctxtswtest_config.num_threads =3D 5; test_context_switch(); =20 + test_ptrace(); + clearhandler(SIGILL); free_stashed_xsave();