From nobody Tue Sep 30 18:37:56 2025 Received: from CO1PR03CU002.outbound.protection.outlook.com (mail-westus2azon11010034.outbound.protection.outlook.com [52.101.46.34]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 16FED1F16B; Tue, 23 Sep 2025 05:10:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.46.34 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604221; cv=fail; b=C7PH56puaFPgbS7eM9TDzASfDgkqh+Opa/f+i5bpRPlEGsm11tqw3S1watZTpWROTLVJlMqhMS4r2n5LKzpO+cD+ivCBQUBcGA59NDdh4lCJXKiSOotM89HUO11JefjqBxKfPwAS4cUo0CsIq+Aim8No4N0fnnWgqaPh+kyTAF0= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604221; c=relaxed/simple; bh=UMNZLlSMbh/iYLAkfLQTuaB0nAXrzX6CEG0P9g6nlEY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Lx3bveeMqgb44JVNVXyWiL0S/SI1zy6vxlRh45j39sigCmIZo9bMLoVGVEntEL/4o7q4ZBJOMvcNLqlff6RKPIGvRwDRHvH0Wf6998SqwAJ8VNn97OXiA6I33VeNsch0RUR1DqOCyapIlzP9+iDC8WvaOI4N7TNz6vTuZ5mz3zo= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=ClyBV+XA; arc=fail smtp.client-ip=52.101.46.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="ClyBV+XA" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=EXVn441nQNGkfxly974LcfmmpInaSL73QQnfBYpuviTqRzzrM/YXloYLG8gUPxIQPxJK/tkfto85OIKedSzxm4EK6nCRORCJLfvawqcMkK44waJhP1Kttqv4mOGlShueHyuJNfO7mjP+Y7Lzxs0pnLz3ACg3TLGIuxtBSSRhK3b9oIgO7+gxyb7EU5qQpwKkohQAO9+/gFcsz0yOeB7GJS0GUAKxgjRRBsi/1elULq5OrNBWbHtIWWSniWChLZSVdqxgoE6Ppc3NnVM6CDxs1y2nBg1N70wjh9dwp4oxdry6hU8JTMXKsXewqSG0WQGp6ChDZ1rvsg7Bi4ApnUh0cg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ipbmMEFgDc0dbI7doanDN8mcBqNvyMhS6QosGwi1E1E=; b=vXzuDq7CTLMaLQuvrgFB36MmC+6vM1R5g6I+Kdwv5KNhaDXuMJqmOegQQAsr/VvtJmqx7A9Z/mV3TxlD4f8CD8pYVrv7gy8sJLdGN4iz2aJqUieoDjqFfNTNy242SsJRXb95T0e75GU6mRK13w+qDDsEUErZ4GboMOmAtk67+2QdESSYYIhXEWeXeNdQ3rpNb8eUFz12wkxsPOUaMJ5PgZKngQJLfJsFPlmFrAFGM8CaNN/TTppFDDoh5tCPrQzBZNRmTOBOl4Q9gdO+ojupdWDjGnqhf5TM4G8vdbc/U3pCx+IiASa8Y84fkXfJkjj/haCLqOFHjP3Ih7RbB7wgEA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ipbmMEFgDc0dbI7doanDN8mcBqNvyMhS6QosGwi1E1E=; b=ClyBV+XAFZgBXMOeHweeV6f733mt38tqylP7DQhbtmsq1hmhdMheYcpWvmhlQz0pzBa0mfcM65xDw17/9qBtWKO2xHxjM2iKpKEGNfd2imutTKwRqlOWlwRAKsk2J7Dnuro3I+AnHkK7RqHxiTNhp79bXTLrSEvx4+QD1U9kIRQ= Received: from BN9PR03CA0346.namprd03.prod.outlook.com (2603:10b6:408:f6::21) by MW6PR12MB8915.namprd12.prod.outlook.com (2603:10b6:303:23e::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.19; Tue, 23 Sep 2025 05:10:13 +0000 Received: from BL6PEPF00020E5F.namprd04.prod.outlook.com (2603:10b6:408:f6:cafe::7c) by BN9PR03CA0346.outlook.office365.com (2603:10b6:408:f6::21) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:10:13 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by BL6PEPF00020E5F.mail.protection.outlook.com (10.167.249.20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:10:13 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:10:08 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 01/35] Add GHCB with setters and getters Date: Tue, 23 Sep 2025 10:39:08 +0530 Message-ID: <20250923050942.206116-2-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BL6PEPF00020E5F:EE_|MW6PR12MB8915:EE_ X-MS-Office365-Filtering-Correlation-Id: 41e4f126-52b3-4177-3df8-08ddfa5f7a2f X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700013|376014|1800799024|82310400026|7053199007; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?kp7VsGn33VtrZ9lEaUMyBrpZPpwcrv0wU4wqEmaoSF0BFqmqfwd5d46zCCNP?= =?us-ascii?Q?Y59/seP9cp+7RnssC06AtIdu1XAdkEXwbkLiLBajIUgGIlikMOtDe313GlhD?= =?us-ascii?Q?A1DY+9HqkCcRDLvlHhcetYFyC0UdnQYEo1eRTng3ehshA8c/QU4k9k7lJQYn?= =?us-ascii?Q?aPRxgtVupuXWiu+uw473PFbsqBRhiOp5bhUwUoJ2vSDTD1YkZ8UpppMD1foU?= =?us-ascii?Q?ZNSAJriBY21bHk4ogglrSttSo9S/Hnvs6rDFRfqdrrKvhmEVjUDtNy+21aEY?= =?us-ascii?Q?NrZHQfwEuCAlXgH/7z+0Ta83NolVPu3dpmKQ4YwI0BPXqBIVDJpdpPdo7QUZ?= =?us-ascii?Q?v0++Vkc5wuVrWKLxi0G+SxHwxtHbSFVefgCVF2fYqsMMjnkmixPVksDDtcRv?= =?us-ascii?Q?eG+w8DlZc3JoiKvEVi+6gzm8QG5L0FvGsMWyQQ8MR8F3udSc6g7z25K+i8WO?= =?us-ascii?Q?mO/R07JiSkfjlm7KErdpGt4UJ+QmyC0voKcUMtRoO/sm7WJfD7UeCUW2ZBzj?= =?us-ascii?Q?ZLe7LqB+XYxiEDh1EVm6kHbPCmdR5Mu3MUE7X4B/kxusTdnnNIHe6HIy5dUA?= =?us-ascii?Q?6vNTE/SRDbJhLGbtghvJGsEIwOIKdgJyzAIRxUTDGLTIzE5mZSejDsfGL/mz?= =?us-ascii?Q?2N4UNrhvueBsHjdItmq4OjhnGg1BwsaviRKr6aFz3FuL2WouxW2R3oy0rLsi?= =?us-ascii?Q?gr2TJrIolcs9wy/MPHRyW0vqyN1OfO6U9C9sSD/+En0W0aHGuFuIdmzt3tsL?= =?us-ascii?Q?pm2Un5F2OWOaERAGU4FjRwG4rPcTrwIv7JoDGFFxw295xSoFhBkVO41Hbzu2?= =?us-ascii?Q?KLyT/18Qj995sygaR72fkSPcYJ5tvW0ueJ7Mpe7Qwg+3KfnTH5NfuN4RnZTA?= =?us-ascii?Q?LJq/xEcRbm56J3eFR0zE/DP/cJZ1dFdEA8EbpULWmXXpOfmBxiX2kisq04WB?= =?us-ascii?Q?TCVkXHJriikmRjG1yNVjQHQ9COrAI8fnBfPdQ386FO2McEuMgsPe8p9FAAHH?= =?us-ascii?Q?Kjeqhqn3jmErB2m/n7SKyI23GGwgSeNFG3XzS+IAItsmU75AYaqbMIXAflaP?= =?us-ascii?Q?RsPEwUR1ay+JgaQaxBI0T73+PLQaNrovvoqKcchVqF8iRiRqqEUPPNVzkjl2?= =?us-ascii?Q?wJ1gPbPvhLUkwq2TUDjGgTkbL+ILSf5qsWr09krWeZDwDgD5ufNDkj+2r2eT?= =?us-ascii?Q?G073N60vk0JSKaAFoMpq1USL5treI+/pK0uBI+Fi9Qky1BChf7oPkKo2jZ9H?= =?us-ascii?Q?wQwuI0Yx01g8Z/Wz+s50W56PqpjZMWXFCL3+iIQlswZjmUs5m2euNvTZYWTi?= =?us-ascii?Q?C68cAZftTr31elrwvTFebNrjYJJwfZuCEqAEti+Q6T5rov2E5hNOk8js/De9?= =?us-ascii?Q?z/ROnO39z6pXAD5yQq1hS3nlIj7U3Pf5NQlUrZ93icu23Zm+ldZXM6oAjt+h?= =?us-ascii?Q?cut5J1LlDLCht1HGoa+hZ9WNSYkP0olbDncAGJ/ncwJaGEmqX15ZCliJKncn?= =?us-ascii?Q?+BMRZrq1eMhNC5D1+F+hapV4Dvtl7TeRaat8?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(36860700013)(376014)(1800799024)(82310400026)(7053199007);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:10:13.4810 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 41e4f126-52b3-4177-3df8-08ddfa5f7a2f X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: BL6PEPF00020E5F.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MW6PR12MB8915 Content-Type: text/plain; charset="utf-8" From: Peter Gonda Move the GHCB definitions from svm.h to the tools/ copy. This allows the SEV-ES selftest to use GHCBs which are required for non-trival VMs to paravirtualize NonAutomaticExits (NAEs) when SEV-ES is enabled. GHCB getters/setters have a warning with address-of-packed-member, so removed this using the CFLAGS. Cc: Vishal Annapurve Cc: Ackerley Tng Cc: Paolo Bonzini Cc: Claudio Imbrenda Cc: Sean Christopherson Cc: Carlos Bilbao Cc: Tom Lendacky Cc: Michael Roth Cc: kvm@vger.kernel.org Cc: linux-kselftest@vger.kernel.org Signed-off-by: Peter Gonda Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/Makefile.kvm | 2 +- tools/testing/selftests/kvm/include/x86/svm.h | 106 ++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selft= ests/kvm/Makefile.kvm index 90f03f00cb04..6dd8675b4861 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -237,7 +237,7 @@ LINUX_TOOL_ARCH_INCLUDE =3D $(top_srcdir)/tools/arch/$(= ARCH)/include CFLAGS +=3D -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=3Dgnu99 \ -Wno-gnu-variable-sized-type-not-at-end -MD -MP -DCONFIG_64BIT \ -fno-builtin-memcmp -fno-builtin-memcpy \ - -fno-builtin-memset -fno-builtin-strnlen \ + -fno-builtin-memset -fno-builtin-strnlen -Wno-address-of-packed-member \ -fno-stack-protector -fno-PIE -fno-strict-aliasing \ -I$(LINUX_TOOL_INCLUDE) -I$(LINUX_TOOL_ARCH_INCLUDE) \ -I$(LINUX_HDR_PATH) -Iinclude -I$(save.valid_bitmap); \ + } \ + \ + static __always_inline u64 ghcb_get_##field(struct ghcb *ghcb) \ + { \ + return ghcb->save.field; \ + } \ + \ + static __always_inline u64 ghcb_get_##field##_if_valid(struct ghcb *ghcb)= \ + { \ + return ghcb_##field##_is_valid(ghcb) ? ghcb->save.field : 0; \ + } \ + \ + static __always_inline void ghcb_set_##field(struct ghcb *ghcb, u64 value= ) \ + { \ + __set_bit(GHCB_BITMAP_IDX(field), \ + (unsigned long *)&ghcb->save.valid_bitmap); \ + ghcb->save.field =3D value; \ + } + +DEFINE_GHCB_ACCESSORS(cpl) +DEFINE_GHCB_ACCESSORS(rip) +DEFINE_GHCB_ACCESSORS(rsp) +DEFINE_GHCB_ACCESSORS(rax) +DEFINE_GHCB_ACCESSORS(rcx) +DEFINE_GHCB_ACCESSORS(rdx) +DEFINE_GHCB_ACCESSORS(rbx) +DEFINE_GHCB_ACCESSORS(rbp) +DEFINE_GHCB_ACCESSORS(rsi) +DEFINE_GHCB_ACCESSORS(rdi) +DEFINE_GHCB_ACCESSORS(r8) +DEFINE_GHCB_ACCESSORS(r9) +DEFINE_GHCB_ACCESSORS(r10) +DEFINE_GHCB_ACCESSORS(r11) +DEFINE_GHCB_ACCESSORS(r12) +DEFINE_GHCB_ACCESSORS(r13) +DEFINE_GHCB_ACCESSORS(r14) +DEFINE_GHCB_ACCESSORS(r15) +DEFINE_GHCB_ACCESSORS(sw_exit_code) +DEFINE_GHCB_ACCESSORS(sw_exit_info_1) +DEFINE_GHCB_ACCESSORS(sw_exit_info_2) +DEFINE_GHCB_ACCESSORS(sw_scratch) +DEFINE_GHCB_ACCESSORS(xcr0) + #endif /* SELFTEST_KVM_SVM_H */ --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from DM5PR21CU001.outbound.protection.outlook.com (mail-centralusazon11011050.outbound.protection.outlook.com [52.101.62.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9114321ADB7; Tue, 23 Sep 2025 05:10:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.62.50 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604238; cv=fail; b=bi+SnPxnG7dQewxphMDYkFtySWkA6JTD6BdFKLbuZuabqKPf7VQVJct6lhajOWx0uB3vVcd/EvS7abFB/r9Dh07TLQJbnvzgA4LfYEYWfeLOKcbK6sL1nYkUWGVDvFTaXyKonUCwVtwBn7jzQ75M5Wq2EF3u1N1z6LPee+XNZIw= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604238; c=relaxed/simple; bh=oZMmjYLHNuTF7WJbt9PZJKcPOn15sIqngRWndXWj6XM=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=H9vrNCb+gxFQrHwhIzSdwQOAv0o4wXpP8awYfmaNvNu86QEwGKRdRzNALHDWj2DzHWJSZQaVVuviKy/e33goM5aklWat+QRd70JUMYs533J2oTHqPDyDz1BSQhByPyr7Q7g+Mg88Osmq6Y2aLLh2RG9qKTMT+jYbdeFP7OQptEs= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=Zn3UGlvn; arc=fail smtp.client-ip=52.101.62.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="Zn3UGlvn" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=xh1xSz/Dm2+sYysJJooWgBYDA+dQJDyUUIKMcojLdFjrl28IYKD4NnprAR03QT2tmfhF31WEGKk774ZWIXEh5DWCkDwEsbquMrqYphsPNXDwhasA/xQuFuAU2bVDPFOgaT6Gdxnf1glBbG9zq0h8adra9F+0sw+X4LW3psEPaDOu9p1vu/vAzY2LVkS1sKlGF/4RUv7ss9UqllsiCihWtUZ1VWW2DJ6K5raqWmwu2Ym7TTYehlxizsqpGwKRw6UKBQHTY8eeZftqQuAnOE/B7coR96axNf2ixmIWrcyimhrl5EZCiFLFeB9Fl8fZz1ps0c6Coc7eY3JtKBz/oPUSRg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ZWQm7MM0g4gyxYiUW//6l6eGc/FVBp1S8fCKd1LcCYU=; b=cWGD7SIayrg2qqpx0Ex1kfLdz0WKqua86pedYbmjXtyV5DZTFqRwzwENvKjfLUquNev2NCKH/B/BtbiuaCuB2NufF0Wr9bh2ismOwPbT19iB7sM1GWdjLSd+glBO+TLmjIBnqQcV3Ag7/Dj3l1k6eSPZrVKCQKN6p7M+IC0DSSEfznfH61tzGMiCWtWfcNWpwq1/9STyKSa04iKyo4KteYwphwCmkyODTwxTBoOix6BpE0QXmjh8BMtlrAc3bGCBCplR5eM4QgtSNKJpPGENglSoGEIN3YvmB9PpejpcY14En5DIxltm84hFuWTevKuU9tqcC5fwfx94kqTxYI7u2w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ZWQm7MM0g4gyxYiUW//6l6eGc/FVBp1S8fCKd1LcCYU=; b=Zn3UGlvnO7p2U2xHmrEZoidM3Mp7FJfrVFCuceqaWrNDkW6G/2OfL9gOSF3jpH67BtgJ5/tox0aSl/JaylzUZpv3mxcMOxosqudrvUr4lmGx6axv9KgVW0SqXykLSHT7aZpE7jq7X3XnNbrOvN9LL2wnVYC63HQO6usxyhRuLgQ= Received: from CH0PR03CA0379.namprd03.prod.outlook.com (2603:10b6:610:119::6) by CY5PR12MB6155.namprd12.prod.outlook.com (2603:10b6:930:25::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.20; Tue, 23 Sep 2025 05:10:30 +0000 Received: from CH2PEPF00000143.namprd02.prod.outlook.com (2603:10b6:610:119:cafe::dc) by CH0PR03CA0379.outlook.office365.com (2603:10b6:610:119::6) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.19 via Frontend Transport; Tue, 23 Sep 2025 05:10:30 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF00000143.mail.protection.outlook.com (10.167.244.100) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:10:30 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:10:25 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 02/35] Add arch specific additional guest pages Date: Tue, 23 Sep 2025 10:39:09 +0530 Message-ID: <20250923050942.206116-3-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF00000143:EE_|CY5PR12MB6155:EE_ X-MS-Office365-Filtering-Correlation-Id: 0381224c-6ae7-4e4c-e4b5-08ddfa5f8468 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|36860700013|82310400026|376014|7053199007; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?jPPTD3PVEZcSRuY4su3Xn/FwuBI9CQT5eLHWREYK8GNhdT93wihHq8jZCSXs?= =?us-ascii?Q?V1IWxvpSTz27yPEpaYmTPDeFC99LY0HsALZJQGAtVTbUwYZHEe/0i/kAugE3?= =?us-ascii?Q?zr4J8jQVpphP/cq5V3JP8Njdf3UpdgMbU81kpMkrmUahz0ONTiSnC/tS483G?= =?us-ascii?Q?1hSzszQHTJsTdW+vwlKy0qT/ko93/J7XW0inP27EHJUwXsgPX8dDmuX8E9n/?= =?us-ascii?Q?EASTrVhqS30VCZiRr/XWG9wxTvRdBFXYzDLjlfGZTNnip6TahE6+VFhe3K0o?= =?us-ascii?Q?LbhtazQ77Uj1A6l1C0moNRoO7FFaHb5E083sUrrt/1rgZWTABZC2/2xDL7Kc?= =?us-ascii?Q?tu46YPNKTDTaOb1c2Ssnd7D/g1kXmZ/eziamElWZf6OdFncaZzlIgSz78SHa?= =?us-ascii?Q?oHX2jM1Qnta+BXowcNsF6u9hhCvWHvWJEHmXIjtUBnqMROJ9Y5LYOLVMABge?= =?us-ascii?Q?pUPRRB5dTumDyeqkNlOMM4hvZn6AlHIa/LwUhkOzI815cScZGuy9P9iMAgSV?= =?us-ascii?Q?exMKJu4Dd4wuS1V4yHqZCjjkPqtxHzn4Xe4gwAvlGDVkgnw4A6jpm/IUFThV?= =?us-ascii?Q?F1IrOq7MrPUIoKIxVBZmpKvjcim5kYVY6GELB3mYH9fphzTp+Ru0+vkFUDpg?= =?us-ascii?Q?q+NY3q2NgAFBHThcGha4csEAir2vs3zI1Ue4zl2TaMz7xHZtvvFv+uQAHvC+?= =?us-ascii?Q?SISP1/p+3+GzBi9+UyYbe4LJnD4BlffPnZclsa2/eI2jP2OnkbrO6IU3ln9r?= =?us-ascii?Q?zEOsEJCrsMbe8gmONJ3QACuwMkaw37qE/Z12NrUhdlhMdssvVPRpdNpvvPJX?= =?us-ascii?Q?ePPlvLyjCfiaLPdJK6Fy1uuXuwBlKe+5RNTJr4ZTwA3p2tbereWUfXZp9pZ7?= =?us-ascii?Q?FWROx5O4Oda5IAf7KceLd453YizsmdbllUKx/Y0QyW7COTg/wgA5BKQCldLC?= =?us-ascii?Q?MUc0qvRbjBfyLckfXpMgrsPo58qv0wD5AXslYkze6HQmxpsD05FTRcHtHLSz?= =?us-ascii?Q?OK4j1XiqFaKJ6N6T8SEZqjKzXYkCARllcaC9nSRds1BKL8Jouq8H/caoFAai?= =?us-ascii?Q?hZPejrooMQmQIUVdpD9A/ri1S6P+MGtb3fc2obYOLqzGY0ixdI7tD6PEaOeS?= =?us-ascii?Q?AhL4e1hSZhFvJ7Y62InK9KxWNwUsOVkyKQKjcdWB7yrG9AUfCp7vk3v73TJ0?= =?us-ascii?Q?tblWTRm09rquFswR6ZHkETte69EYczfb2TRMbKCYXjiGT5ZAV8rqnQ75a/Wh?= =?us-ascii?Q?0K4iIx72tW0qqPcMAH1W3cBJB6eKci10N5cWzDsmLM1HgU+7JlNuDKiQv6qk?= =?us-ascii?Q?NKdXm5qeY68Ea3HV+5A0Cmu3h3X2VD0ci532OZ+kwBjT54MJoHrbqaZkU/O5?= =?us-ascii?Q?qboryIZ9VDLBAnPji7tBpf24GhBzyMcIEbRaWmGPTHtbxFUwcAeIxVJOea3W?= =?us-ascii?Q?PcZk5pwlOl6iQu3+pv2sWZFSo7XYpi7f7SdyORIB5fbU8R5Fh88+GoSONGgN?= =?us-ascii?Q?jZbZ6Z9lOWfzoyKw22dfu3wYn9iYYOi2pjzy?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(36860700013)(82310400026)(376014)(7053199007);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:10:30.6245 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 0381224c-6ae7-4e4c-e4b5-08ddfa5f8468 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF00000143.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY5PR12MB6155 Content-Type: text/plain; charset="utf-8" From: Peter Gonda SEV-ES guests need additional pages allocated for their GHCBs. Add arch specific function definition with __weak to allow for overriding for X86 specific SEV-ES functionality. Cc: Vishal Annapurve Cc: Ackerley Tng Cc: Paolo Bonzini Cc: Claudio Imbrenda Cc: Sean Christopherson Cc: Carlos Bilbao Cc: Tom Lendacky Cc: Michael Roth Cc: kvm@vger.kernel.org Cc: linux-kselftest@vger.kernel.org Signed-off-by: Peter Gonda Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/include/kvm_util.h | 2 ++ tools/testing/selftests/kvm/lib/kvm_util.c | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing= /selftests/kvm/include/kvm_util.h index 23a506d7eca3..1a9764658eb9 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -268,6 +268,8 @@ int get_kvm_param_integer(const char *param); int get_kvm_intel_param_integer(const char *param); int get_kvm_amd_param_integer(const char *param); =20 +int kvm_arch_vm_additional_pages_required(struct vm_shape shape, + uint64_t page_size); unsigned int kvm_check_cap(long cap); =20 static inline bool kvm_has_cap(long cap) diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index c3f5142b0a54..a3b16793b2fd 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -391,11 +391,11 @@ struct kvm_vm *____vm_create(struct vm_shape shape) return vm; } =20 -static uint64_t vm_nr_pages_required(enum vm_guest_mode mode, +static uint64_t vm_nr_pages_required(struct vm_shape shape, uint32_t nr_runnable_vcpus, uint64_t extra_mem_pages) { - uint64_t page_size =3D vm_guest_mode_params[mode].page_size; + uint64_t page_size =3D vm_guest_mode_params[shape.mode].page_size; uint64_t nr_pages; =20 TEST_ASSERT(nr_runnable_vcpus, @@ -427,7 +427,9 @@ static uint64_t vm_nr_pages_required(enum vm_guest_mode= mode, /* Account for the number of pages needed by ucall. */ nr_pages +=3D ucall_nr_pages_required(page_size); =20 - return vm_adjust_num_guest_pages(mode, nr_pages); + nr_pages +=3D kvm_arch_vm_additional_pages_required(shape, page_size); + + return vm_adjust_num_guest_pages(shape.mode, nr_pages); } =20 void kvm_set_files_rlimit(uint32_t nr_vcpus) @@ -474,7 +476,7 @@ static bool is_guest_memfd_required(struct vm_shape sha= pe) struct kvm_vm *__vm_create(struct vm_shape shape, uint32_t nr_runnable_vcp= us, uint64_t nr_extra_pages) { - uint64_t nr_pages =3D vm_nr_pages_required(shape.mode, nr_runnable_vcpus, + uint64_t nr_pages =3D vm_nr_pages_required(shape, nr_runnable_vcpus, nr_extra_pages); struct userspace_mem_region *slot0; struct kvm_vm *vm; @@ -2334,6 +2336,12 @@ __weak void kvm_arch_vm_post_create(struct kvm_vm *v= m) { } =20 +__weak int kvm_arch_vm_additional_pages_required(struct vm_shape shape, + uint64_t page_size) +{ + return 0; +} + __weak void kvm_selftest_arch_init(void) { } --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from SN4PR0501CU005.outbound.protection.outlook.com (mail-southcentralusazon11011009.outbound.protection.outlook.com [40.93.194.9]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BFA3B25B662; Tue, 23 Sep 2025 05:10:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.194.9 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604254; cv=fail; b=Z/+GjxlTft28YfY6//X+MRZ6K0+yHIjFDQJlkf0qF4eHMIce8Ht17MlIZkcdlsCn1+mr/a1xIsWCc1f3j4O83HTwtxRJgUZrrXLMEDQcBN72N98DhYTxcVx5ZkiHT22gmtxEhw2pMRgjlBL0OW0dWulOVYBh2iITRhkSVMxVV30= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604254; c=relaxed/simple; bh=MTHnPH6V5cNXr7Kx/Z/WGsayU1vB3YScf9LdF8yTZFg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=EMiqhVMSjjW+BX93fCNmJ56gh1jizKEeE1Kj5C4Ygrq9cQ2vUynTBLZPWBvBH25cLqRU605IZt/h/Mn+9XFFbXgYOODge7l60lLggYYG74qIIQXwa6DX9ZGzL2AAd+085a47GxWwfvSrAPSA1+H9vJ+wukfINiWv72sTjgwH5mI= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=X2p6cPEw; arc=fail smtp.client-ip=40.93.194.9 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="X2p6cPEw" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=xRzFvHIoAtYVth5V5GxfuMOtdhyHnTyDCGCM3bAhpVNhNmBuLlyXjhItCGrZtgFIuS2Y7o8xaSIApSiivsVw8fZr0nxwu2YeHZYGXnfU1wq/D5Fga7sQ1Ko86fe0uWZYJ8gRnK+rwdNTYeAVqq3wnRnT4GC/JHJrLkywHxrtKORUz4Xzz7upBjSLplTk7weS9SeF15tYvQ9XrBY+Cqz4VvNr5m+T3UB74nk5Jh2OXzzktJoS7GagoWIC74q2vfuSOaAqjcMpfOwJPqf5B6mb0R2XB27zHHWg7AA7lSW++WDq6v2rK88tcPEqcucRpYjebE+RXoQgV06Wu8LCjflbog== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=GkI0MJxPKH/l4KHI8R3iTGH5GJw1hG/6niatmIKE19k=; b=ru6OszXAnTkn/5AF/H6x7yi8rTf5qSCQMcE7zsTKKxMcPKSFgJAIlGpCAJ6HGUIfEW8e50/prQZUIoOgBIf5H7OG9S8i3+bfC5Bo/7sKD0KpDt0bYJXtU2sZoQS2K00t5D88PdAY07GRCjryaCek1wFod4AUsmkGs6WzMuFroyKFre7On+O3flk41VUkZQt9WBkpMETIBUwWscS9AsN5KC7bxmeRhuHMXClwGLiDbfwfa5Hv5k1MBSTK1gMvt7E7Hc4VuM0Y6Gh+GaoS5mVsCDYrSN7oDkVqDQFH8ykfIES8taYbyYuMgqVyZBgNSa/8i3PkOiWY+W5w5jKsbDHhMA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=GkI0MJxPKH/l4KHI8R3iTGH5GJw1hG/6niatmIKE19k=; b=X2p6cPEwRDiqfuOTCwMi0fNH+3C1/p5cmACPbS9BeQwhtBnLmImGk5V1uU9L08jeSfw1GFESh7VcsWZSRlY+kuDbfWDgMUbX2Zjy/lhuUUC2/Dy1XPt2YigV5XfIH7/ywaRtjpBSGPZTTOu+8j2krUBr5tytZkcSPZ44q8EiPhc= Received: from CH2PR07CA0063.namprd07.prod.outlook.com (2603:10b6:610:5b::37) by CH3PR12MB7764.namprd12.prod.outlook.com (2603:10b6:610:14e::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.19; Tue, 23 Sep 2025 05:10:48 +0000 Received: from CH2PEPF0000014A.namprd02.prod.outlook.com (2603:10b6:610:5b:cafe::6a) by CH2PR07CA0063.outlook.office365.com (2603:10b6:610:5b::37) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:10:48 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF0000014A.mail.protection.outlook.com (10.167.244.107) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:10:48 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:10:43 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 03/35] Add vm_vaddr_alloc_pages_shared() Date: Tue, 23 Sep 2025 10:39:10 +0530 Message-ID: <20250923050942.206116-4-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF0000014A:EE_|CH3PR12MB7764:EE_ X-MS-Office365-Filtering-Correlation-Id: 0f4f6a92-80c6-42d1-7dcb-08ddfa5f8ef1 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|376014|36860700013|82310400026|7053199007; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?ez8dTp2cEuNUk70PVzWKw6lJ1a+zNzszpakxRwkg3FO2Pf41qhmunp978QGK?= =?us-ascii?Q?heB5RylXmw6t0G451cmOTzbB7vl4sGYVZAeVmGE/TkTAhYtM7MZV5CVzX8+6?= =?us-ascii?Q?LETzC1DFJAz412uSJb4ac4BJyv1NeAs/VCrQZ3ii41CtOriV21+W8ddj6G4c?= =?us-ascii?Q?zUuVro+K0KUrUZ6LN4xNEcfZhXfJNE985EKGm2ApV5MKYkQVlZRQ9F1kNUHS?= =?us-ascii?Q?wbjbMYFKkwZXH45KjFYYQsjvibU2qPRUf++0aOTw0kmcdCe/1nqF5lvNpcwe?= =?us-ascii?Q?V80lShrnR0tVQXPZnZ+8hAhVv2vASQZ6sSdAzED31bapH0/TUk1YAC7shhPQ?= =?us-ascii?Q?N3ORxP8CEl/wlOeNat6OyWutmVs0zD3zPKbiod4+QNfrTzF7Z3po4h8vA8hq?= =?us-ascii?Q?QC2PRQcwUH+V2v9y0ix/juA1Rb55FJ9gOsso5DOrX70+g2nCHRCEAEa46PkJ?= =?us-ascii?Q?O2RA1eZMFSfpKhgaQNh34m17WfStaYOFk27C/vr9gCMYkBoJt3hYd7VJmJfA?= =?us-ascii?Q?w5jqxTqxOWhD8MiXA1oKfl/SweJP5qXNIVgXdEgHgZ0TPI7nzrp2aF+zCxyb?= =?us-ascii?Q?yQ5RLMO7zOrrANIdNPw7xziygLiLzpCsWZSyZVeutVybUvnqxamw5yndTtx8?= =?us-ascii?Q?m+eIdF2RGkTJFhcOQJWBOsn+U9+kwjnDZiAzVn8AYuHVbzcI3dHdLHua0eVj?= =?us-ascii?Q?qsk2d7fafFqSGLqtEyvp/3pc17cnoXIMGU1s0AkezbuJ53OqRIsL1+EQvIgJ?= =?us-ascii?Q?x1xYaUczckFio9ONPZlOrgUy1zoSrtQf1ey7e3uogJds/Ub3oe8OjrKb2dyw?= =?us-ascii?Q?/qfXe9rgGWFn/4oD/NNjRSEyvJiPUE8KdgEb0XIVYNxeKdFueVhHkv+AXq8x?= =?us-ascii?Q?rKqHlAk16HkSrAKCIveqKeJXJbviJ6IyP0rZXO1sofxyaXb0wDu3UqNW0wSn?= =?us-ascii?Q?I+RWMFsW1xSQrYH7uKhka6wMLiBV9qRw773MbrN4AcSe+sCh2+Th/SLcuGGk?= =?us-ascii?Q?GOgF6t9/RdeX08FpZVbsqPKz84TJ8o1xBX+BSqA6oDb8fa13s2T1N6pohutG?= =?us-ascii?Q?OecpwOl77DoohE938raPeACuZHuo09RWgqU2PSgYpwRNEClSEzE5X7kD8CLl?= =?us-ascii?Q?JxtOTmFuzhn2MM34ceU964lNB/KgI+95FOVQLJf7sKBh0X616UleLbY1xSqC?= =?us-ascii?Q?eppiHz317DGc4NxDv6wKA3rwzbWCj3wLT8sdCR2IO/ZIhsbGpqXvrVPizhae?= =?us-ascii?Q?9pLCQIb6514GSKnwsuXLqcyAMhzg3G8JUNgjB6KE5LzlIee8tX4kXN52WbVl?= =?us-ascii?Q?GxhRyjYcwgSjgLPrXMONvPX+K8jDve4jVqW8hdw1MOxbtVvzphr3kBkmazDR?= =?us-ascii?Q?CjHoQRGT679BBRiW16Nill9Q1zx8NZfkGp6wbU9TR++5kV5yVygXzAA2CnuY?= =?us-ascii?Q?Mix5Hg3PRpdeSINkvlfdRiuBC1W0Zaq4SHSu03tJjvDc8GRFRSVHHKPrMXV0?= =?us-ascii?Q?BFOLzXCORyQKz040H10+hT8dm78J2cd+TMrM?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(376014)(36860700013)(82310400026)(7053199007);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:10:48.2971 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 0f4f6a92-80c6-42d1-7dcb-08ddfa5f8ef1 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF0000014A.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH3PR12MB7764 Content-Type: text/plain; charset="utf-8" From: Peter Gonda Add a shared page allocation. To be used for SEV-ES GHCBs. Cc: Vishal Annapurve Cc: Ackerley Tng Cc: Paolo Bonzini Cc: Claudio Imbrenda Cc: Sean Christopherson Cc: Carlos Bilbao Cc: Tom Lendacky Cc: Michael Roth Cc: kvm@vger.kernel.org Cc: linux-kselftest@vger.kernel.org Signed-off-by: Peter Gonda Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/include/kvm_util.h | 1 + tools/testing/selftests/kvm/lib/kvm_util.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing= /selftests/kvm/include/kvm_util.h index 1a9764658eb9..2e27682c5077 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -696,6 +696,7 @@ vm_vaddr_t vm_vaddr_alloc_shared(struct kvm_vm *vm, siz= e_t sz, vm_vaddr_t vaddr_min, enum kvm_mem_region_type type); vm_vaddr_t vm_vaddr_alloc_pages(struct kvm_vm *vm, int nr_pages); +vm_vaddr_t vm_vaddr_alloc_pages_shared(struct kvm_vm *vm, int nr_pages); vm_vaddr_t __vm_vaddr_alloc_page(struct kvm_vm *vm, enum kvm_mem_region_type type); vm_vaddr_t vm_vaddr_alloc_page(struct kvm_vm *vm); diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index a3b16793b2fd..00317ce5dbb9 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -1562,6 +1562,12 @@ vm_vaddr_t vm_vaddr_alloc_pages(struct kvm_vm *vm, i= nt nr_pages) return vm_vaddr_alloc(vm, nr_pages * getpagesize(), KVM_UTIL_MIN_VADDR); } =20 +vm_vaddr_t vm_vaddr_alloc_pages_shared(struct kvm_vm *vm, int nr_pages) +{ + return vm_vaddr_alloc_shared(vm, nr_pages * getpagesize(), + KVM_UTIL_MIN_VADDR, MEM_REGION_TEST_DATA); +} + vm_vaddr_t __vm_vaddr_alloc_page(struct kvm_vm *vm, enum kvm_mem_region_ty= pe type) { return __vm_vaddr_alloc(vm, getpagesize(), KVM_UTIL_MIN_VADDR, type); --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from CH1PR05CU001.outbound.protection.outlook.com (mail-northcentralusazon11010019.outbound.protection.outlook.com [52.101.193.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 55610272E5A; Tue, 23 Sep 2025 05:11:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.193.19 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604274; cv=fail; b=KiDmW45DGR0fyseReBsbFlu8Vy4YjtX1b+ZSEElwUSjAGQ+OMWxmiA/RPHESXxtM1NzKNc4DnREtl/p3+QBFstVCIOAlMuYPFzy98VcgJ1YqhaiVMzKsiPbkSZdqp/sZ99vPOkyX4HK4o16+yoXg0wvhb4O3SA2KP+cehLQPwC0= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604274; c=relaxed/simple; bh=zoWx+dzcsl07uRqEJCQ74UFYRfIhlfm7gZ7ghM/KUpI=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=JjiwdBtRJXtKo0NW6mxeIkWheZZUuLQcEyBT7ky5w/cYNAPucHlBDJLLFWV0sxg9owB4g4aNRpUWq7xFaW/qawIjjRZ3Y+LhGsTGPJ1+1wh5JlVzzOwf3ucfEsn7wbzhat4fk0Zh8PhyPHapuMTar4IrccN8JBsl/zaUBBAe9aw= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=yJjaw2bn; arc=fail smtp.client-ip=52.101.193.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="yJjaw2bn" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=PSpg3nIdhSHsm5QcmThIdxf1Q+SrT3o12XOdjBtERxujkYSvCN11pHjvKdFj44vl7bU/yT5iE0kAvkFURz2q1cTUM3Mh9OGh1lt2/eRPfAbFY3xYrPrRDmUrAEXGoT0tdfyij5qVT89T2mTc/1/8LT8EF9Yq/OyvXLVOOOmBUlro2nPKo9g7H5ure3fJ1XG6dm+hSOjYTsTpR5TnkUK8fbL54MoQ30GIGvRAWNvAYuZG90ul3KflNir3Qa/ZsPDMjUVHrKFesJWJXjtiQfMLV8HRxEIHTg5hulK34CpkW0SCtt6QPls/XEsnijGoXD/s1Gl1skgmnr3tA3BZVP5yDQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=xhUV+6Sof0Ablv9xPhrcdJ7bUtp8bnPBp5TFaojMyFY=; b=bePYwue86gfq6MWuf8i+t1elI+grHbHLD/RcOrFiyuTs3OhUBSNsJ1CsPDxJAjeOpQIggta0p6kkNT3Vl9JUHap1ssekI9Yn3kWrbO/x6QM90QCqejYcKcCYfPh4G5Uus/PZB7nk05cNxwR9dap7VDXYHMYuzRuHQLZvud9f6v+s6qNWibg0cpJaNp4QwsvZSUww2h9CiGSajiIXOMPnJ9ipHtVDfY3iZazt4L9GpFCW3GiBCkasPDGiW9l1URB004hB/HZ7yJhOQFW4DxcKLnkBGVsP5KogTuy5mdescNnKQ00a6bqyEPCBIQh8A+IISLCo+EZqk0uBTbDgmRvDGw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=xhUV+6Sof0Ablv9xPhrcdJ7bUtp8bnPBp5TFaojMyFY=; b=yJjaw2bn085VG66R97Vqbp1bVsN/x7iu/Ykt47rRJLyYNKXZ8ABLzSs2taLjEmK/29qKyVIDhYwYSjzSLAsNS7HwDrbKdWD6ZjIGV7F261vcYgO+3Ww+n2QhZyUGMsfXCHvbeLfrMYuOjJ967PjIiGVpdYRQbaXzn8boHh57IB4= Received: from CH0PR04CA0063.namprd04.prod.outlook.com (2603:10b6:610:74::8) by PH7PR12MB9067.namprd12.prod.outlook.com (2603:10b6:510:1f5::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.16; Tue, 23 Sep 2025 05:11:06 +0000 Received: from CH2PEPF00000149.namprd02.prod.outlook.com (2603:10b6:610:74:cafe::7e) by CH0PR04CA0063.outlook.office365.com (2603:10b6:610:74::8) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:11:06 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF00000149.mail.protection.outlook.com (10.167.244.106) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:11:06 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:11:00 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 04/35] Add GHCB allocations and helpers Date: Tue, 23 Sep 2025 10:39:11 +0530 Message-ID: <20250923050942.206116-5-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF00000149:EE_|PH7PR12MB9067:EE_ X-MS-Office365-Filtering-Correlation-Id: 83d3987b-fb18-49f9-387d-08ddfa5f9981 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|36860700013|82310400026|376014|7053199007; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?5BaiC0iwC4CRXOO04PEy649xtiYswVv8Re2ItNrVEGeRhxAQKQaVi8qMtDiD?= =?us-ascii?Q?tVbF+wwxpFUdNdla80pcO8X0NITZiHpzd2xc9/AXdShXwW2xnotE11zz65DZ?= =?us-ascii?Q?J0zZUK1x7jvN9I+nu/cTgeC7GFK0beun5FViqSdbYapkDApKVL3xJCPNDzrE?= =?us-ascii?Q?WQ1f1DvV6OO8UsAG+RZXBo37i9j4b5U8d1WI2iHZCyKkObPReqYbiGyCngur?= =?us-ascii?Q?iZkeW1+sXVciAsLnOgwmbEGooUuWZE0Ll6GFcGSQiW44Q4Dtla5rldiRTte7?= =?us-ascii?Q?QK400Ysft3O1xiP1LpIVSpfVnFAQWHQWDtlWT+vL0bKxKSmkxvd2dKtjjoPv?= =?us-ascii?Q?hXWTeDXuBcPeec2tMamHq4a+Rv6+Gcg3d9ZzI46JJiXIv+sEHQNSd/xV7WNk?= =?us-ascii?Q?zlD3ISyWCEsmFIAfz4EcXgupgLjiVIaB4ecGOVTuEQIJPyZxsGp6T4f+qmFT?= =?us-ascii?Q?ukGiE6Ft4GpGY4Mpzz/oihCCmZ9ZfosPJXq11tSBdzoIrJFuyv7da3X+XPjP?= =?us-ascii?Q?8myY9zNtINKJ6v8vBjfR931PoWugABoNf3MW9zyHTw/tn77lOFeG/0UEbT1e?= =?us-ascii?Q?NrRlekWd0m3sRiyA5tl/1dE4hcuPyAutQH4rbYm5nckyy5662A8loI12DlXZ?= =?us-ascii?Q?SI29VkAFeNOlSnp+H4pB0ZSojxiPYR5mhuSqoa1vqik87sHUWKvg19dqEFq8?= =?us-ascii?Q?rngFXLHUQIAkUUrfJt0HVi2pHj9JFXQzAfPIMouybbnKXIi+MPYnVmX4un0o?= =?us-ascii?Q?RB+reWKtx9P55GQ7OHKfkj43JXRipSQSw14g5/gGMUyZEDK7XjeoDchHqQUx?= =?us-ascii?Q?exftjP2teLQODcpCHLTUm7AffKj09NIPP8KYFPvhtzO4PmKQmzGTeFicXNQD?= =?us-ascii?Q?we1D473SM2h96epVsVfFbAqjZw0vV1/YsI/xxUlmCkqohKyFa+L8T7+5+2Ep?= =?us-ascii?Q?iqD9RjE9pDPXXS1byT2r1JbDVxV86Z20PyY9pPTBKjpNnskL6oC2NQLY1+tZ?= =?us-ascii?Q?GxEKmhZSMWhf+sL6MNM/t1DzCH8WcL06w2+6vObK7uVZ7+uNHLny9eYLXNPM?= =?us-ascii?Q?OTzTvVhCxtSHzTNSJYxijkNHDnME3msKz8Sofvc3lxPxamObirB7nFFugxmQ?= =?us-ascii?Q?2gefgI1jQOj2jedPy1bHQL5YiUQoYMQEX37Viyu9ql+W/p9tm41G+JyOhjCm?= =?us-ascii?Q?RYsMGXpw6Ih+ueDZhNegnYiJEXcbAcLb5RmHvZSt5KCVb1wAlyWP1q9VLno9?= =?us-ascii?Q?ZzpIoS0DArhy6l00EjafHrQrCsTXs8LS8Bs4RxNRTmuWYccpmtgRWyhBMovD?= =?us-ascii?Q?n8nIBSIqmE0f8vfmDGCByDFB03MN04injzPAvkp/MIQZbhoxxwg6Oj4eroil?= =?us-ascii?Q?u+bM4SCWDDMwT/rBCHbQnD84pr4plRZ4o9e/7LmAYBBNcubwaS2eGqfgGaqU?= =?us-ascii?Q?ZS+f8eNOvZuNBPpHTf1bRTE8nY7HbdvAJSBf82kyO0bfEMddTky5G4Le5O/A?= =?us-ascii?Q?1jwSYMs81xwAVgN6WZELqNLCyIOyOKc3TlLN?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(36860700013)(82310400026)(376014)(7053199007);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:11:06.0150 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 83d3987b-fb18-49f9-387d-08ddfa5f9981 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF00000149.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR12MB9067 Content-Type: text/plain; charset="utf-8" From: Peter Gonda Add GHCB management functionality similar to the ucall management. Allows for selftest vCPUs to acquire GHCBs for their usage. Cc: Vishal Annapurve Cc: Ackerley Tng Cc: Paolo Bonzini Cc: Claudio Imbrenda Cc: Sean Christopherson Cc: Carlos Bilbao Cc: Tom Lendacky Cc: Michael Roth Cc: kvm@vger.kernel.org Cc: linux-kselftest@vger.kernel.org Signed-off-by: Peter Gonda Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/include/x86/sev.h | 2 + .../testing/selftests/kvm/lib/x86/processor.c | 9 +++ tools/testing/selftests/kvm/lib/x86/sev.c | 78 +++++++++++++++++++ 3 files changed, 89 insertions(+) diff --git a/tools/testing/selftests/kvm/include/x86/sev.h b/tools/testing/= selftests/kvm/include/x86/sev.h index 008b4169f5e2..6cda0acd22e4 100644 --- a/tools/testing/selftests/kvm/include/x86/sev.h +++ b/tools/testing/selftests/kvm/include/x86/sev.h @@ -46,6 +46,8 @@ static inline bool is_sev_vm(struct kvm_vm *vm) return is_sev_es_vm(vm) || vm->type =3D=3D KVM_X86_SEV_VM; } =20 +int ghcb_nr_pages_required(uint64_t page_size); + void sev_vm_launch(struct kvm_vm *vm, uint32_t policy); void sev_vm_launch_measure(struct kvm_vm *vm, uint8_t *measurement); void sev_vm_launch_finish(struct kvm_vm *vm); diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testin= g/selftests/kvm/lib/x86/processor.c index d4c19ac885a9..d72eb96efb7c 100644 --- a/tools/testing/selftests/kvm/lib/x86/processor.c +++ b/tools/testing/selftests/kvm/lib/x86/processor.c @@ -651,6 +651,15 @@ void kvm_arch_vm_post_create(struct kvm_vm *vm) sync_global_to_guest(vm, guest_tsc_khz); } =20 +int kvm_arch_vm_additional_pages_required(struct vm_shape shape, uint64_t = page_size) +{ + if (shape.type =3D=3D KVM_X86_SEV_ES_VM || + shape.type =3D=3D KVM_X86_SNP_VM) + return ghcb_nr_pages_required(page_size); + + return 0; +} + void vcpu_arch_set_entry_point(struct kvm_vcpu *vcpu, void *guest_code) { struct kvm_regs regs; diff --git a/tools/testing/selftests/kvm/lib/x86/sev.c b/tools/testing/self= tests/kvm/lib/x86/sev.c index c3a9838f4806..c400faa9cc5f 100644 --- a/tools/testing/selftests/kvm/lib/x86/sev.c +++ b/tools/testing/selftests/kvm/lib/x86/sev.c @@ -3,6 +3,80 @@ #include =20 #include "sev.h" +#include "linux/bitmap.h" +#include "svm.h" +#include "svm_util.h" + +struct ghcb_entry { + struct ghcb ghcb; + + /* Guest physical address of this GHCB. */ + void *gpa; + + /* Host virtual address of this struct. */ + struct ghcb_entry *hva; +}; + +struct ghcb_header { + struct ghcb_entry ghcbs[KVM_MAX_VCPUS]; + DECLARE_BITMAP(in_use, KVM_MAX_VCPUS); +}; + +static struct ghcb_header *ghcb_pool; + +int ghcb_nr_pages_required(uint64_t page_size) +{ + return align_up(sizeof(struct ghcb_header), page_size) / page_size; +} + +void ghcb_init(struct kvm_vm *vm) +{ + struct ghcb_header *hdr; + struct ghcb_entry *entry; + vm_vaddr_t vaddr; + int i; + + vaddr =3D vm_vaddr_alloc_shared(vm, sizeof(*hdr), KVM_UTIL_MIN_VADDR, + MEM_REGION_DATA); + hdr =3D (struct ghcb_header *)addr_gva2hva(vm, vaddr); + memset(hdr, 0, sizeof(*hdr)); + + for (i =3D 0; i < KVM_MAX_VCPUS; ++i) { + entry =3D &hdr->ghcbs[i]; + entry->hva =3D entry; + entry->gpa =3D (void *)addr_hva2gpa(vm, &entry->ghcb); + } + + write_guest_global(vm, ghcb_pool, (struct ghcb_header *)vaddr); +} + +static struct ghcb_entry *ghcb_alloc(void) +{ + return &ghcb_pool->ghcbs[0]; + struct ghcb_entry *entry; + int i; + + if (!ghcb_pool) + goto ucall_failed; + + for (i =3D 0; i < KVM_MAX_VCPUS; ++i) { + if (!test_and_set_bit(i, ghcb_pool->in_use)) { + entry =3D &ghcb_pool->ghcbs[i]; + memset(&entry->ghcb, 0, sizeof(entry->ghcb)); + return entry; + } + } + +ucall_failed: + return NULL; +} + +static void ghcb_free(struct ghcb_entry *entry) +{ + /* Beware, here be pointer arithmetic. */ + clear_bit(entry - ghcb_pool->ghcbs, ghcb_pool->in_use); +} + =20 /* * sparsebit_next_clear() can return 0 if [x, 2**64-1] are all set, and the @@ -88,7 +162,11 @@ void sev_vm_launch(struct kvm_vm *vm, uint32_t policy) struct kvm_sev_guest_status status; int ctr; =20 + if (is_sev_es_vm(vm)) + ghcb_init(vm); + vm_sev_ioctl(vm, KVM_SEV_LAUNCH_START, &launch_start); + vm_sev_ioctl(vm, KVM_SEV_GUEST_STATUS, &status); =20 TEST_ASSERT_EQ(status.policy, policy); --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from BYAPR05CU005.outbound.protection.outlook.com (mail-westusazon11010003.outbound.protection.outlook.com [52.101.85.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1910830CDAF; Tue, 23 Sep 2025 05:11:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.85.3 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604288; cv=fail; b=Mk88PzoWISTJvNg95LHzSQO+22gatq3jK+aqdeUgErZrBApK8w666MWSwOGwqAinDOV61ED2/pQvtkL5ryHAexrU7s6IbGodF6iHYr/5ZP4rE4CUTi/SFPquBtCdrGWxZbpzP6iyDsdjNkseIe2VEc+DDsYZwPzqGzLDEkn0syw= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604288; c=relaxed/simple; bh=dlcVOkG41p5tNaz/SsF6JKFUPVJRHmJWmcDex7yzU8Q=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=dHPhmdtrQugZpbWSu0gbXTWdTyEEUphrDTmFOH+iTewOIrmBg8XDyJ1fx7JcWMgnzR5H4Y9rDOKVTiwaiO6xqWtQ+Dh/td4AJ8Pze71RYdOrqIc2xO/MAPGFIg34bfRVVENH1NfaqY03KEYQR7HB7eEE/eou3zasuj+a/kaX6qY= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=12VZXVGc; arc=fail smtp.client-ip=52.101.85.3 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="12VZXVGc" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=uIYHPlkAST1APGSsptWCeBEHtV2SvhOxKLQhu8zPmAvvtxsaEKjjSw9E9alvdGjRdh+c2qGDB1xjmlOtmVNfPGSm00RsQussDU6OPLpbVEvsinIwRW6bX9GIlGJZDYmGPwl2i82AJ7VexF46k6C6CYsHQp6ctR19+6y9kEEBvsNVHSnc6rqfLJfPeYRedYiyNPx3k8Z2sTzFDvy8MHjDyZqcc8zALHWmnxopMbWpY008K+HaF5BS8WJu2HfGgm3EwOhOaiKROTtDGQYQia9oE9BgLWmp5uDt5q0WgpjTg0ouDCPWAS2iFAcNPWfAWvZLB/XULDGag9GZw7vtCumECQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=xUKpzU7azTdJ7Gdo3q6syH6q+G8cqFbTZDLbm2APJU0=; b=sZpTSt1NEz7GjybdFKOT8qKxThkXCkOveg02vzDd+IwGuRB0vRhJSG+dQlTk6LVf1RmQlAs1FmopdjTi3JjkDvPQWgtrhKzxgTaBukuw+VIx8cMdkcIMEm/8hsAA9vrlqCpAVXatH5x3LspDzb1EOAnglUtsYXu9JIkHCwnZ3rc1rouVO99QEa5OISA5rqqLGHohHqSr7cvM2MTUaD/W4cYR4fVU8QQvMqI8qYFni0iPoT3mL0N8WN/nTKEjQDdJR4qyU4+dilQ5z9BNaj6r0ygiaSnyImxFbsdIy+E2ODmQ9Xvmoti01DtQigMa2kvrRgbisSs81EQjh7EVDO9JEA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=xUKpzU7azTdJ7Gdo3q6syH6q+G8cqFbTZDLbm2APJU0=; b=12VZXVGcmEZ4X02r1iaw/RFl2zsie5uYR0xI6TF9Gmh5ywHcC7z9cy1Qh98lBfjhegzllngIKHqJa1hBXlkyubyBh/thTwxYjftySYdr5EMZ266/63TTQkYpEbus/b6BftPtG3c7SOD+JNs64q1E2pkukccZO1YAn3eXxMNCrA4= Received: from CH0PR04CA0089.namprd04.prod.outlook.com (2603:10b6:610:74::34) by PH7PR12MB5976.namprd12.prod.outlook.com (2603:10b6:510:1db::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.20; Tue, 23 Sep 2025 05:11:23 +0000 Received: from CH2PEPF00000149.namprd02.prod.outlook.com (2603:10b6:610:74:cafe::5f) by CH0PR04CA0089.outlook.office365.com (2603:10b6:610:74::34) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:11:23 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF00000149.mail.protection.outlook.com (10.167.244.106) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:11:23 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:11:18 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 05/35] Add is_sev_enabled() helpers Date: Tue, 23 Sep 2025 10:39:12 +0530 Message-ID: <20250923050942.206116-6-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF00000149:EE_|PH7PR12MB5976:EE_ X-MS-Office365-Filtering-Correlation-Id: c9516d5a-be85-4e25-c5a2-08ddfa5fa407 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|82310400026|36860700013|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?VetIsudNtbiy7/B45umuUgyzRF4Z1j8kkFPwlgChC9tj0QLEc3qr1nx6e3i9?= =?us-ascii?Q?+TZipNuurhyRyLgRRlIUegBEIYCqJ4zzz+L1tIhZwSMYaM3ZGi1KpULLdk3p?= =?us-ascii?Q?VVMHeiS/OmwzXx1Y6akYRBAPF5sx9Vpz7Oww/o3h/XGX9MO2QMK0SkaVZaI5?= =?us-ascii?Q?L09ZpZtdjaphkVATvACmJF4gJ8xkdr0ikTWp4fTqjgOkrn6An7p7oXijO9i6?= =?us-ascii?Q?jhAVRNxJTME9LeikycTc7HvCUxYXOtglFHj/sHqjFwOqZXHMI6sSWbt7C6hI?= =?us-ascii?Q?4959E7eWw+gsXSgt3SE7948sZygxUap5/56jhNIuFmKI/xuzlyrPvY9UCtXc?= =?us-ascii?Q?PPrJZmrdn7HnjkOgLM9R+Au3N3HD5jnVIRSS1yg/Tlmpf6auiodnU7jxrpVY?= =?us-ascii?Q?6FSrw3zMIH1po3ezxogaNNLVdVaZkwn1dYNWQ1Fzq/VaPcNVrXPdK3KTH6+g?= =?us-ascii?Q?LzisS85Osi2l35ye7WWlFiRlchyErm01UGRIYJZFP6H9FpdywImbTNqXwbpE?= =?us-ascii?Q?oi4oGc4TctPpf/Mrok+xNXn9PK8VxUJyE+n49GpDS8FkIRGZaX4PpeT1vdGV?= =?us-ascii?Q?vOxIUgiVt/4//yjF4VrKvtoKNeVInxsrd2va4NuTw5Bc85M6hUq218TXM1gW?= =?us-ascii?Q?sUdNfw1vR5iVLCjqQQ1/KlApRN0Wb19ZUJr8/I2qgGdFarJcda6nQzNyIynP?= =?us-ascii?Q?3fFBt+7E0uOaEspk931o/mXMPeJd8jbTDj3XI2zbGg2jJOPb/vJWtBqx5M9C?= =?us-ascii?Q?s4DwrFozJC1Yl+FOwjDIVl17S/8Rsyg/v2BZPAi/VaYGxCgLTvQevlQhS1dQ?= =?us-ascii?Q?r5BCJglBxxg5XPLqzLQ2b8v2CV7nZzyoI9eF0bj9qrpvrxm8xtUSRkc6IHKf?= =?us-ascii?Q?OHtNG7rX4cuoT778IE7sz95V9FT5jFvpK83kSfYoLbPK61qLllDdQPHUGeDP?= =?us-ascii?Q?IxYSjlXv5p9wmnbFyjMYveGAdar6hRu0jMi1cr/D0QQFBo3YpQrbz5Eh4zbA?= =?us-ascii?Q?MnIQ5gMf0t8VjybFtCYwQATKcPgjfJvxfQ7/MZk4UM14LeCinP9M3Eb6hSuk?= =?us-ascii?Q?59SH8aCElBRYWleUhnhxSvNnzTIbVmoNsdMpkkZSbhKXVa9wYzlrMy6AqKSt?= =?us-ascii?Q?yZ+ehUQAcLiccg7UNvqHaobzNenujw8zMcsAEJqgl8g8kdxkHM3w2Ln2H25j?= =?us-ascii?Q?6mclKrgmgaDsgsWWzNveJbe8cJw2tg2XZnLpSJyUBSuJ6Pu46GHNqr2+iydU?= =?us-ascii?Q?0RqR3rK/hJDUIVo+d+bUJ6Yfg33qL3AzDb2RSMw3WXfznssn4/JeVQjSoCue?= =?us-ascii?Q?roArxvw6TRZgioXZeYfN1KlhbWNHDnf0utJk0RsTtzoE1CLk8Q3zaJ9MBUaQ?= =?us-ascii?Q?Uf1VHIkErrMiNieJD9sWqQ1VRmdoY0s/8HAe1RRTt/kUGZsKuJSinIRi6FLY?= =?us-ascii?Q?06RxMnYqTGhhKRfzyaZEVFi4XR0Qbh/OFvGMEAE0LWMXxpMu8phro7epL0cV?= =?us-ascii?Q?/JmjOlXOziqqbIPOhFvfM+jxo0X6gV1Hrh70?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(376014)(82310400026)(36860700013)(1800799024);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:11:23.6744 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: c9516d5a-be85-4e25-c5a2-08ddfa5fa407 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF00000149.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR12MB5976 Content-Type: text/plain; charset="utf-8" From: Peter Gonda Add helper functions for guest code to check the status of SEV and SEV-ES. Cc: Paolo Bonzini Cc: Claudio Imbrenda Cc: Sean Christopherson Cc: Carlos Bilbao Cc: Tom Lendacky Cc: Michael Roth Signed-off-by: Peter Gonda Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/include/x86/sev.h | 17 +++++++++++++++++ .../testing/selftests/kvm/x86/sev_smoke_test.c | 11 +++-------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/tools/testing/selftests/kvm/include/x86/sev.h b/tools/testing/= selftests/kvm/include/x86/sev.h index 6cda0acd22e4..2c1bd27345f4 100644 --- a/tools/testing/selftests/kvm/include/x86/sev.h +++ b/tools/testing/selftests/kvm/include/x86/sev.h @@ -46,6 +46,23 @@ static inline bool is_sev_vm(struct kvm_vm *vm) return is_sev_es_vm(vm) || vm->type =3D=3D KVM_X86_SEV_VM; } =20 +static inline bool is_sev_enabled(void) +{ + return rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SEV_ENABLED; +} + +static inline bool is_sev_es_enabled(void) +{ + return is_sev_enabled() && + rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SEV_ES_ENABLED; +} + +static inline bool is_sev_snp_enabled(void) +{ + return is_sev_es_enabled() && + rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SEV_SNP_ENABLED; +} + int ghcb_nr_pages_required(uint64_t page_size); =20 void sev_vm_launch(struct kvm_vm *vm, uint32_t policy); diff --git a/tools/testing/selftests/kvm/x86/sev_smoke_test.c b/tools/testi= ng/selftests/kvm/x86/sev_smoke_test.c index 77256c89bb8d..3316427eee46 100644 --- a/tools/testing/selftests/kvm/x86/sev_smoke_test.c +++ b/tools/testing/selftests/kvm/x86/sev_smoke_test.c @@ -18,11 +18,7 @@ =20 static void guest_snp_code(void) { - uint64_t sev_msr =3D rdmsr(MSR_AMD64_SEV); - - GUEST_ASSERT(sev_msr & MSR_AMD64_SEV_ENABLED); - GUEST_ASSERT(sev_msr & MSR_AMD64_SEV_ES_ENABLED); - GUEST_ASSERT(sev_msr & MSR_AMD64_SEV_SNP_ENABLED); + GUEST_ASSERT(is_sev_snp_enabled()); =20 wrmsr(MSR_AMD64_SEV_ES_GHCB, GHCB_MSR_TERM_REQ); vmgexit(); @@ -31,8 +27,7 @@ static void guest_snp_code(void) static void guest_sev_es_code(void) { /* TODO: Check CPUID after GHCB-based hypercall support is added. */ - GUEST_ASSERT(rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SEV_ENABLED); - GUEST_ASSERT(rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SEV_ES_ENABLED); + GUEST_ASSERT(is_sev_es_enabled()); =20 /* * TODO: Add GHCB and ucall support for SEV-ES guests. For now, simply @@ -45,7 +40,7 @@ static void guest_sev_es_code(void) static void guest_sev_code(void) { GUEST_ASSERT(this_cpu_has(X86_FEATURE_SEV)); - GUEST_ASSERT(rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SEV_ENABLED); + GUEST_ASSERT(is_sev_enabled()); =20 GUEST_DONE(); } --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from SJ2PR03CU001.outbound.protection.outlook.com (mail-westusazon11012045.outbound.protection.outlook.com [52.101.43.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 017A425B662; Tue, 23 Sep 2025 05:11:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.43.45 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604307; cv=fail; b=nX8bpDw05qP9Xqkm2vyEW2E3tQYw/11wXGtCq+JvQkIRHPEQiGM+SlY1hOEKpqmsB0ofhM1s6Yct5e556WGTHrCJ7UT5s1meT59C/Cx7ZT0XcK93W/C9wDgzwtdkQ33EAlYaHvNWm7mUo31+7/a8bAcRKMEbkijhNTzbxIRdpI8= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604307; c=relaxed/simple; bh=sS5jnhrsiMb8BAR+slcncBvAAMoj3BspB1cX3+6Iceg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ElYqBi5DvSMRLpyk0zUj94UBzyH23No1uATlq9yYUYgxc0BIZX2UC+5qz+sNPWfAykhR6hWzgm2Ckcb0nByCyovh4IUIxw0jd8sAyzJ/PwJGrbD0jZIIhXMmetCxkPZ42lhYuvUnEMAYeEgJybB4McGxo5KB57nG5d/nyXyQYTY= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=FwlswyHa; arc=fail smtp.client-ip=52.101.43.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="FwlswyHa" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=TVerA3/gZwZUA4rEbabskMwOvw3+2P3ZVLDSf1RTtON2bgDyFyPiGhnmpGBGTn2DaEdVqIUq9Oc1ShpseIHCs88ODu+Y/bwkcWszNFAwsD40PCTZxnz83xliWy09S/b8AfgBVxy5YiHAHmzDAwwIfEZ1zDQStAJUmSZGftXPMBGnECVI58ZOk7aFlRiDiMyz5CmCm1VvlouEBJ+PBbopOlwabmij+7OXmS0BauAlHfPWBgkzCiLclt1a4H8dNn83O0DGtpWLjLxn+BS7+Vt4BP5NHrqgNaNGvku5k6mFDeelZW2SqBrmGL2EblHcJBt52sfhqkV9LBdM3Zg+L04/EQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=v1OsI9zC9mdPwpdjgzCA99MeG8COE6wT/Meuk/USSvE=; b=UyfbGWztMvBhj6zD/CN/LA1NMccGK31muQlVlLH0wSwzaohqO5KWSh+hOfQ2+b2DNfQjugkIxzBU7+0Ag9kmrgKX9s/31SX3iJlMG96NWAym7CIgGQ4RG/FyxUjLeBUdEUaLf7ZwlZMyyd6t7kakEujx37mA2ksbtpTV9vQX/fFxJAv9lVPNDY+6Q0QY/dYxVHMqSUC95LTuQ9mf9q6jff+iFlKFP5bxUv0bEdE3A7lHtmPsFelmNtRyw8cIktLbGVpZMfV+OzfgFu+h8A8dk/A1PlACfib5ZvYgk1eN91EvF6xZHeMXLmLMxKkomXbfTP4Ca00ii/woUwXFl8zO8g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=v1OsI9zC9mdPwpdjgzCA99MeG8COE6wT/Meuk/USSvE=; b=FwlswyHa+wU4qL4J9LOAVGbU6oDKAIejvTtWKFuCtiITBU/yU0wWU4uzfEJ4K7ZeHg/GbBcx1a+C3G0ekvslEkJJxmHRN6/FbAPMvw+qFBpqrbKlKoPyQsIoFwwQ92agNnaGbT21qRBXoz1GvNUAo9ESYVB6ZyyhyI0mZU7X9A4= Received: from CH2PR07CA0041.namprd07.prod.outlook.com (2603:10b6:610:5b::15) by BN3PR12MB9572.namprd12.prod.outlook.com (2603:10b6:408:2ca::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.20; Tue, 23 Sep 2025 05:11:41 +0000 Received: from CH2PEPF00000144.namprd02.prod.outlook.com (2603:10b6:610:5b:cafe::cc) by CH2PR07CA0041.outlook.office365.com (2603:10b6:610:5b::15) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.19 via Frontend Transport; Tue, 23 Sep 2025 05:11:41 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF00000144.mail.protection.outlook.com (10.167.244.101) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:11:41 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:11:36 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 06/35] Add ability for SEV-ES guests to use ucalls via GHCB Date: Tue, 23 Sep 2025 10:39:13 +0530 Message-ID: <20250923050942.206116-7-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF00000144:EE_|BN3PR12MB9572:EE_ X-MS-Office365-Filtering-Correlation-Id: c5e94c18-0c73-4005-cf2c-08ddfa5fae9c X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|1800799024|376014|36860700013|7053199007; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?BdjzPLfL6z/XaGeaiG41HdczOZyFVK1M72Nq06ZconbnaYCw/8NWbmQOaFI1?= =?us-ascii?Q?O1XxfN16xeKW6EgVVn5t0XFCLow4HXM5UeLstg5OQyxSMpXjvzsDk2THtV42?= =?us-ascii?Q?92O6WN+8uMierXCtFXouglonbl8H1WbSLSGph64thsRuLf4x5hJjHt+t4SrY?= =?us-ascii?Q?0KARlyOHefrE4Xrfsc8LpatM1NyuD3W6pQFN67Ee7Np8COslcBzoqYbrOmbw?= =?us-ascii?Q?sUviNe2G4Xpt/lqSKnfafIQjmLVFnzc467Zt9nLW+dAWXEHxhPkIluncj2cA?= =?us-ascii?Q?CniNwCfKO5v6ddq0T1uycN+H+61A2qwC8r3ZZlCEKH4W9ZIvwA62XoZin37k?= =?us-ascii?Q?7/kRiRT/Fk+Fz6ywVW71oOPHqooGu8YzqDIQm7P4mX/kv+EifAyERPr/9NTu?= =?us-ascii?Q?w1XDOjekYuwyc/0Sg770yYy8z7c5+4krrGf7TjLcDTA5fBLDwl6fZ9H3vNCk?= =?us-ascii?Q?R52qUTJkwk4KixQbXwou/sCt3dtnA9p6se6OitJ3wiVQq6S/HSZRx90PvYTq?= =?us-ascii?Q?5pMnqxgQYUzTymm0zE04HCR0/VO2LHlPB6d4ENcIAf0J0CFq5CKcvXHWRMEn?= =?us-ascii?Q?nGxN4g6hGBF+Re84qYnrpPk+cg7pdvIbqvkeGOVM4s4xAyPzZsqb4qZ64QVn?= =?us-ascii?Q?A6czYSPQJKWHr1N2jBlUX9TE+IckIyK538ubBH+ae98SykDJvr+Ts5QlezK8?= =?us-ascii?Q?C4MzMXI9hvm9qOSIMXXeFZFqy/0r7e6s7PKsJJdKzKDEtT7ddBSYkvjM8YJ9?= =?us-ascii?Q?ZxkzwPk8s/wu163cqrlrUVHc9AE62PXuLlYB3mz7vYoiezYM/rE+ybbgPsf3?= =?us-ascii?Q?Mr5+YBiOlcGodViW34C0jt9uPk9J7D+3VSs5aZyWb8lr8nN3F2RoHJks5ju+?= =?us-ascii?Q?8mI341rHcC2RgUgMuvhKcp1DkyZepow+ERZMZTbWLoR2wKpJdTqnUXoqSwpd?= =?us-ascii?Q?TuFIHpxsOM4peJOxjtXIkXUqQWQApUfuQAX0DdcqR3Nn8WzTXC5P455IYrIk?= =?us-ascii?Q?2JDg5fyzjtRUFP/6+H3/sE1YkKML7bbfsPCsJ5EiRpRdWCUPgken4fZc8mP3?= =?us-ascii?Q?9PqDOFPxwJ30zplux7wM3MzFCTkzF/jjcNMa13xWNyJC5a0COc8sgH+5Ld9L?= =?us-ascii?Q?5BeKPzI6YfxfSMujuNFIvYAdU7dBoDvt0opcYJiy12Az8GyN1HmLvCEkRFrP?= =?us-ascii?Q?x1iP2y+fTSslqhn24RnKDOrHMzVrlmSgmQVm+H8p9AJ1cpl8dLfpjRnz9Rb9?= =?us-ascii?Q?m75iNLcn+OZ8ad5DAZCcxsk/S961Zto/qkxeEXEjTQNpZKZaJaHMI8Iat1aI?= =?us-ascii?Q?6AgZtMrWw1d75kOl/i7d5cHnRs02LKNRWx6NNPq2gX+TBMRHR5xrdydXbK2q?= =?us-ascii?Q?0pNdMs5vY5iiYAKs9FFPdVFNdLAImcXE89O/0PNNrxoTwbJran5L6w5NRn3T?= =?us-ascii?Q?igQ8kM8kM8u+xVHojLQwL2BRTXNy2aSo+mpbrLIHjXiEA82YpyUJziw+AhlL?= =?us-ascii?Q?MK1VLvvPMSjR6UIP5nbv65/O70ovva/FDkuM?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(1800799024)(376014)(36860700013)(7053199007);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:11:41.4276 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: c5e94c18-0c73-4005-cf2c-08ddfa5fae9c X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF00000144.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN3PR12MB9572 Content-Type: text/plain; charset="utf-8" From: Peter Gonda Modifies ucall handling for SEV-ES VMs. Instead of using an out instruction and storing the ucall pointer in RDI, SEV-ES guests use a outsb VMGEXIT to move the ucall pointer as the data. Allows for SEV-ES to use ucalls instead of relying the SEV-ES MSR based termination protocol. Cc: Vishal Annapurve Cc: Ackerley Tng Cc: Paolo Bonzini Cc: Claudio Imbrenda Cc: Sean Christopherson Cc: Carlos Bilbao Cc: Tom Lendacky Cc: Michael Roth Cc: kvm@vger.kernel.org Cc: linux-kselftest@vger.kernel.org Signed-off-by: Peter Gonda Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/include/x86/sev.h | 2 + tools/testing/selftests/kvm/lib/x86/sev.c | 98 +++++++++++++++++-- tools/testing/selftests/kvm/lib/x86/ucall.c | 18 ++++ .../selftests/kvm/x86/sev_smoke_test.c | 27 +---- 4 files changed, 113 insertions(+), 32 deletions(-) diff --git a/tools/testing/selftests/kvm/include/x86/sev.h b/tools/testing/= selftests/kvm/include/x86/sev.h index 2c1bd27345f4..a4fbea0d3562 100644 --- a/tools/testing/selftests/kvm/include/x86/sev.h +++ b/tools/testing/selftests/kvm/include/x86/sev.h @@ -163,4 +163,6 @@ static inline void snp_launch_update_data(struct kvm_vm= *vm, vm_paddr_t gpa, vm_sev_ioctl(vm, KVM_SEV_SNP_LAUNCH_UPDATE, &update_data); } =20 +void sev_es_ucall_port_write(uint32_t port, uint64_t data); + #endif /* SELFTEST_KVM_SEV_H */ diff --git a/tools/testing/selftests/kvm/lib/x86/sev.c b/tools/testing/self= tests/kvm/lib/x86/sev.c index c400faa9cc5f..de36a6c93839 100644 --- a/tools/testing/selftests/kvm/lib/x86/sev.c +++ b/tools/testing/selftests/kvm/lib/x86/sev.c @@ -7,11 +7,18 @@ #include "svm.h" #include "svm_util.h" =20 +#define IOIO_TYPE_STR (1 << 2) +#define IOIO_SEG_DS (1 << 11 | 1 << 10) +#define IOIO_DATA_8 (1 << 4) +#define IOIO_REP (1 << 3) + +#define SW_EXIT_CODE_IOIO 0x7b + struct ghcb_entry { struct ghcb ghcb; =20 /* Guest physical address of this GHCB. */ - void *gpa; + uint64_t gpa; =20 /* Host virtual address of this struct. */ struct ghcb_entry *hva; @@ -35,25 +42,35 @@ void ghcb_init(struct kvm_vm *vm) struct ghcb_entry *entry; vm_vaddr_t vaddr; int i; + size_t sz =3D align_up(sizeof(struct ghcb_header), vm_guest_mode_params[v= m->mode].page_size); =20 - vaddr =3D vm_vaddr_alloc_shared(vm, sizeof(*hdr), KVM_UTIL_MIN_VADDR, + vaddr =3D vm_vaddr_alloc_shared(vm, sz, KVM_UTIL_MIN_VADDR, MEM_REGION_DATA); hdr =3D (struct ghcb_header *)addr_gva2hva(vm, vaddr); - memset(hdr, 0, sizeof(*hdr)); + memset(hdr, 0, sz); =20 for (i =3D 0; i < KVM_MAX_VCPUS; ++i) { entry =3D &hdr->ghcbs[i]; entry->hva =3D entry; - entry->gpa =3D (void *)addr_hva2gpa(vm, &entry->ghcb); + entry->gpa =3D (uint64_t)addr_hva2gpa(vm, &entry->ghcb); } =20 + if (is_sev_snp_vm(vm)) + vm_mem_set_shared(vm, addr_hva2gpa(vm, hdr), sz); + write_guest_global(vm, ghcb_pool, (struct ghcb_header *)vaddr); } =20 +static void sev_es_terminate(void) +{ + wrmsr(MSR_AMD64_SEV_ES_GHCB, GHCB_MSR_TERM_REQ); +} + static struct ghcb_entry *ghcb_alloc(void) { return &ghcb_pool->ghcbs[0]; struct ghcb_entry *entry; + struct ghcb *ghcb; int i; =20 if (!ghcb_pool) @@ -62,12 +79,18 @@ static struct ghcb_entry *ghcb_alloc(void) for (i =3D 0; i < KVM_MAX_VCPUS; ++i) { if (!test_and_set_bit(i, ghcb_pool->in_use)) { entry =3D &ghcb_pool->ghcbs[i]; - memset(&entry->ghcb, 0, sizeof(entry->ghcb)); + ghcb =3D &entry->ghcb; + + memset(&ghcb, 0, sizeof(*ghcb)); + ghcb->ghcb_usage =3D 0; + ghcb->protocol_version =3D 1; + return entry; } } =20 ucall_failed: + sev_es_terminate(); return NULL; } =20 @@ -162,9 +185,6 @@ void sev_vm_launch(struct kvm_vm *vm, uint32_t policy) struct kvm_sev_guest_status status; int ctr; =20 - if (is_sev_es_vm(vm)) - ghcb_init(vm); - vm_sev_ioctl(vm, KVM_SEV_LAUNCH_START, &launch_start); =20 vm_sev_ioctl(vm, KVM_SEV_GUEST_STATUS, &status); @@ -254,6 +274,9 @@ struct kvm_vm *vm_sev_create_with_one_vcpu(uint32_t typ= e, void *guest_code, =20 void vm_sev_launch(struct kvm_vm *vm, uint64_t policy, uint8_t *measuremen= t) { + if (is_sev_es_vm(vm)) + ghcb_init(vm); + if (is_sev_snp_vm(vm)) { vm_enable_cap(vm, KVM_CAP_EXIT_HYPERCALL, BIT(KVM_HC_MAP_GPA_RANGE)); =20 @@ -275,3 +298,62 @@ void vm_sev_launch(struct kvm_vm *vm, uint64_t policy,= uint8_t *measurement) =20 sev_vm_launch_finish(vm); } + +static uint64_t setup_exitinfo1_portio(uint32_t port) +{ + uint64_t exitinfo1 =3D 0; + + exitinfo1 |=3D IOIO_TYPE_STR; + exitinfo1 |=3D ((port & 0xffff) << 16); + exitinfo1 |=3D IOIO_SEG_DS; + exitinfo1 |=3D IOIO_DATA_8; + exitinfo1 |=3D IOIO_REP; + + return exitinfo1; +} + +#define GHCB_MSR_REG_GPA_REQ 0x012 +#define GHCB_MSR_REG_GPA_REQ_VAL(v) \ + /* GHCBData[63:12] */ \ + (((u64)((v) & GENMASK_ULL(51, 0)) << 12) | \ + /* GHCBData[11:0] */ \ + GHCB_MSR_REG_GPA_REQ) + +static void register_ghcb_page(uint64_t ghcb_gpa) +{ + if (is_sev_snp_enabled()) { + wrmsr(MSR_AMD64_SEV_ES_GHCB, GHCB_MSR_REG_GPA_REQ_VAL(ghcb_gpa >> 12)); + vmgexit(); + } +} + +static void do_vmg_exit(uint64_t ghcb_gpa) +{ + wrmsr(MSR_AMD64_SEV_ES_GHCB, ghcb_gpa); + vmgexit(); +} + +void sev_es_ucall_port_write(uint32_t port, uint64_t data) +{ + struct ghcb_entry *entry; + struct ghcb *ghcb; + const uint64_t exitinfo1 =3D setup_exitinfo1_portio(port); + + entry =3D ghcb_alloc(); + ghcb =3D &entry->ghcb; + + register_ghcb_page(entry->gpa); + + ghcb_set_sw_exit_code(ghcb, SW_EXIT_CODE_IOIO); + ghcb_set_sw_exit_info_1(ghcb, exitinfo1); + ghcb_set_sw_exit_info_2(ghcb, sizeof(data)); + + // Setup the SW Stratch buffer pointer. + ghcb_set_sw_scratch(ghcb, + entry->gpa + offsetof(struct ghcb, shared_buffer)); + memcpy(&ghcb->shared_buffer, &data, sizeof(data)); + + do_vmg_exit(entry->gpa); + + ghcb_free(entry); +} diff --git a/tools/testing/selftests/kvm/lib/x86/ucall.c b/tools/testing/se= lftests/kvm/lib/x86/ucall.c index 1265cecc7dd1..711e58a3a356 100644 --- a/tools/testing/selftests/kvm/lib/x86/ucall.c +++ b/tools/testing/selftests/kvm/lib/x86/ucall.c @@ -5,6 +5,8 @@ * Copyright (C) 2018, Red Hat, Inc. */ #include "kvm_util.h" +#include "processor.h" +#include "sev.h" =20 #define UCALL_PIO_PORT ((uint16_t)0x1000) =20 @@ -21,6 +23,11 @@ void ucall_arch_do_ucall(vm_vaddr_t uc) #define HORRIFIC_L2_UCALL_CLOBBER_HACK \ "rcx", "rsi", "r8", "r9", "r10", "r11" =20 + if (is_sev_es_enabled()) { + sev_es_ucall_port_write(UCALL_PIO_PORT, uc); + return; + } + asm volatile("push %%rbp\n\t" "push %%r15\n\t" "push %%r14\n\t" @@ -48,8 +55,19 @@ void *ucall_arch_get_ucall(struct kvm_vcpu *vcpu) =20 if (run->exit_reason =3D=3D KVM_EXIT_IO && run->io.port =3D=3D UCALL_PIO_= PORT) { struct kvm_regs regs; + uint64_t addr; + + if (is_sev_es_vm(vcpu->vm)) { + TEST_ASSERT( + run->io.count =3D=3D 8 && run->io.size =3D=3D 1, + "SEV-ES ucall exit requires 8 byte string out\n"); + + addr =3D *(uint64_t *)((uint8_t *)(run) + run->io.data_offset); + return (void *)addr; + } =20 vcpu_regs_get(vcpu, ®s); + return (void *)regs.rdi; } return NULL; diff --git a/tools/testing/selftests/kvm/x86/sev_smoke_test.c b/tools/testi= ng/selftests/kvm/x86/sev_smoke_test.c index 3316427eee46..d3670b21261b 100644 --- a/tools/testing/selftests/kvm/x86/sev_smoke_test.c +++ b/tools/testing/selftests/kvm/x86/sev_smoke_test.c @@ -20,8 +20,7 @@ static void guest_snp_code(void) { GUEST_ASSERT(is_sev_snp_enabled()); =20 - wrmsr(MSR_AMD64_SEV_ES_GHCB, GHCB_MSR_TERM_REQ); - vmgexit(); + GUEST_DONE(); } =20 static void guest_sev_es_code(void) @@ -29,12 +28,7 @@ static void guest_sev_es_code(void) /* TODO: Check CPUID after GHCB-based hypercall support is added. */ GUEST_ASSERT(is_sev_es_enabled()); =20 - /* - * TODO: Add GHCB and ucall support for SEV-ES guests. For now, simply - * force "termination" to signal "done" via the GHCB MSR protocol. - */ - wrmsr(MSR_AMD64_SEV_ES_GHCB, GHCB_MSR_TERM_REQ); - vmgexit(); + GUEST_DONE(); } =20 static void guest_sev_code(void) @@ -103,12 +97,7 @@ static void test_sync_vmsa(uint32_t type, uint64_t poli= cy) =20 vcpu_run(vcpu); =20 - TEST_ASSERT(vcpu->run->exit_reason =3D=3D KVM_EXIT_SYSTEM_EVENT, - "Wanted SYSTEM_EVENT, got %s", - exit_reason_str(vcpu->run->exit_reason)); - TEST_ASSERT_EQ(vcpu->run->system_event.type, KVM_SYSTEM_EVENT_SEV_TERM); - TEST_ASSERT_EQ(vcpu->run->system_event.ndata, 1); - TEST_ASSERT_EQ(vcpu->run->system_event.data[0], GHCB_MSR_TERM_REQ); + TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO); =20 compare_xsave((u8 *)&xsave, (u8 *)hva); =20 @@ -129,16 +118,6 @@ static void test_sev(void *guest_code, uint32_t type, = uint64_t policy) for (;;) { vcpu_run(vcpu); =20 - if (is_sev_es_vm(vm)) { - TEST_ASSERT(vcpu->run->exit_reason =3D=3D KVM_EXIT_SYSTEM_EVENT, - "Wanted SYSTEM_EVENT, got %s", - exit_reason_str(vcpu->run->exit_reason)); - TEST_ASSERT_EQ(vcpu->run->system_event.type, KVM_SYSTEM_EVENT_SEV_TERM); - TEST_ASSERT_EQ(vcpu->run->system_event.ndata, 1); - TEST_ASSERT_EQ(vcpu->run->system_event.data[0], GHCB_MSR_TERM_REQ); - break; - } - switch (get_ucall(vcpu, &uc)) { case UCALL_SYNC: continue; --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from CO1PR03CU002.outbound.protection.outlook.com (mail-westus2azon11010004.outbound.protection.outlook.com [52.101.46.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CA38530DED5; Tue, 23 Sep 2025 05:12:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.46.4 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604323; cv=fail; b=NDdylelKkKe6ZkoOhNtmF7a2Z0oc+LW5U9NvkuJf+qjAASf+Q6JurcltrewYk1BfjBYajnXIsBR8qnNB3Vg9XG5sD1MtkrzPtftuc+E4ggf1a7hyaO2UPLzbvRqFXsP9TH/0H1TTtxlWyhzrFJY3rJ3azS4R0/xjt1ltbgu/8bw= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604323; c=relaxed/simple; bh=C1Khm0C3bR1DE+moHfVnUrfokMrMB1fYJLnHVxLuBrM=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=k9/Hl8zSoZibxnqokQ5euiE2NrJnG+7oPY0ygOwiOS80ZuAEBiA1F+9iFUru7WNYd9ScJQcQN4oiYqZ/8vsyZqoBS1Rka+CBktO4Dkju+0dI80sBEdAERqhJeNPH+jOX/BeMmL1u97mi/aA+XN/tgIv0SuhNtSAv4Lv8HcCBgC4= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=lQ/WdCUk; arc=fail smtp.client-ip=52.101.46.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="lQ/WdCUk" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=J7Eb3VNhsxnDjP5IjSmSJCbzdWulB2bZWO+nT3Ndh3nSeEnlzh6oJS9C2QN92e6mwU3mpSthzJJAuf3jPCxekvK7MLkz/xQiAfjCFEpjh0W8F91qhLzxJDh1LkIDNVJSXnTu2+ltI2HFQzwBstq3PtYehDWEnl02wEFAVmLRDLC7v68VYvNCB5hsJmSsrRTVpyWvuSSmsldA7xiWEhdDBU0pgkOUJPP7GWLS1O0tdMv+TN3fWx52HZe4iIT0+DWCHAMTcrUCbDfT3kvP3KvloPtJtIV5wBZKAjCo0Wyjh+nEvmVFwA/QkLSW/rggXHcRizuECqQQHVZ3vYktMqB7Cg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=kpFWPMuftoxWXqI51yHcFjtR93PwDYTYiBSZGhlGlI0=; b=tjrrFdiujWRxjtKCDquiJZ+hmrQYZcEuP1cCcFEaJ27kgcQHt7g1mb9qMnYeDG1s/Wysx80cgEDQ0vsWes0F0Kx7nOtSQtiCuIjTFIa7qQMfixdgpYyib+R67hyeHTTqqQIJZvQuTt3EhBTDK8FNtBDdp5+KTzvZjvcD2XtkCLaC/3zVS459nTdZFjP9gM6dCH50sNDsL4aQqEGI0E40M4Y1ukRl8cBz2hJDdMkMDiSI5myN/k8JbGD66PteN/qSh9h0pFrnGRc19Gev5Gy1afwdQlufoujpEPtq3PgfnLYJ7y+qLDT6oIle1yhINOgyUPatBr8QUUVJVNg4TiDFTg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=kpFWPMuftoxWXqI51yHcFjtR93PwDYTYiBSZGhlGlI0=; b=lQ/WdCUkseM/npe0SB3ABAlKP3bplYrgVWmWREX0lNB2Mltir3ZnxZIz/TYMDsXYW/nR776UhUGY/oQTLNL/Ht6XlFzLwASMPCv0nG2hmZObTOamfuF8tuufcc8NNfpBtbYGj0Ij8/M64JTEVFXoOZ15jdNNTok+KY7tvTAyxxA= Received: from CH2PR12CA0025.namprd12.prod.outlook.com (2603:10b6:610:57::35) by LV5PR12MB9753.namprd12.prod.outlook.com (2603:10b6:408:2b6::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.19; Tue, 23 Sep 2025 05:11:59 +0000 Received: from CH2PEPF00000146.namprd02.prod.outlook.com (2603:10b6:610:57:cafe::38) by CH2PR12CA0025.outlook.office365.com (2603:10b6:610:57::35) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:11:59 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF00000146.mail.protection.outlook.com (10.167.244.103) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:11:59 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:11:54 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 07/35] KVM: selftests: Return an unused GHCB from the pool Date: Tue, 23 Sep 2025 10:39:14 +0530 Message-ID: <20250923050942.206116-8-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF00000146:EE_|LV5PR12MB9753:EE_ X-MS-Office365-Filtering-Correlation-Id: eba7be5b-7e4f-4cff-c5de-08ddfa5fb930 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|82310400026|1800799024|36860700013; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?GBev2MwGhsZavlmLGSCSdIFUsgq4RhV2GsBqlke6dUBJ2SKaosM/utbY3WeD?= =?us-ascii?Q?9MIBqubOqzXHoKsFzhvAqOr9Gwpm0QAT4Kz3Ic7EAlYcys0tyyKId9w3RsHz?= =?us-ascii?Q?RF/qsTpr0gdDP60M2Z0b99yvSY29Zx2+io4S9bJD/VFpUONlYXy5gyVmuv2u?= =?us-ascii?Q?5j21DQRMwoMN947ZjLbCDlM2LFjNtu7RmmyDb9vp4KC/bRpJ1BydJFnPIEvB?= =?us-ascii?Q?5fjXLyyxKjNQyNtU20OSQnMfr6kFrpnCp43pfJ/irl/14v9m8Yg+P05oJ2fq?= =?us-ascii?Q?ZxVXzR52JVA4z+IfimQUDcv98ZjovyVizntRodkAzdp+cct4Z/VCzNcLu/ko?= =?us-ascii?Q?AA69I0QaozntiG9PoljmMfvi9gAN3O0eYRKnI6H0aEEVFLWmI8k8WTFeUH2g?= =?us-ascii?Q?5NHPKuEVgkkiIqAEJZ+neknvNPDdiAMfqNHNj6lQXs9tTbtb6HadxH2R2XrH?= =?us-ascii?Q?izRDyH29wN9AuAeK3SK3CjQ12VJ1MhUJz/0SwtnqyjN1LTv5QuHNtNJUkFHo?= =?us-ascii?Q?xCeBdbGujJJXm/1XCSUH22gnQYQi9yDDzADDpTmmcOgoLuxeDAQg7R2VRvYk?= =?us-ascii?Q?8WSigHuWNAO5WzVVyLBlZlBpgK3X+8iU/fCU/zbixc0b1QXle4z4ODWRnER8?= =?us-ascii?Q?tFJSiT0vHiGCpa8/Wrd3rEjFUu5vc1tlWyPUjFL3TajqxQEYZd9JnDFUWuxj?= =?us-ascii?Q?P2UnSkRXzJgSKZVMKtfSnRWPAzQIFJzf0Ff/SEDHp2Lx3HH3ydEl8ww1zfdi?= =?us-ascii?Q?OMrYbSMlVSjQf9eGAoUk6a5dp1ZHSVo11sE64T/Laa8+vhEaCiF3yX+Sy9qL?= =?us-ascii?Q?2aCrXf/VGThoFLVcsrOxE18xH42pTe7rKgicy8NSP6cR/giINVrjhEcMgOUv?= =?us-ascii?Q?W1+u4OEtSChEUB3hpTZaAk0hLyylF6rtggJuZm6Q9mjgBC5YDJOENFwBJjnY?= =?us-ascii?Q?t0OFkABb7XZsDTEBeU6pnNQQvyyg4lIZhzEfo4wSNV+J+l3bnIIoz5MD+nLi?= =?us-ascii?Q?RIXAgfahHEDNKHrBpX284hE/1FZ/URSjUBu/i9ARZZyDGaiGz2Wlm/KzGka6?= =?us-ascii?Q?zTQE1ZiSIDiBXn7Y7aX7rs56e/YPSIBeleLQUwMJhjSq+zQEYsj7OMM7sxec?= =?us-ascii?Q?qZRG1yF/jdB74Mn5tiIG4zzuVenTxQaRh80z5cxIXS1Gt479SpOVapwBsXXS?= =?us-ascii?Q?CEDcqAhQzRlQTpq8Hee+gtAk6y3idlyuPS/fclvHwGkqDZ/+Y4bVAJoW7nPp?= =?us-ascii?Q?ds5XwIEgqy3Pii2kIi4ctFv4oq7OumIT9jKI9ZWmRIkeaEBd4wtA4iztlk5q?= =?us-ascii?Q?7nswyI7EdcrdnvLL0x4/oTMkslMAard2D264x2MRD7zm81HI58taO4NSqKQT?= =?us-ascii?Q?YDkLb0r6fmxd2UdrpkWwpfSVcY8m4WN7BceU+JHp02FFBg4vpBD8duHr9aRE?= =?us-ascii?Q?c713c4+bPJnmsm1/cfCv6tPfUtqJ9NcBHnDHmbzu7mKCg307x/19l+wBEU1c?= =?us-ascii?Q?OvSgjccjzPv73i90VHjbCGWsL4IvbZYfwgeN?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(376014)(82310400026)(1800799024)(36860700013);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:11:59.1753 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: eba7be5b-7e4f-4cff-c5de-08ddfa5fb930 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF00000146.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: LV5PR12MB9753 Content-Type: text/plain; charset="utf-8" The ghcb_alloc() function in the SEV selftest library always returned the first GHCB from the pool, regardless of whether it was already in use. In a multi-vCPU test, this causes all vCPUs to share and corrupt the same GHCB, leading to unpredictable test failures. Modify ghcb_alloc() to iterate through the pool and return the first entry that is not currently marked as in_use. Mark the selected entry as in use before returning it to prevent other vCPUs from allocating it. Additionally, correct a minor bug in the memset call which was incorrectly taking the address of the ghcb pointer instead of using the pointer value itself. This ensures that each vCPU in a test gets its own unique GHCB, allowing multi-threaded SEV-ES tests to run correctly. Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/lib/x86/sev.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/testing/selftests/kvm/lib/x86/sev.c b/tools/testing/self= tests/kvm/lib/x86/sev.c index de36a6c93839..3090a6518066 100644 --- a/tools/testing/selftests/kvm/lib/x86/sev.c +++ b/tools/testing/selftests/kvm/lib/x86/sev.c @@ -68,7 +68,6 @@ static void sev_es_terminate(void) =20 static struct ghcb_entry *ghcb_alloc(void) { - return &ghcb_pool->ghcbs[0]; struct ghcb_entry *entry; struct ghcb *ghcb; int i; @@ -81,7 +80,7 @@ static struct ghcb_entry *ghcb_alloc(void) entry =3D &ghcb_pool->ghcbs[i]; ghcb =3D &entry->ghcb; =20 - memset(&ghcb, 0, sizeof(*ghcb)); + memset(ghcb, 0, sizeof(*ghcb)); ghcb->ghcb_usage =3D 0; ghcb->protocol_version =3D 1; =20 --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from BN1PR04CU002.outbound.protection.outlook.com (mail-eastus2azon11010002.outbound.protection.outlook.com [52.101.56.2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0781E272E5A; Tue, 23 Sep 2025 05:12:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.56.2 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604344; cv=fail; b=osl7BpDQgMJsCjzyX4y36dcGn60AchKqPrYPhxASlYGkEOqxd8hVYlJsuM6cHbQFwHJrgqgEJt/ACxuvkzJQvPVxmb4YvTn7216qM5RpkxvKwMW/b3v3WzxLfKR4Pt5zzVjBjwj9edhLZhyhtPF8G5JFbrbu6oHC2kD2BLzZ7FE= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604344; c=relaxed/simple; bh=cfuya4EEi8oI/+WmrtyAfsC/M5zrCHYRzoDI5e1mt3A=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=YFGOPI92zsTIVoeZmuJMfMSFBA5nzuQJWV778U7pz65LRWFNIRpabScVFHVt4innH83Kqp0LNeBwrdFlQZR9/FQf9Pe564qDqrrVGDjhRyCM0NnuuJy4lGPkDxJBXDIA1SWJVzsDv9pb+Hhm/ECSBtnbAsdQ8wM4XW3GrlkOql4= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=B807+3xk; arc=fail smtp.client-ip=52.101.56.2 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="B807+3xk" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=mbBI6OmwAogLAXdY+vUalWIFFFtlpXtyR9RLA2EeIrn/ywwrEquta6vqXLG8u3esjE4qsQzia1YWHjewsdTVCUMc6pT9roS373egWAUKPxZDs4oCPrmecTseNIMgvMhdDM0dY22Bctfu3TfmpioQE49uwY8aTiJTUW+pqJml44rbJg0slf8DBwiCjzjr4ZcSMrWHzcMtYSqkwWLVEFWjHyhvqmM6Atd3PtY0EsmNJFQnjfVFA+5Kzr4FJgPi8Uo/h0YIyNDF//lN+o9wMlBLYwhE5tDQ2looJdimUhyY9pNuXuOyBn25f6NQL6eVv3tsMm+rnyEicOR/Q90omhVNiQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=XFCNr+EEcIiPrzgteF56PKu8ebDoTXVm0HeVyhc45WI=; b=HXZThhJWl2vLLbox7J5Y7nHy0P52nnBFxUGIhKPs+01gpM5XXcVELdGnR4x1Yh//txk9vSjbzPnup/DvGiP9X/E461QkSCTWUTNP5G7mM3XBjM+H8fGjOrdqx/CZ2uf4lEN4ueUrqVxIps7MRJlP3epI521uiI8zFa8jFEKQQ1wqU0wNF/qSCaJIb73FC6CLS9GdwsmWNuql/Eaj2oWHJDurDTZPY4dXmqfnY1lW+zz4nS0x2Pc7kqaZhZYpskkMjNKOBSO/UXMchdunNoqmg/YGdmeBI6ssiQ71Dhuf72pS4LAcl/Sk/A1cmrDfovEbZerPtaMW2NQP55WnmRu4Ng== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=XFCNr+EEcIiPrzgteF56PKu8ebDoTXVm0HeVyhc45WI=; b=B807+3xkocDrywRhDVX/PUKi8CyvUgLAbdp2CoM8zhNkyXlblWE5kLK+lQSrqnqOyuJjgSzZfFm5ajtk65USSN2/jOhB6qtKhpA8pEguDIcQFrt36XNcFEfiBERCUkVJtkJvBwp1ijmRYbUQdKYUWuXPxtbI2Qibfag7dfDgQuo= Received: from CH0PR07CA0013.namprd07.prod.outlook.com (2603:10b6:610:32::18) by MN2PR12MB4357.namprd12.prod.outlook.com (2603:10b6:208:262::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.19; Tue, 23 Sep 2025 05:12:18 +0000 Received: from CH2PEPF00000144.namprd02.prod.outlook.com (2603:10b6:610:32:cafe::e5) by CH0PR07CA0013.outlook.office365.com (2603:10b6:610:32::18) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:12:18 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF00000144.mail.protection.outlook.com (10.167.244.101) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:12:18 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:12:11 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 08/35] KVM: selftests: Align GHCB entry struct to page size Date: Tue, 23 Sep 2025 10:39:15 +0530 Message-ID: <20250923050942.206116-9-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF00000144:EE_|MN2PR12MB4357:EE_ X-MS-Office365-Filtering-Correlation-Id: 8964688f-635c-4a30-de22-08ddfa5fc4aa X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|36860700013|82310400026|376014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?QQ3TFZMelSAXI7Zjmly7DhnaMXmytJPELfbSJTubLagZ1pVPyG5hLrUTyavf?= =?us-ascii?Q?cflWRIsmV+KPWtLVCu06roOGp4ubkPArCqEbJUxVDgMEPPJ5UppwAjqLPlio?= =?us-ascii?Q?Fk3kZZfW2GErqmAGAMEKGcbqwEqLU3vVY9rKFOVcuF9I5z6NvUbhPm1Xo6ZU?= =?us-ascii?Q?k+27Y4eHlXrlyG4fUwPTzqjEFWo8djDgRcYmbw9NklvVxdgFB+XkPZkQmD0t?= =?us-ascii?Q?rvN4HikfWAfESK3QJ+9CKynVBev1Jw5gYpwrlvxHZWOB7PlQ6GgWpUfWtS/P?= =?us-ascii?Q?jnBRwVRXd6gfcfbC6BdqfJQbVeLmCf0ivuOogMMj255EzSwafIYpZMn+7Q//?= =?us-ascii?Q?misKBT1C4J7yv/okCQ28fD0HbLS/jgs+Z6OdMEqtUKu3rmjrJmR4y2Ul2/du?= =?us-ascii?Q?xkiqssShg+j0lmAO+oAAT69Iq5k3p4db35234hE1kZ+CcfISn8xN4JO0Ifq3?= =?us-ascii?Q?E7oeezaQvNBL4koOFc2AqDDqMrKfBCI3anjAT5smy1fTYTviS9SRLDHtm0RT?= =?us-ascii?Q?FOZ2YtJ97ENqzoBjnrfZogM8/P7i/qPuRSEtzLaY/3sP53zXjQpFyPZnyE0z?= =?us-ascii?Q?M5bQY7U6vFtjcfWUJqwC5gr05vNDBb8fQuDlsYKQJWN0xds035Zl5So24tPL?= =?us-ascii?Q?m7TEz4FIab2qPtjyclTwuvECLSJ1n/dNuEiqHgI+TsAlJi6FUMe9PoDGCsyM?= =?us-ascii?Q?rEGIQbsu0GlJnd1Bw6eHYli5UC5UWrekHEPwF2saDxGwn/XXeZITGeJZ5Zhy?= =?us-ascii?Q?jpjy4MHPfB4Of7c0Wg8wd1rhatlg9FVjF7TWTBw0BzwsRom+HPU79jxLjIrB?= =?us-ascii?Q?BHDcMO+OFMwlN7a+ytM7a/KnmToOY3NOWaW2xdzB3tWodgE4IVzDjdwZ6n9G?= =?us-ascii?Q?wR1zehcFSBAiqv3//KNv6ED2yqhpiwVzBT3mVMbP7CQl2YaLy+ohCKHg1R1f?= =?us-ascii?Q?pOetRjQqQBm9FxZ6hg5LDAzQSMlPCE13eufZWtz6A7Qy98HL7RDt62n4P0cX?= =?us-ascii?Q?PXSh0vb0yHGj3z+rEv76gwdPzJFmOuIGhKjfWpWXBws6YoEniJ9511VD2pV4?= =?us-ascii?Q?m+h1dES6dvfH32WXdbkSjujMFVGSSnbdijGBE1fG9oUMCq/XRYf6AhWgMCAy?= =?us-ascii?Q?hNTHqk8D5gtbHqHht2rfIkFvyYYBU5Aid/gUf/eZV+NPscdzOIfdSV4vP2oP?= =?us-ascii?Q?Ifa55McivXCPJmaC0LIKLUpoiYNd157WS3C25m6GzzW6yI04KQ7vtd5MRCfY?= =?us-ascii?Q?7kNsAvX0joQjJ+k5AhShyoTQW9TormoczybtDJ/U5d/EcRO5M5GQHFwKqDZy?= =?us-ascii?Q?+7ykj8WVSHKKL7ouLFrKUQJr40P+3VYWy3MgBYWWZrF76AntaEIFbZFBaIcD?= =?us-ascii?Q?nssret6LewZv8Y6bs6H4tx1l/x3tUxfQLecdjOdmb/6/bFPishQscjC17hJ9?= =?us-ascii?Q?gDne4GI6nxolt19IaZJ32VC4EN18iuz83TMT80mYq/hS9AEqtwlnGjjP6KFm?= =?us-ascii?Q?Y74v3mD+1i6rS/gq/82rt/Di+EwU5pv2rL2g?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(36860700013)(82310400026)(376014);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:12:18.4307 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 8964688f-635c-4a30-de22-08ddfa5fc4aa X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF00000144.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4357 Content-Type: text/plain; charset="utf-8" The SEV GHCB specification defines two methods for a guest to register its GHCB page with the hypervisor: an MSR-based protocol and a GPA-based protocol. The hypervisor (KVM) distinguishes between them by inspecting the value written to the MSR_AMD64_SEV_ES_GHCB MSR. If the value has its lower 12 bits as zero, it is treated as a page-aligned Guest Physical Address (GPA). Otherwise, it is interpreted as a command for the MSR-based protocol. The selftest's ghcb_entry struct is not explicitly page-aligned. When the test guest attemptd to register the GHCB by writing its unaligned GPA to the MSR, KVM would incorrectly interpret the request as a malformed MSR-based command instead of a GPA registration. This caused GHCB initialization to fail. Fix this by aligning the ghcb_entry struct definition to PAGE_SIZE. This forces the structure to be page-aligned, ensuring its GPA has zero in the lower 12 bits and allowing KVM to correctly recognize it as a GPA registration request. Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/lib/x86/sev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/kvm/lib/x86/sev.c b/tools/testing/self= tests/kvm/lib/x86/sev.c index 3090a6518066..edefba7f49ce 100644 --- a/tools/testing/selftests/kvm/lib/x86/sev.c +++ b/tools/testing/selftests/kvm/lib/x86/sev.c @@ -22,7 +22,7 @@ struct ghcb_entry { =20 /* Host virtual address of this struct. */ struct ghcb_entry *hva; -}; +} __aligned(PAGE_SIZE); =20 struct ghcb_header { struct ghcb_entry ghcbs[KVM_MAX_VCPUS]; --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from SA9PR02CU001.outbound.protection.outlook.com (mail-southcentralusazon11013041.outbound.protection.outlook.com [40.93.196.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E603730E825; Tue, 23 Sep 2025 05:12:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.196.41 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604360; cv=fail; b=WZbPbYTGhbFrkHUBWVMNZultgo2cYCsSPFgf5Xo98+ui+FylxzcUZuOxiV7IEpRWW+zbHjef2drOe+27MiK4xvieEfPX1fg0EaXmShAbaAGRin5jFtmCYVs7e6F56jD1PHfQXYjd3kPQJOkG4uEdGLStOzruAH+O5d93ZpchDCQ= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604360; c=relaxed/simple; bh=3K9j2U2fXoWWSPMPg2qxN0ZFQzGlug6sFRIsPsiXdZ4=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=kG+SJM8nCSYNsFBvQtUsxXBA/EdMpCgGwgJfcPYWgHUxHN/T6/FWZZ9NetxNVHNlAZOb7T01n1PopKITDwVLtKoEmxK5OY58clsW17bDV3M0V0gJ6+wYSJp4zu/GSd5ksZT9bJkD+vSX6cZcKnyIBoGaHCFtBZ07g7zt+suAKsY= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=EOSRkOq/; arc=fail smtp.client-ip=40.93.196.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="EOSRkOq/" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=wmWn2unVuJaRoJmqAp1P/Kg7aQ4W8gExiZvgZ1ouA7MJqylp/P7U75YmUoabrm3o6/X7BWdOqg63Q/CN/YWTdX1IRzqWn490MtwfY8s+6T2jXCLRYykt8dulkdUDnQ3+HH2Ruw0q65zbhhQKOQMeGjvYt+5uBqQE6YLKI/4teHBw+ydF6FKr/r7YWUfOb48aSMQzQOsDvNsAMVxTTPkAzf6Z818MgYmylnL7ZypFOThco2yUSu6O8SBPVaoGqMpD1817E1Rfq6P5TYEXlrywsKYxsJ4r8pTvneQU2qnHK5/2GLRXpt7dHKyxXOb0AgSFvmYXGWyQuTWEX25lhNILvw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=rosafdskfJVmzghnjyHVOXJxS7z+dJ9hgLO4xLfN0rI=; b=YjvxXd76tmSiyYzKJJOqJz8PGw/MUja/TCuFUkNT+UXD8dHL+lR/K4Nn3IjK39forpJja6H4z4VEk6vggoBO+Ci0Qyn1ki1nSokgpoFfDgmGzBjX+qu0XwI2rOrDgISU9By08vJY+bM8sI+L+b9yQN+1Ipkl7kSRBsHTnh+5ONK5XryifMIPEBC9OOrwvww0veSAHC9HMrpdmhmXMZKfQXXvW3NxCQdTyeZDb8XIlm5MD19no/EoSv+P8Gh3Fe/s1C4BRAOdsl/YcGkns0+YENN5g/9mYdKM3w+teL2ekYABmjObD73DKUDDjVoYu/dauz8FXxZGye1H9NxOsdTFOA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=rosafdskfJVmzghnjyHVOXJxS7z+dJ9hgLO4xLfN0rI=; b=EOSRkOq/zQecpGFTSNayCtGrAX6n6M0cetkfPnwb/1zWAzRHLdwQFSzAorVyvEy93lpKsBfow05kgdupkh65YYK76YXhc2sq9DvBZJcBipP5e0Yw/IJzXeL94jKAedgmUkOQ2+zABjVTiEjDgmRfnDmNcJbXFc5DKSi3GbYIifA= Received: from CH2PR07CA0039.namprd07.prod.outlook.com (2603:10b6:610:5b::13) by DS0PR12MB6463.namprd12.prod.outlook.com (2603:10b6:8:c5::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9115.19; Tue, 23 Sep 2025 05:12:35 +0000 Received: from CH2PEPF0000014A.namprd02.prod.outlook.com (2603:10b6:610:5b:cafe::1a) by CH2PR07CA0039.outlook.office365.com (2603:10b6:610:5b::13) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:12:35 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF0000014A.mail.protection.outlook.com (10.167.244.107) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:12:35 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:12:29 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 09/35] KVM: selftests: Add #VC exception handler with error code support Date: Tue, 23 Sep 2025 10:39:16 +0530 Message-ID: <20250923050942.206116-10-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF0000014A:EE_|DS0PR12MB6463:EE_ X-MS-Office365-Filtering-Correlation-Id: 3ed430c0-5fed-4679-594b-08ddfa5fcea6 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|1800799024|36860700013|376014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?lpY72coTuEcPFpc9Q5mWU7ZLDwOnGJyKYMA48Llvtut7V9e9K4JR/mzaNJcg?= =?us-ascii?Q?vfKW4YBLx8kdTeLI/+ocHI323T+J5cDp7tIVqEM/hnIpE2XW3yTZlBl+sjUl?= =?us-ascii?Q?H4FF0woyisxFYkmgzbbdZHDdWBxfKTbNe47nhf2ENJv5MwZJuZd6qvmK0vmV?= =?us-ascii?Q?oucAA4m/ZtJHqlDDtbtYtZLGo31Rih/wk7Havaob1auMmsLOcthTVlIP21k6?= =?us-ascii?Q?uYYZsLXramLIvOa+YWLkuTZRmhvxe1r+gIX72ygSCH7Td/ta1ndSVbn/pLiM?= =?us-ascii?Q?iJiKl6Y4VM4v2LCg3HcKDLr5fh/5ARkLSELIzrtHc4U28T9M2VeCHG9N7xNE?= =?us-ascii?Q?V/7sIem5Omiv5MLUXjIO6R0Av0h67Uc21M3xFt/SfUcoOcvXgMHyvgPeVfAl?= =?us-ascii?Q?IeITXNIddKr9NylvSRH4/plvz75lLcMyUVFji0vEHMU0frYjL6z5tEA7SnmH?= =?us-ascii?Q?Tl5MY7rbgtlfUq1Wfbhvf00QFieasfJHlMbmi2qA9stezp4QD4A3LapwEVxD?= =?us-ascii?Q?n525DF6V3NWoc0cvZLBki0UjMJ7WAei0hM6jLR/LhHTFzbFIzkiijVn/FQor?= =?us-ascii?Q?RRjJW/JwAT989Q3zsTWMmh3HIayF+C/a5BlfXSgKYQ6ABBAGsoL1HgD2/OtE?= =?us-ascii?Q?Tur0diXp9Z4iDkdNlpXL6uE3iQTUQtR/21XiLLEG7wvX0QylFy4unMVyqXL9?= =?us-ascii?Q?Mpb4BTVUZaIfczD5GVaee4JNe7jX3OS+K/b9GtkQ00Fz3Vphhoy8iZ6YyPfJ?= =?us-ascii?Q?IvjRin7gvPIgWymWdtxFz5GicX77ofXX1szTk3fgBj2d7C6AjwjpTq5T4DIb?= =?us-ascii?Q?cZfDB8Fji7FVU81sutvSZFDkdADDKpHLEDwhA3pP4RkoesWnoPETdB1Fcxv4?= =?us-ascii?Q?t/g9ScoP5fDQKyibdmEBLIb1W6XpKIc1HgNPoCjuNEu9j2zQOm2mFIN/+Ews?= =?us-ascii?Q?6/FtUyQ7NLqANzIj73Ho8BNeiHfRYlTuI1BmIb57PGOhboZ7erw46kzGSVJm?= =?us-ascii?Q?NltdHb0syhNI1pKQNP92/xjTlwzOSjut9T4RXhdwwSNj5ab0tBtENG4tLSsm?= =?us-ascii?Q?QXr4yqZnAN/M/NjNdTwTomK1zodIBF02E1ruOdT8FAjroIQKmbiQO8wfcDo4?= =?us-ascii?Q?lv+9Rb9D3XWaxt1c6K6pMIozQff2L0lDlVZqVqmwDaUT9ODNxl4wcYfgmT13?= =?us-ascii?Q?oN4J3mV78rQnZnF+DwulfB1NpkQECYdaz8qN8SobSDNABpYW9aIENmEA22GE?= =?us-ascii?Q?vm/N7+4s0N3tnW6hEIaeqM0f3uOEV1zqX4YBkq70cNkr1+cskobUarwHefng?= =?us-ascii?Q?4v8XBMkrKaqW8FDnoYoyaId9VLVXVXqmc12bRAPC6RWSjMOC0D5nSqZP5D5t?= =?us-ascii?Q?OQDTnE5RxwlR1At26VdnFRhvLDjnH6hgIty/hEdwf28AX4wYCa+zMGX7qMkU?= =?us-ascii?Q?tdablgH4GtWa9cU6vCkjKqCr2tsz0uUxC8/gvPwJ21ZP6Jja93caNkalZGnp?= =?us-ascii?Q?i28bEvdAFRJEBd9UMOSEpYizS8EMDc/BREQU?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(1800799024)(36860700013)(376014);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:12:35.1794 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 3ed430c0-5fed-4679-594b-08ddfa5fcea6 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF0000014A.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS0PR12MB6463 Content-Type: text/plain; charset="utf-8" The VMM Communication Exception (#VC, vector 29) pushes an error code onto the stack, similar to exceptions like #PF or #GP. The generic IDT handler generation macro in the selftests incorrectly assumed that all vectors from 18 to 255 do not have an error code. For new tests (added in subsequent commits) which trigger #VC exception, this incorrect assumption caused the handler to misinterpret the stack frame and the ex_regs fields, leading to stack corruption upon IRET. Fix this by explicitly defining a handler for vector 29 that correctly accounts for the error code. This allows selftests to properly catch and handle #VC exceptions, which is a prerequisite for testing features like SEV-ES. Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/lib/x86/handlers.S | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/kvm/lib/x86/handlers.S b/tools/testing= /selftests/kvm/lib/x86/handlers.S index 7629819734af..19715a58f5d2 100644 --- a/tools/testing/selftests/kvm/lib/x86/handlers.S +++ b/tools/testing/selftests/kvm/lib/x86/handlers.S @@ -76,6 +76,8 @@ idt_handler_code: HANDLERS has_error=3D1 from=3D10 to=3D14 HANDLERS has_error=3D0 from=3D15 to=3D16 HANDLERS has_error=3D1 from=3D17 to=3D17 - HANDLERS has_error=3D0 from=3D18 to=3D255 + HANDLERS has_error=3D0 from=3D18 to=3D28 + HANDLERS has_error=3D1 from=3D29 to=3D29 + HANDLERS has_error=3D0 from=3D30 to=3D255 =20 .section .note.GNU-stack, "", %progbits --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from PH7PR06CU001.outbound.protection.outlook.com (mail-westus3azon11010024.outbound.protection.outlook.com [52.101.201.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 37D9630DD00; Tue, 23 Sep 2025 05:13:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.201.24 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604381; cv=fail; b=HpaclQDxRCxR4KybVsBvMD17Rw/e8iJyyL6nI1BjQUEr/B8Eq5TJhgTuLcXMq/an+pyc+Il1g/JEgwz2sNkyEpS2d189tqzcn1ELg5Eq95QE9PLRqn8MWcSsmyFLYbGMn7KzTRjeWZw04K8R6OughOuocEITCoIL2k5S6ufc0cY= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604381; c=relaxed/simple; bh=sZPjDcNkA0p8ZkxVxn/kTkO38bmXO0bTLo8NGaCd3WQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=jVCIptG1bd/lklS4mjS85DrbazZKnWFxJir4giWSSnwXNMS91cXG+UqgvRrdtDdzBmubLAnz8jcf7gs6LXy5LulIgXiTL6AhnPjt0vau9bE6Sl+Cb5MHfYjz8bcX+zE4DXP23UzmlQw+B9pkKHCu/z+ZL8Q1TAfCY8Di1WiDOs0= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=I1uGiCU9; arc=fail smtp.client-ip=52.101.201.24 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="I1uGiCU9" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=uSDgydmSBeb5/WvaNxuHc8PDlY/YMcLwBRyE6QomoknC76XbuUChP29rD8jn/5sxDsDJWb7qnvivbqmcYWQzniuB4P0H0mTx13Fhjp/IB8wPvOrlxv1+mXZfxqSv9HSlSrlsHZhMDX0Re7wQJ1nqvlUINKdsk2KfFOD1pYIductZS22CodOKSmxPuGIAP50LDIX9r6nnV8a6D209SZKBjo3s3bGI1w7D+MjVeiR0GkgeOzvE0/OoEZPrSpat+DAICv3enQGOFfFQ5FO/QLHZkWkqLDPM4uzgVbYvTlHjk1LFEhgaWRUUgYxFSg8vQ0XAQ/xoSPvNOc2wXXR2WV3N2w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=gOf6g/hXe+0hyzhPHeC2OmeYnmX/FyghyZyaK8CJLtg=; b=khqXST0lds7+iT09mBIYlDkk2qbCmydFnvA5Oio8+HAUxWtYLxtQjQcxDkR/y8X27/qm9A1MiC3rR+cs/PM/MXpabpi15oPQFUJu5YaEG/qwtKp4lNNQa1VsRtB3kiMUQeTGriDMjsidLCsWpcAXNhkGjgEIIB4Tj8WyHwHFFXe8pPotMCAAHoM+1hsuEBuvhzx9TvQa9o5rq+7vIVKElyzWuTm5WvXriPeH6DWhOyW5jYveDYborgNYIxW6zz6z8P+XhIwfuygXPim01zyNykgg8A8Uf7vUkOBDGwraWmpooJtWwQ62nli4rq4dg6Iv01jAxge/Zi+ZDY+dQNCtzA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=gOf6g/hXe+0hyzhPHeC2OmeYnmX/FyghyZyaK8CJLtg=; b=I1uGiCU9Qnz/fi0Wvr6UxX4Qd00SgB4mfGCt+RcawnzZAJ30PqBctaFv2E5i/CjDtAOCEOi8Ogq88iD4Ixa5Lp8sHzaaNPYJQeQg9dXvY69ZsYTEFdkT3D276IPQ3B2Zh0gr8+Plv1feW3NsqdnHsI3TN7ty+UkjP4rWbnRXbo0= Received: from CH0PR03CA0332.namprd03.prod.outlook.com (2603:10b6:610:11a::9) by IA1PR12MB8310.namprd12.prod.outlook.com (2603:10b6:208:3ff::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.19; Tue, 23 Sep 2025 05:12:54 +0000 Received: from CH2PEPF00000141.namprd02.prod.outlook.com (2603:10b6:610:11a:cafe::7e) by CH0PR03CA0332.outlook.office365.com (2603:10b6:610:11a::9) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:12:54 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF00000141.mail.protection.outlook.com (10.167.244.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:12:54 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:12:47 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 10/35] KVM: selftests: Add MSR access support for SEV-ES guests Date: Tue, 23 Sep 2025 10:39:17 +0530 Message-ID: <20250923050942.206116-11-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF00000141:EE_|IA1PR12MB8310:EE_ X-MS-Office365-Filtering-Correlation-Id: 9b9d28ac-c2ec-4d62-88a4-08ddfa5fd9f3 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|376014|36860700013|82310400026; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?T+b6ujaDrtRzSJ2FB7Y1wDrduPi1vfQwVoyc/6l4XFuX52iu/lH/bto1hMn4?= =?us-ascii?Q?MbPMqi6RXnLoYw+deZhL7KWMDJZr3RqhC0xokHtwaE0bdkbnDjnwZkwGu0B4?= =?us-ascii?Q?MD2avnWWo2yz0KWS3qblfKsr66RlqrZn2BaZTbcYz1eLG4mW4Nzs66qtsnjU?= =?us-ascii?Q?/4w1MVWdNYTdLxhEfXMVvlNlH22LDNLSgBo4qKMIaa5aGvrCBBT2HH1e5SKK?= =?us-ascii?Q?5BiL1endwghdDwJDN4+o+84XP10xWaIYO2GxWmlrEwr1i77ntVaDjGEpNkiv?= =?us-ascii?Q?cADolodcsS7IOB5cyloUlScJSI8mfi2t7XToFB1yRLAxPWK3N69ia+Q7Onut?= =?us-ascii?Q?sjKveeUJqCoGviGmiaHBT33+LPJwQ0gDMSTQMLcFdu0nvaaDKe0S9pSgUygF?= =?us-ascii?Q?DJluBRQOEGRtNJgCyPZz0cJ7SJqt7Jxx5t/gJw7YxsZk5Mytw458TQfdonVl?= =?us-ascii?Q?6se7QjT9UES56ezphsHTFxeZjs4g+O8WuMr2iS0WUdkRkQpxI6+mAROZBM+0?= =?us-ascii?Q?+6O1cRjTHPxk9I10AbpK2t1UcyugtB7zf8hOzhQY/dUAoymg6aUmo84Xa6dH?= =?us-ascii?Q?NKPfJrKdGYduqYwD3atmsSjv6VAUxy3Pu5OSnrRZiJuFA2Xn9mWtASjwZb65?= =?us-ascii?Q?Noy5/1yIlDq9cON4HKzwemMzHe65+N2Zq2AQnvdKTqaPlO9RWKyRp5ZBvAW1?= =?us-ascii?Q?3RblhgOuAtcFXczbeVWh4Cz24J2XKzde54rWaPNIVL3LgD7BvwE9iRDqr56s?= =?us-ascii?Q?2FrqEwp7Fr9SBPatAdHsdF4oqtV2/SCUqVp54ozF9j6gl8Dpe41ZhjegZAyG?= =?us-ascii?Q?N/js+MkusS0wAhPwfEELJbCOLKT/pt6TtImf/PLtZGs7sZwQ65hU6uz0/HKd?= =?us-ascii?Q?+loJjdXJoNsCSO3cwjkBESjnxtZ/AP1vTSCqQ2krb9BEAcKXLE+OGOji+aMa?= =?us-ascii?Q?iSwAytggQ1sNrLLalRj4XfG6OtO3l8Rk9i3YJZ6JPasokbdYg/vL4wtYSrwP?= =?us-ascii?Q?aFdIpNlUy72fc6dlx4CZjMLyhh8hxQutGNpz2FsMNe4AaSV5lQ+1pvXp2IfA?= =?us-ascii?Q?GX75XfkRzSw7+DiRnBIQZ8rCNQj9CGSgHDpHr/vK72IDMhN3355M4LVGl2pQ?= =?us-ascii?Q?byh2H7+wmMuoc43KGqvKV3eI2ITh8LUnLwKbgMs+KVOpheeYziw4fHk9hjCq?= =?us-ascii?Q?YKJjYcn7+sY1ZgN09FBE7jhE5Kk0di9OFNvq5jdXXxqtUDTwDpdW0peuOdB4?= =?us-ascii?Q?H/Z4wYM1dzEuUJ0sbfeQUPl97v90CfxGHzdCpUHD2cVkhaZx6GK7AHT5B1vD?= =?us-ascii?Q?DwsJyeA9/Cxo/3EcrwfvESP/fHlfrq8I9dBLTuq5lbiis9xlZDzY3oaVzGlB?= =?us-ascii?Q?jQWkJsrHBAtDn5gXO76uVc3ZNKVB7S8x/5pPCS6aJhik60AHrP3OAZEUdQPu?= =?us-ascii?Q?7h28m/x5LbhV8Tkryqnl03qZVlZBQPSWxvxz7AWfiEi40v68huZqwvcqj6kQ?= =?us-ascii?Q?z8cO9P9+8KiAEhH7iqXWQ85uHqi8bnKUkNKp?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(376014)(36860700013)(82310400026);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:12:54.1404 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 9b9d28ac-c2ec-4d62-88a4-08ddfa5fd9f3 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF00000141.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA1PR12MB8310 Content-Type: text/plain; charset="utf-8" For SEV-ES guests, RDMSR/WRMSR of the intercepted MSRs trap and generate a #VC (VMM Communication) exception. The guest must then handle this exception and communicate the desired MSR operation to the hypervisor using the GHCB protocol. Add the necessary selftest infrastructure to support this flow, enabling tests to correctly perform MSR operations from within an SEV-ES guest. Two mechanisms are introduced: 1. #VC Exception Handling: Provide a #VC handler, which inspects the trapping instruction and the register state and does a GHCB request to forward the MSR operation to the host . 2. Paravirtual Interface: Provide a direct, "paravirtual" way to test the MSR GHCB protocol. This allows test code to request an MSR read or write without needing to execute a trapping instruction, simplifying certain test scenarios. Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/include/x86/sev.h | 2 + tools/testing/selftests/kvm/lib/x86/sev.c | 83 ++++++++++++++++++- 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/kvm/include/x86/sev.h b/tools/testing/= selftests/kvm/include/x86/sev.h index a4fbea0d3562..9c1fe6be5e68 100644 --- a/tools/testing/selftests/kvm/include/x86/sev.h +++ b/tools/testing/selftests/kvm/include/x86/sev.h @@ -165,4 +165,6 @@ static inline void snp_launch_update_data(struct kvm_vm= *vm, vm_paddr_t gpa, =20 void sev_es_ucall_port_write(uint32_t port, uint64_t data); =20 +void sev_es_vc_handler(struct ex_regs *regs); +void sev_es_pv_msr_rw(uint64_t msr, uint64_t *data, bool write); #endif /* SELFTEST_KVM_SEV_H */ diff --git a/tools/testing/selftests/kvm/lib/x86/sev.c b/tools/testing/self= tests/kvm/lib/x86/sev.c index edefba7f49ce..57ae5a388b8c 100644 --- a/tools/testing/selftests/kvm/lib/x86/sev.c +++ b/tools/testing/selftests/kvm/lib/x86/sev.c @@ -12,7 +12,8 @@ #define IOIO_DATA_8 (1 << 4) #define IOIO_REP (1 << 3) =20 -#define SW_EXIT_CODE_IOIO 0x7b +#define SW_EXIT_CODE_IOIO 0x7b +#define SW_EXIT_CODE_MSR 0x7c =20 struct ghcb_entry { struct ghcb ghcb; @@ -356,3 +357,83 @@ void sev_es_ucall_port_write(uint32_t port, uint64_t d= ata) =20 ghcb_free(entry); } + +static void __sev_es_msr_rw(struct ghcb_entry *entry, uint64_t msr, + uint32_t *low, uint32_t *high, bool write) +{ + uint64_t exitinfo1 =3D write ? 1 : 0; + struct ghcb *ghcb =3D &entry->ghcb; + uint32_t ret; + + ghcb_set_sw_exit_code(ghcb, SW_EXIT_CODE_MSR); + ghcb_set_sw_exit_info_1(ghcb, exitinfo1); + ghcb_set_sw_exit_info_2(ghcb, 0); + + ghcb_set_rcx(ghcb, msr); + if (write) { + ghcb_set_rax(ghcb, *low); + ghcb_set_rdx(ghcb, *high); + } + + do_vmg_exit(entry->gpa); + + ret =3D ghcb->save.sw_exit_info_1 & 0xffffffff; + __GUEST_ASSERT(!ret, "%smsr failed, ret: %u", write ? "wr" : "rd", ret); + + if (!write) { + *low =3D ghcb->save.rax; + *high =3D ghcb->save.rdx; + } +} + +void sev_es_pv_msr_rw(uint64_t msr, uint64_t *data, bool write) +{ + struct ghcb_entry *entry; + uint32_t low, high; + + entry =3D ghcb_alloc(); + register_ghcb_page(entry->gpa); + + if (write) { + low =3D *data & ((1ULL << 32) - 1); + high =3D *data >> 32; + } + __sev_es_msr_rw(entry, msr, &low, &high, write); + + if (!write) + *data =3D low | (uint64_t)high << 32; + + ghcb_free(entry); +} + +static void sev_es_vc_msr_handler(struct ex_regs *regs) +{ + struct ghcb_entry *entry; + bool write; + + /* wrmsr encoding has second byte =3D 0x30 */ + write =3D (*((char *)regs->rip + 1) =3D=3D 0x30); + + entry =3D ghcb_alloc(); + register_ghcb_page(entry->gpa); + + __sev_es_msr_rw(entry, regs->rcx, (uint32_t *)®s->rax, + (uint32_t *)®s->rdx, write); + + ghcb_free(entry); +} + +void sev_es_vc_handler(struct ex_regs *regs) +{ + uint64_t exit_code =3D regs->error_code; + + switch (exit_code) { + case SVM_EXIT_MSR: + sev_es_vc_msr_handler(regs); + /* rdmsr/wrmsr instruction size =3D 2 */ + regs->rip +=3D 2; + break; + default: + __GUEST_ASSERT(0, "No VC handler\n"); + } +} --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from CH4PR04CU002.outbound.protection.outlook.com (mail-northcentralusazon11013006.outbound.protection.outlook.com [40.107.201.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EBE3030DECF; Tue, 23 Sep 2025 05:13:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.201.6 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604401; cv=fail; b=WEfh3QwTsH487LRj4I7SQmVtpEf4m2k5ffjywt7SamiOgF225upo9kbGj7U+QY+IMRwU6JLbmcpXHbAr18NPYNOJTjoVfPxVf//WHTyCsUTfVaPj7BH6oiK6tkCT3K3Ont1HWFQ6rtVocTOKFcbjpxg8oDf8jRvrHqoJLHjsiM8= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604401; c=relaxed/simple; bh=aTtUfQLQy1OZ1nnXtpx5RvRYh/Q2CZvVsTPcNsnOoks=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=uqEMvsxRAA/DoZyUV3kQqWrhFwQ5rUkdKds+xrBOA6GVMBFvTLIHOjjoCSst5tRrwxyxhWtBl8fJ9k5ERhjr3z/ZL/cLAdtatyFbD0VO6t5/go6ZH8RXKZrMTSp5C+qIa0b8nS4Fyqv4NxmU36L034croKYDY5ycPTDBotZp9KU= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=oUjODJDZ; arc=fail smtp.client-ip=40.107.201.6 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="oUjODJDZ" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=d3NvvleDsu6voAYJPVbFoOFM7JZoinnF0hQd0F7tOmbl4XSjc9KFN6SljS9dx2nFB8z0fiNiLTwBUM6I/ZlywwujDzn7DWVYD0Pd7tMblvr9MYHf0uuZDWP2JUHN3vCECtjieE957mOsXuySMJbTAufbpjT/8kd8P9CRmoJMb1fbN5cFAgrT+tRly3cMRwCo5erWig2aCj3g5s5hww10b//mg0JeqL8Hv1f4MoPSbSWsavgvbxveJOoxS7LGETsMqtBd1vdTUvvNGNiHf9xANNwx4EqfPss1P57X/ZxglVFdtfzHlcNqHCHR5+jWTlaapk+Az4BSEkBh95+McXJlEA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=S3quAgaIovj0XoMvkwqAjZDXRQC/N2Q6DX4p0HVQoTQ=; b=y5+WiNUWI19oqf5D+DBwQrA8DGhinQPlSUrc2dSrBhoJ/KAMVZfcKra1UKP+ijVBugbPCiKvPkjGAxvxeBwbNZrpbRnrWwALASbnLcvHyN+LL8rwhyjykfWpsA1SnLL7wuzVCKvsIEh6vOE5fmy7Ef0mWPvPb12lsObd3ffjuCobS/sDUNkGrw3Qn2fwr4MCq6hFXvFFlXVGXdMbSdHcV3EQGoOrEwsx6gWa40ijiMRvAOS0CgpHl+h8bFIykpXeI7NQJeHqjCDMWiMJywA5A9vNKUo4bYMUkb0UQDI2TsowBNxYHhAKrUZfoDdDAstzF0uVmwiuB33DKP++9P27qA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=S3quAgaIovj0XoMvkwqAjZDXRQC/N2Q6DX4p0HVQoTQ=; b=oUjODJDZU+EQF946YGlZrs26Xvj6tkEYj20aZkQ36drtnXOaQHata2hGdN6IE5NnCN5qaaI68rXnNjbNDAantLCPF6rFcDuwdK0daby5ethivKFcyLWrQbnPDJRFxEBzO3x/jrawlUrBk0LUN6FXplR2lQ0C7NmM2IQ/v30fGIA= Received: from CH2PR16CA0010.namprd16.prod.outlook.com (2603:10b6:610:50::20) by SA3PR12MB7879.namprd12.prod.outlook.com (2603:10b6:806:306::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.20; Tue, 23 Sep 2025 05:13:13 +0000 Received: from CH2PEPF0000013B.namprd02.prod.outlook.com (2603:10b6:610:50:cafe::d9) by CH2PR16CA0010.outlook.office365.com (2603:10b6:610:50::20) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:13:13 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF0000013B.mail.protection.outlook.com (10.167.244.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:13:13 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:13:05 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 11/35] KVM: selftests: Skip guest memory checks for APIC MMIO mapping Date: Tue, 23 Sep 2025 10:39:18 +0530 Message-ID: <20250923050942.206116-12-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF0000013B:EE_|SA3PR12MB7879:EE_ X-MS-Office365-Filtering-Correlation-Id: 3ed27ce2-9d92-43ce-9fe3-08ddfa5fe55d X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|36860700013|1800799024|376014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?rsYgwFlTRjYjAH37lieT4EKxpWLd5I5j/KmvMDRcp9JyvduwttM2LkAY6Q3H?= =?us-ascii?Q?ojtW243gGTzShe7exRwEgSWWt++TK0cPIQ6hfS/OB1Uaz7rykP0faO3owJhH?= =?us-ascii?Q?goO6wiZvUnW4S1gj88MqipkAm34qSIdBSvpfe4bcnnbxJzCqAYB97E9ipUdw?= =?us-ascii?Q?NSwKRNGMgn/aFBNbzX/Sz7xGiHBAHiKQo5d2jCTQbgb+VjD2GFihZxK0Ck9S?= =?us-ascii?Q?he9QF18EUHvr6qeRWejuEZMwrX52gMChbo+HNglOJwmVx1o9VtuE+cSqqm+R?= =?us-ascii?Q?kjanloS78LoWLckq8q45Q9ayk/iW0s2jpg/tVbx5O6qLJ/8+G2bgB+cBvEH2?= =?us-ascii?Q?hses4sBWQqlRQri1JhZTN2H1iu0LKHA9iPu2D+gy95ps9Ee1peaEYeo6p26C?= =?us-ascii?Q?LqkxqstfZg1WiOVKVkdXl94gop6ZPP93NduVRn0dZz9Pc9QZfAOFJTN322Pv?= =?us-ascii?Q?vRaw2wyTUmYGEQPyFX33uw7SJGk+c3jQtTsc05sZ2v56bGjwyAzBArYR5PBw?= =?us-ascii?Q?Wr7g/GYC//WU3iFhCwmpUumHd46UMyuo4H6VF6ixtoeLDV/otvZyCjGiDNF0?= =?us-ascii?Q?RkYCplNtepMr2zkKSB335fHXZX1G5Te7hNZWs/wePlK16Vvyif9JnFjJtrhw?= =?us-ascii?Q?5OUgHaEBEOC97kBSMvjyqc69qyfcuDo0qCXmfyDCLKoUE0CuuhBjUlvMIE2H?= =?us-ascii?Q?oSarhDhm4GlUjB1ROAgyW1rlLftz38ebz2ULDuuIENLN0m9M4/mq3lI21BKf?= =?us-ascii?Q?mWV5Dbq/iLh+E5d91Hql/0tGyFC39K8qhpo13VzKaHQUvMkGYD2MSnVhqkHh?= =?us-ascii?Q?lMDXhkgrwGq6+YOonIo++6g+/JZPADuYcV3fFRFG5+TZ5yILzmWQy9w3GnIx?= =?us-ascii?Q?hnFcUa5XTIlUW+Qrtk8TgCKrewrBDu718KZ7M5fEMvKz05Ic67tjzP1nmCZk?= =?us-ascii?Q?Nryi+kSdYPxiRp6KQKJmo/ydTU6KAgACkleW7u8gV2zVWJ/6WXK8T3hAUvO/?= =?us-ascii?Q?S3ue1iWe+s16Sa1nUNsQWYbicEXkdVsoLdDmH12E/2xY7elLcLqPJM7ndmPb?= =?us-ascii?Q?xOtv3OJcIxCbJv9z2pypYAd6TZ7X02I1RyiRMr0SJ0Vj/kxZkLeU+EWhNdFT?= =?us-ascii?Q?yD8SukmYjcEGiE3PdwOLCXb1/ziC0pya9ZdMvK6GYWOb7rZ19JzNvD3C+0oP?= =?us-ascii?Q?/mqyk2WutvU7OjVATOUzv2KxWBh5MXsIieSaUR///PYvwJfeIaVIKJqTMy8J?= =?us-ascii?Q?W2RR4lvRVMhWbx/BdS3H88fFtow1SegAeh8PPeqkGF4VFzfYuesZqO+EpHmM?= =?us-ascii?Q?jtRrc7vdoFxAvk580uaevisBLx0PuKp9Tg2SKXD5IH6QqqcFcoKf1FaJfF8L?= =?us-ascii?Q?OQANoc+ZFBdUYS2fmxeal8Hcmvd6vP4gKxGH6vhs0DyW+59AbeRiLTYs8aNm?= =?us-ascii?Q?D/lq2hEbRsWmiq0tObiXArjwNTctDkCrg/+pWR1G5Ica2TB5ZJp5PNqtDhm1?= =?us-ascii?Q?svfAuvHpPgVCbM7MH1O6BD4TsnAXRgE57RBm?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(36860700013)(1800799024)(376014);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:13:13.2903 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 3ed27ce2-9d92-43ce-9fe3-08ddfa5fe55d X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF0000013B.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA3PR12MB7879 Content-Type: text/plain; charset="utf-8" The __virt_pg_map() helper function, used to build guest page tables, calls vm_is_gpa_protected() to determine the correct memory protection attributes for a given Guest Physical Address (GPA). This check works by looking up the GPA in the VM's defined physical memory regions. This approach fails when mapping the local APIC's base address (0xfee00000), as this is a Memory-Mapped I/O (MMIO) region, not part of the guest's RAM. Consequently, the lookup fails, and virt_pg_map() aborts with the error: "No vm physical memory at 0xfee00000". Fix this by introducing a special case for the APIC base address. When the physical address being mapped is APIC_DEFAULT_GPA, bypass the vm_is_gpa_protected() call. Since the APIC MMIO region is always treated as shared, explicitly set the shared bit in its Page Table Entry (PTE) and return immediately. This allows selftests to correctly map the APIC MMIO region, which is necessary for tests involving protected guests. Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/lib/x86/processor.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testin= g/selftests/kvm/lib/x86/processor.c index d72eb96efb7c..181f1943c4be 100644 --- a/tools/testing/selftests/kvm/lib/x86/processor.c +++ b/tools/testing/selftests/kvm/lib/x86/processor.c @@ -8,6 +8,7 @@ #include "kvm_util.h" #include "processor.h" #include "sev.h" +#include "apic.h" =20 #ifndef NUM_INTERRUPTS #define NUM_INTERRUPTS 256 @@ -227,6 +228,11 @@ void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, = uint64_t paddr, int level) "PTE already present for 4k page at vaddr: 0x%lx", vaddr); *pte =3D PTE_PRESENT_MASK | PTE_WRITABLE_MASK | (paddr & PHYSICAL_PAGE_MA= SK); =20 + if (paddr =3D=3D APIC_DEFAULT_GPA) { + *pte |=3D vm->arch.s_bit; + return; + } + /* * Neither SEV nor TDX supports shared page tables, so only the final * leaf PTE needs manually set the C/S-bit. --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from BL2PR02CU003.outbound.protection.outlook.com (mail-eastusazon11011044.outbound.protection.outlook.com [52.101.52.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A557630DEA0; Tue, 23 Sep 2025 05:13:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.52.44 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604419; cv=fail; b=WrEjyRMR2P2DxM0uKYVU2u+yEiajPyYnUeeypy4SHQ12HQoAxFBueet0y5gp6DtZJX6Eothl5n9oVJsBVpSoEN0v5MTkxP4HLSWl1LEMhKs7H2Sil83QkTOwA1JKmqSjyr+L8ctciqruey57XaVqbBFbCbm9HXGRzlMZQSZq/Do= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604419; c=relaxed/simple; bh=Fk0RDiKry4RvH+VCdzFrFaillU7UDan9eiTMzCW8G6s=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=VVevY9ImryrBoOCQkPuFvX2UFE5ba7sSL/uS+k2cyIPcL/77E26FtUqg/Jww+Kwsz8+pA8NUOF+lYRcUcjRh4VY7nh8fre/2Oa0LfFDvdsSY5k87medNlEejIrmAyJhGWHbJLM27ZNTQl8RwJrk7XnykRt7ebuGg870fgHqp2OM= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=bd7EM6Zj; arc=fail smtp.client-ip=52.101.52.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="bd7EM6Zj" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=LlnYWXgy1vsN/UyrZ23RF2MTCix85er98BHWNTXHPFanvzuUOKXbUuTUWqKVsbBkACd8j0+s2kai6Z09wpxHTRipNI+Jy9mx1NH8RoyfZaIzW2cwnFw0NTv74M2iUey/otBMCZK4y6nWRcOsOdy1nsY5dtgYUJmCXgnda18i5MuRNWyWSQEqMqgOE2J2sg8Astw95PkU6IWcanshz0MScAsQjCimsL8O6U/Ks37rymsKGEa3AKmLVPEAkE64/v+sqv0eH6rlXlBbNUZkzlYOAU/AeNfj5Utbv3qdBS5AywZQLwodZVUTJ5cULBD4YU7oIs0zA00KJIAcmbPawZICaw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=zb/XH0Gek1bTTRXKnRGiQrMQfbdlQ5hf+c2zaVKt46g=; b=g7/HJuKSiTHBni3pIwECkBN8J1/6pfssnQXlqS5JXZ0Ce6XCoTUGzbeumq43vltipORhW0H2PUc/L/ikcogAhgGoumIM9XNAVpJUCnTth91QFwKgB//PaAiU5DsM/ETsL9k4DKbW+/xqKoNo5mIqbIcml7R6lLGpGEh/RehPxQYd+AFyZ26m//3aCIPZFVcR+VoWWokFUJdvCFNTwUS7sh9/y4zbIs1hIAJdQ50g6JgJIh5w0kwzBzHBAxjD1T6InDD+0xc4zBBj1FkMobdX38LambIME1PFIv1NyG74WmwdnGdtM2SAmX7OQGwqtzBFLZY9LWGFIq5cRRG7Y27E4w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=zb/XH0Gek1bTTRXKnRGiQrMQfbdlQ5hf+c2zaVKt46g=; b=bd7EM6ZjnaUhaTiTC9Mn2UTBLR9ccc2kwP2LVdI/ft5LwEKZ568FArs1s3+AZTVYsPR5RnbWFq8hJXl3kdVaIE/6z9S1kVyFq/Zdvt4I2sF5mr4bfkPTTmjrbQpZP3qdrS+SKC5eMTI43jy0ZtVJSeCef9e5ZsO3PiTQzUuxNks= Received: from CH2PR16CA0007.namprd16.prod.outlook.com (2603:10b6:610:50::17) by SN7PR12MB6716.namprd12.prod.outlook.com (2603:10b6:806:270::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.19; Tue, 23 Sep 2025 05:13:29 +0000 Received: from CH2PEPF0000013B.namprd02.prod.outlook.com (2603:10b6:610:50:cafe::4) by CH2PR16CA0007.outlook.office365.com (2603:10b6:610:50::17) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:13:29 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF0000013B.mail.protection.outlook.com (10.167.244.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:13:29 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:13:23 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 12/35] KVM: selftests: Add x86 instruction decoding library Date: Tue, 23 Sep 2025 10:39:19 +0530 Message-ID: <20250923050942.206116-13-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF0000013B:EE_|SN7PR12MB6716:EE_ X-MS-Office365-Filtering-Correlation-Id: 2e7a052c-32a7-4a52-c5bc-08ddfa5feed3 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|36860700013|82310400026|376014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?93ccuXOtb43liboCkeXHcYyq2mZd++ucYYtThAj2ZZh772I/fS4ru/DFkW+L?= =?us-ascii?Q?36RxhlR3VQ3qgS9O0yc71BC46GOiscbQrSBNj4SkmbN/n/iRAK4ZoNqiNJQr?= =?us-ascii?Q?r2aJv+VHjTw0hJW4aou7taLvqoA2Vto4BKrwOei5QG04i0WwXRKDKwvUDZ6H?= =?us-ascii?Q?RqcLAAdo95pChuQSNE362TrB2teC7CTx8acTMrFRkw3dpYvAAVams3CH+XmG?= =?us-ascii?Q?q18dfmfXjHMqV1Z24SnNkEQLFu67I411L/xeHsIvc/I7/nzcIE5K1Fl228Jl?= =?us-ascii?Q?wzuQE1fDcf6aiSRwdSwhlvrqx2i7DAV3xRpX4JrkQHSP2u57Wuv9m6tDLmT/?= =?us-ascii?Q?rLBxKXiKphagVdwv14sb9MAbs9rXocZEYHLsHsoc8c5qx6b4LWATKGepAkOg?= =?us-ascii?Q?Pc6CHQZtCQknyr/RKqs1E/krSTkJtV0RS+MORWFSIhU0KOHF5sqwfLWyGadc?= =?us-ascii?Q?SH5JCWgvrlSW3fMpTPPbrMVZewvEoyiRiyK415t/sgP0hQinxun06em63v2w?= =?us-ascii?Q?mu5aS/zl0vDmroHtSwvTwcvnjtzsXQ3l1Ef/2FhmbCTdG1Zdy6v1kl3QLisn?= =?us-ascii?Q?rET8YmmYJnatbAzM/OD5SJ+rapiWTUqNGZeQljPzlLbhZSFcuac5vVZrM6iK?= =?us-ascii?Q?vOid1y2a/1ZW3pk7F3DYepDFNW01y2Z4IJ3DMu0KT/86jbLEwq8paSqhgRwb?= =?us-ascii?Q?sSbdM1Jtw69ke2lJDsM9m9g0qsSYgOT0tmIfVXxbJ3gMwnTr6uVfNeBczEkZ?= =?us-ascii?Q?rfwsybq3nuAyIHSsZkvSX+rVLIFJaMk1IOdNbz5wcrQi8T2ibsGvTPu59xjZ?= =?us-ascii?Q?aIPfP++RFAg8Lp2Nssb1s3a8qM2e2OUwbfz2MCaWUjBQRMvleEbsPdd8TVGg?= =?us-ascii?Q?Bipx05r03afegXRksz4gbb8eugX05GM/9zB/4OTe4+YamFTh8ZxjtBMRVTUY?= =?us-ascii?Q?ytlCOqM8NLH8ajEGNJa8t0wvUlUPoPdTvzt254+VX6c0PmGS+V+V22IC5hsQ?= =?us-ascii?Q?a0nFVTH/cM+L+itxslv39rqQSj3XLx9rmVDm4w63aw6uT0qL1bHXOJRYf9Af?= =?us-ascii?Q?0ryYx9XPwZhz5Tf3/2FuYk7lJOmHFznIg8gyOwEiKvyjEZ4bMqKH29F4m4GJ?= =?us-ascii?Q?/sp6L/U0KEzafMqwHo9NvzXzwhUyZOWVAYTDbf4GC0+x/gGkR4yrTXctBM6M?= =?us-ascii?Q?bbQggqur7Webau94ZSjOIBWzg2MHd4aetT4HuGogiu8fUPqYch77dQ2IjmT5?= =?us-ascii?Q?8JvNG3DLIRSQWyYwP7y8uHgr1o5+mvgEd+5TVBnrh0dk09BOq37jwnC8mSip?= =?us-ascii?Q?PAAbd9tANSctUl7Tqb/EhN/CYlMLHmb2I7ZoAtYCmahrU7FHNygr5RlWs/39?= =?us-ascii?Q?sPBZKWH4UWxbmcTEisa7Cx7mKRoDYz+1KDtUs/hwEYgpsjEHJ+sYe6zqwqU0?= =?us-ascii?Q?HI/8/pvv7/9ca4LgHHtrtxqF10hqdU0dCPZmE07jdj5aw8F9FyP45rMWhdEb?= =?us-ascii?Q?njNrw28DGEhyVqnBQU+xkfM2iDoIuTtPgfWo?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(36860700013)(82310400026)(376014);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:13:29.1639 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 2e7a052c-32a7-4a52-c5bc-08ddfa5feed3 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF0000013B.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR12MB6716 Content-Type: text/plain; charset="utf-8" For SEV-ES guests, certain MMIO accesses are configured to trap, generating a #VC (VMM Communication) exception. The guest-side instruction. To perform this emulation correctly, the handler needs to decode the instruction to determine its properties, such as the access size (byte, word, dword), direction (read/write), and the registers involved. This requires an instruction decoding library. Introduce the kernel's x86 instruction decoder (arch/x86/lib/insn-eval.c) into the selftest library to provide this capability. For ease of review, add an unmodified snapshot of the kernel file. Subsequent commits will strip it down to only the functionality required for emulating MMIO instruction, reducing its size and complexity for the selftest environment. Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/.gitignore | 3 +- .../selftests/kvm/include/x86/insn-eval.h | 47 + .../testing/selftests/kvm/lib/x86/insn-eval.c | 1678 +++++++++++++++++ 3 files changed, 1727 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/kvm/include/x86/insn-eval.h create mode 100644 tools/testing/selftests/kvm/lib/x86/insn-eval.c diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftes= ts/kvm/.gitignore index 1d41a046a7bf..7f75c8a2f722 100644 --- a/tools/testing/selftests/kvm/.gitignore +++ b/tools/testing/selftests/kvm/.gitignore @@ -9,4 +9,5 @@ !config !settings !Makefile -!Makefile.kvm \ No newline at end of file +!Makefile.kvm + diff --git a/tools/testing/selftests/kvm/include/x86/insn-eval.h b/tools/te= sting/selftests/kvm/include/x86/insn-eval.h new file mode 100644 index 000000000000..54368a43abf6 --- /dev/null +++ b/tools/testing/selftests/kvm/include/x86/insn-eval.h @@ -0,0 +1,47 @@ +#ifndef _ASM_X86_INSN_EVAL_H +#define _ASM_X86_INSN_EVAL_H +/* + * A collection of utility functions for x86 instruction analysis to be + * used in a kernel context. Useful when, for instance, making sense + * of the registers indicated by operands. + */ + +#include +#include +#include +#include + +#define INSN_CODE_SEG_ADDR_SZ(params) ((params >> 4) & 0xf) +#define INSN_CODE_SEG_OPND_SZ(params) (params & 0xf) +#define INSN_CODE_SEG_PARAMS(oper_sz, addr_sz) (oper_sz | (addr_sz << 4)) + +int pt_regs_offset(struct pt_regs *regs, int regno); + +bool insn_has_rep_prefix(struct insn *insn); +void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs); +int insn_get_modrm_rm_off(struct insn *insn, struct pt_regs *regs); +int insn_get_modrm_reg_off(struct insn *insn, struct pt_regs *regs); +unsigned long *insn_get_modrm_reg_ptr(struct insn *insn, struct pt_regs *r= egs); +unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx); +int insn_get_code_seg_params(struct pt_regs *regs); +int insn_get_effective_ip(struct pt_regs *regs, unsigned long *ip); +int insn_fetch_from_user(struct pt_regs *regs, + unsigned char buf[MAX_INSN_SIZE]); +int insn_fetch_from_user_inatomic(struct pt_regs *regs, + unsigned char buf[MAX_INSN_SIZE]); +bool insn_decode_from_regs(struct insn *insn, struct pt_regs *regs, + unsigned char buf[MAX_INSN_SIZE], int buf_size); + +enum insn_mmio_type { + INSN_MMIO_DECODE_FAILED, + INSN_MMIO_WRITE, + INSN_MMIO_WRITE_IMM, + INSN_MMIO_READ, + INSN_MMIO_READ_ZERO_EXTEND, + INSN_MMIO_READ_SIGN_EXTEND, + INSN_MMIO_MOVS, +}; + +enum insn_mmio_type insn_decode_mmio(struct insn *insn, int *bytes); + +#endif /* _ASM_X86_INSN_EVAL_H */ diff --git a/tools/testing/selftests/kvm/lib/x86/insn-eval.c b/tools/testin= g/selftests/kvm/lib/x86/insn-eval.c new file mode 100644 index 000000000000..4e385cbfd444 --- /dev/null +++ b/tools/testing/selftests/kvm/lib/x86/insn-eval.c @@ -0,0 +1,1678 @@ +/* + * Utility functions for x86 operand and address decoding + * + * Copyright (C) Intel Corporation 2017 + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef pr_fmt +#define pr_fmt(fmt) "insn: " fmt + +enum reg_type { + REG_TYPE_RM =3D 0, + REG_TYPE_REG, + REG_TYPE_INDEX, + REG_TYPE_BASE, +}; + +/** + * is_string_insn() - Determine if instruction is a string instruction + * @insn: Instruction containing the opcode to inspect + * + * Returns: + * + * true if the instruction, determined by the opcode, is any of the + * string instructions as defined in the Intel Software Development manual. + * False otherwise. + */ +static bool is_string_insn(struct insn *insn) +{ + /* All string instructions have a 1-byte opcode. */ + if (insn->opcode.nbytes !=3D 1) + return false; + + switch (insn->opcode.bytes[0]) { + case 0x6c ... 0x6f: /* INS, OUTS */ + case 0xa4 ... 0xa7: /* MOVS, CMPS */ + case 0xaa ... 0xaf: /* STOS, LODS, SCAS */ + return true; + default: + return false; + } +} + +/** + * insn_has_rep_prefix() - Determine if instruction has a REP prefix + * @insn: Instruction containing the prefix to inspect + * + * Returns: + * + * true if the instruction has a REP prefix, false if not. + */ +bool insn_has_rep_prefix(struct insn *insn) +{ + insn_byte_t p; + int i; + + insn_get_prefixes(insn); + + for_each_insn_prefix(insn, i, p) { + if (p =3D=3D 0xf2 || p =3D=3D 0xf3) + return true; + } + + return false; +} + +/** + * get_seg_reg_override_idx() - obtain segment register override index + * @insn: Valid instruction with segment override prefixes + * + * Inspect the instruction prefixes in @insn and find segment overrides, i= f any. + * + * Returns: + * + * A constant identifying the segment register to use, among CS, SS, DS, + * ES, FS, or GS. INAT_SEG_REG_DEFAULT is returned if no segment override + * prefixes were found. + * + * -EINVAL in case of error. + */ +static int get_seg_reg_override_idx(struct insn *insn) +{ + int idx =3D INAT_SEG_REG_DEFAULT; + int num_overrides =3D 0, i; + insn_byte_t p; + + insn_get_prefixes(insn); + + /* Look for any segment override prefixes. */ + for_each_insn_prefix(insn, i, p) { + insn_attr_t attr; + + attr =3D inat_get_opcode_attribute(p); + switch (attr) { + case INAT_MAKE_PREFIX(INAT_PFX_CS): + idx =3D INAT_SEG_REG_CS; + num_overrides++; + break; + case INAT_MAKE_PREFIX(INAT_PFX_SS): + idx =3D INAT_SEG_REG_SS; + num_overrides++; + break; + case INAT_MAKE_PREFIX(INAT_PFX_DS): + idx =3D INAT_SEG_REG_DS; + num_overrides++; + break; + case INAT_MAKE_PREFIX(INAT_PFX_ES): + idx =3D INAT_SEG_REG_ES; + num_overrides++; + break; + case INAT_MAKE_PREFIX(INAT_PFX_FS): + idx =3D INAT_SEG_REG_FS; + num_overrides++; + break; + case INAT_MAKE_PREFIX(INAT_PFX_GS): + idx =3D INAT_SEG_REG_GS; + num_overrides++; + break; + /* No default action needed. */ + } + } + + /* More than one segment override prefix leads to undefined behavior. */ + if (num_overrides > 1) + return -EINVAL; + + return idx; +} + +/** + * check_seg_overrides() - check if segment override prefixes are allowed + * @insn: Valid instruction with segment override prefixes + * @regoff: Operand offset, in pt_regs, for which the check is performed + * + * For a particular register used in register-indirect addressing, determi= ne if + * segment override prefixes can be used. Specifically, no overrides are a= llowed + * for rDI if used with a string instruction. + * + * Returns: + * + * True if segment override prefixes can be used with the register indicat= ed + * in @regoff. False if otherwise. + */ +static bool check_seg_overrides(struct insn *insn, int regoff) +{ + if (regoff =3D=3D offsetof(struct pt_regs, di) && is_string_insn(insn)) + return false; + + return true; +} + +/** + * resolve_default_seg() - resolve default segment register index for an o= perand + * @insn: Instruction with opcode and address size. Must be valid. + * @regs: Register values as seen when entering kernel mode + * @off: Operand offset, in pt_regs, for which resolution is needed + * + * Resolve the default segment register index associated with the instruct= ion + * operand register indicated by @off. Such index is resolved based on def= aults + * described in the Intel Software Development Manual. + * + * Returns: + * + * If in protected mode, a constant identifying the segment register to us= e, + * among CS, SS, ES or DS. If in long mode, INAT_SEG_REG_IGNORE. + * + * -EINVAL in case of error. + */ +static int resolve_default_seg(struct insn *insn, struct pt_regs *regs, in= t off) +{ + if (any_64bit_mode(regs)) + return INAT_SEG_REG_IGNORE; + /* + * Resolve the default segment register as described in Section 3.7.4 + * of the Intel Software Development Manual Vol. 1: + * + * + DS for all references involving r[ABCD]X, and rSI. + * + If used in a string instruction, ES for rDI. Otherwise, DS. + * + AX, CX and DX are not valid register operands in 16-bit address + * encodings but are valid for 32-bit and 64-bit encodings. + * + -EDOM is reserved to identify for cases in which no register + * is used (i.e., displacement-only addressing). Use DS. + * + SS for rSP or rBP. + * + CS for rIP. + */ + + switch (off) { + case offsetof(struct pt_regs, ax): + case offsetof(struct pt_regs, cx): + case offsetof(struct pt_regs, dx): + /* Need insn to verify address size. */ + if (insn->addr_bytes =3D=3D 2) + return -EINVAL; + + fallthrough; + + case -EDOM: + case offsetof(struct pt_regs, bx): + case offsetof(struct pt_regs, si): + return INAT_SEG_REG_DS; + + case offsetof(struct pt_regs, di): + if (is_string_insn(insn)) + return INAT_SEG_REG_ES; + return INAT_SEG_REG_DS; + + case offsetof(struct pt_regs, bp): + case offsetof(struct pt_regs, sp): + return INAT_SEG_REG_SS; + + case offsetof(struct pt_regs, ip): + return INAT_SEG_REG_CS; + + default: + return -EINVAL; + } +} + +/** + * resolve_seg_reg() - obtain segment register index + * @insn: Instruction with operands + * @regs: Register values as seen when entering kernel mode + * @regoff: Operand offset, in pt_regs, used to determine segment register + * + * Determine the segment register associated with the operands and, if + * applicable, prefixes and the instruction pointed by @insn. + * + * The segment register associated to an operand used in register-indirect + * addressing depends on: + * + * a) Whether running in long mode (in such a case segments are ignored, e= xcept + * if FS or GS are used). + * + * b) Whether segment override prefixes can be used. Certain instructions = and + * registers do not allow override prefixes. + * + * c) Whether segment overrides prefixes are found in the instruction pref= ixes. + * + * d) If there are not segment override prefixes or they cannot be used, t= he + * default segment register associated with the operand register is use= d. + * + * The function checks first if segment override prefixes can be used with= the + * operand indicated by @regoff. If allowed, obtain such overridden segment + * register index. Lastly, if not prefixes were found or cannot be used, r= esolve + * the segment register index to use based on the defaults described in the + * Intel documentation. In long mode, all segment register indexes will be + * ignored, except if overrides were found for FS or GS. All these operati= ons + * are done using helper functions. + * + * The operand register, @regoff, is represented as the offset from the ba= se of + * pt_regs. + * + * As stated, the main use of this function is to determine the segment re= gister + * index based on the instruction, its operands and prefixes. Hence, @insn + * must be valid. However, if @regoff indicates rIP, we don't need to insp= ect + * @insn at all as in this case CS is used in all cases. This case is chec= ked + * before proceeding further. + * + * Please note that this function does not return the value in the segment + * register (i.e., the segment selector) but our defined index. The segment + * selector needs to be obtained using get_segment_selector() and passing = the + * segment register index resolved by this function. + * + * Returns: + * + * An index identifying the segment register to use, among CS, SS, DS, + * ES, FS, or GS. INAT_SEG_REG_IGNORE is returned if running in long mode. + * + * -EINVAL in case of error. + */ +static int resolve_seg_reg(struct insn *insn, struct pt_regs *regs, int re= goff) +{ + int idx; + + /* + * In the unlikely event of having to resolve the segment register + * index for rIP, do it first. Segment override prefixes should not + * be used. Hence, it is not necessary to inspect the instruction, + * which may be invalid at this point. + */ + if (regoff =3D=3D offsetof(struct pt_regs, ip)) { + if (any_64bit_mode(regs)) + return INAT_SEG_REG_IGNORE; + else + return INAT_SEG_REG_CS; + } + + if (!insn) + return -EINVAL; + + if (!check_seg_overrides(insn, regoff)) + return resolve_default_seg(insn, regs, regoff); + + idx =3D get_seg_reg_override_idx(insn); + if (idx < 0) + return idx; + + if (idx =3D=3D INAT_SEG_REG_DEFAULT) + return resolve_default_seg(insn, regs, regoff); + + /* + * In long mode, segment override prefixes are ignored, except for + * overrides for FS and GS. + */ + if (any_64bit_mode(regs)) { + if (idx !=3D INAT_SEG_REG_FS && + idx !=3D INAT_SEG_REG_GS) + idx =3D INAT_SEG_REG_IGNORE; + } + + return idx; +} + +/** + * get_segment_selector() - obtain segment selector + * @regs: Register values as seen when entering kernel mode + * @seg_reg_idx: Segment register index to use + * + * Obtain the segment selector from any of the CS, SS, DS, ES, FS, GS segm= ent + * registers. In CONFIG_X86_32, the segment is obtained from either pt_reg= s or + * kernel_vm86_regs as applicable. In CONFIG_X86_64, CS and SS are obtained + * from pt_regs. DS, ES, FS and GS are obtained by reading the actual CPU + * registers. This done for only for completeness as in CONFIG_X86_64 segm= ent + * registers are ignored. + * + * Returns: + * + * Value of the segment selector, including null when running in + * long mode. + * + * -EINVAL on error. + */ +static short get_segment_selector(struct pt_regs *regs, int seg_reg_idx) +{ + unsigned short sel; + +#ifdef CONFIG_X86_64 + switch (seg_reg_idx) { + case INAT_SEG_REG_IGNORE: + return 0; + case INAT_SEG_REG_CS: + return (unsigned short)(regs->cs & 0xffff); + case INAT_SEG_REG_SS: + return (unsigned short)(regs->ss & 0xffff); + case INAT_SEG_REG_DS: + savesegment(ds, sel); + return sel; + case INAT_SEG_REG_ES: + savesegment(es, sel); + return sel; + case INAT_SEG_REG_FS: + savesegment(fs, sel); + return sel; + case INAT_SEG_REG_GS: + savesegment(gs, sel); + return sel; + default: + return -EINVAL; + } +#else /* CONFIG_X86_32 */ + struct kernel_vm86_regs *vm86regs =3D (struct kernel_vm86_regs *)regs; + + if (v8086_mode(regs)) { + switch (seg_reg_idx) { + case INAT_SEG_REG_CS: + return (unsigned short)(regs->cs & 0xffff); + case INAT_SEG_REG_SS: + return (unsigned short)(regs->ss & 0xffff); + case INAT_SEG_REG_DS: + return vm86regs->ds; + case INAT_SEG_REG_ES: + return vm86regs->es; + case INAT_SEG_REG_FS: + return vm86regs->fs; + case INAT_SEG_REG_GS: + return vm86regs->gs; + case INAT_SEG_REG_IGNORE: + default: + return -EINVAL; + } + } + + switch (seg_reg_idx) { + case INAT_SEG_REG_CS: + return (unsigned short)(regs->cs & 0xffff); + case INAT_SEG_REG_SS: + return (unsigned short)(regs->ss & 0xffff); + case INAT_SEG_REG_DS: + return (unsigned short)(regs->ds & 0xffff); + case INAT_SEG_REG_ES: + return (unsigned short)(regs->es & 0xffff); + case INAT_SEG_REG_FS: + return (unsigned short)(regs->fs & 0xffff); + case INAT_SEG_REG_GS: + savesegment(gs, sel); + return sel; + case INAT_SEG_REG_IGNORE: + default: + return -EINVAL; + } +#endif /* CONFIG_X86_64 */ +} + +static const int pt_regoff[] =3D { + offsetof(struct pt_regs, ax), + offsetof(struct pt_regs, cx), + offsetof(struct pt_regs, dx), + offsetof(struct pt_regs, bx), + offsetof(struct pt_regs, sp), + offsetof(struct pt_regs, bp), + offsetof(struct pt_regs, si), + offsetof(struct pt_regs, di), +#ifdef CONFIG_X86_64 + offsetof(struct pt_regs, r8), + offsetof(struct pt_regs, r9), + offsetof(struct pt_regs, r10), + offsetof(struct pt_regs, r11), + offsetof(struct pt_regs, r12), + offsetof(struct pt_regs, r13), + offsetof(struct pt_regs, r14), + offsetof(struct pt_regs, r15), +#else + offsetof(struct pt_regs, ds), + offsetof(struct pt_regs, es), + offsetof(struct pt_regs, fs), + offsetof(struct pt_regs, gs), +#endif +}; + +int pt_regs_offset(struct pt_regs *regs, int regno) +{ + if ((unsigned)regno < ARRAY_SIZE(pt_regoff)) + return pt_regoff[regno]; + return -EDOM; +} + +static int get_regno(struct insn *insn, enum reg_type type) +{ + int nr_registers =3D ARRAY_SIZE(pt_regoff); + int regno =3D 0; + + /* + * Don't possibly decode a 32-bit instructions as + * reading a 64-bit-only register. + */ + if (IS_ENABLED(CONFIG_X86_64) && !insn->x86_64) + nr_registers -=3D 8; + + switch (type) { + case REG_TYPE_RM: + regno =3D X86_MODRM_RM(insn->modrm.value); + + /* + * ModRM.mod =3D=3D 0 and ModRM.rm =3D=3D 5 means a 32-bit displacement + * follows the ModRM byte. + */ + if (!X86_MODRM_MOD(insn->modrm.value) && regno =3D=3D 5) + return -EDOM; + + if (X86_REX_B(insn->rex_prefix.value)) + regno +=3D 8; + break; + + case REG_TYPE_REG: + regno =3D X86_MODRM_REG(insn->modrm.value); + + if (X86_REX_R(insn->rex_prefix.value)) + regno +=3D 8; + break; + + case REG_TYPE_INDEX: + regno =3D X86_SIB_INDEX(insn->sib.value); + if (X86_REX_X(insn->rex_prefix.value)) + regno +=3D 8; + + /* + * If ModRM.mod !=3D 3 and SIB.index =3D 4 the scale*index + * portion of the address computation is null. This is + * true only if REX.X is 0. In such a case, the SIB index + * is used in the address computation. + */ + if (X86_MODRM_MOD(insn->modrm.value) !=3D 3 && regno =3D=3D 4) + return -EDOM; + break; + + case REG_TYPE_BASE: + regno =3D X86_SIB_BASE(insn->sib.value); + /* + * If ModRM.mod is 0 and SIB.base =3D=3D 5, the base of the + * register-indirect addressing is 0. In this case, a + * 32-bit displacement follows the SIB byte. + */ + if (!X86_MODRM_MOD(insn->modrm.value) && regno =3D=3D 5) + return -EDOM; + + if (X86_REX_B(insn->rex_prefix.value)) + regno +=3D 8; + break; + + default: + pr_err_ratelimited("invalid register type: %d\n", type); + return -EINVAL; + } + + if (regno >=3D nr_registers) { + WARN_ONCE(1, "decoded an instruction with an invalid register"); + return -EINVAL; + } + return regno; +} + +static int get_reg_offset(struct insn *insn, struct pt_regs *regs, + enum reg_type type) +{ + int regno =3D get_regno(insn, type); + + if (regno < 0) + return regno; + + return pt_regs_offset(regs, regno); +} + +/** + * get_reg_offset_16() - Obtain offset of register indicated by instruction + * @insn: Instruction containing ModRM byte + * @regs: Register values as seen when entering kernel mode + * @offs1: Offset of the first operand register + * @offs2: Offset of the second operand register, if applicable + * + * Obtain the offset, in pt_regs, of the registers indicated by the ModRM = byte + * in @insn. This function is to be used with 16-bit address encodings. The + * @offs1 and @offs2 will be written with the offset of the two registers + * indicated by the instruction. In cases where any of the registers is not + * referenced by the instruction, the value will be set to -EDOM. + * + * Returns: + * + * 0 on success, -EINVAL on error. + */ +static int get_reg_offset_16(struct insn *insn, struct pt_regs *regs, + int *offs1, int *offs2) +{ + /* + * 16-bit addressing can use one or two registers. Specifics of + * encodings are given in Table 2-1. "16-Bit Addressing Forms with the + * ModR/M Byte" of the Intel Software Development Manual. + */ + static const int regoff1[] =3D { + offsetof(struct pt_regs, bx), + offsetof(struct pt_regs, bx), + offsetof(struct pt_regs, bp), + offsetof(struct pt_regs, bp), + offsetof(struct pt_regs, si), + offsetof(struct pt_regs, di), + offsetof(struct pt_regs, bp), + offsetof(struct pt_regs, bx), + }; + + static const int regoff2[] =3D { + offsetof(struct pt_regs, si), + offsetof(struct pt_regs, di), + offsetof(struct pt_regs, si), + offsetof(struct pt_regs, di), + -EDOM, + -EDOM, + -EDOM, + -EDOM, + }; + + if (!offs1 || !offs2) + return -EINVAL; + + /* Operand is a register, use the generic function. */ + if (X86_MODRM_MOD(insn->modrm.value) =3D=3D 3) { + *offs1 =3D insn_get_modrm_rm_off(insn, regs); + *offs2 =3D -EDOM; + return 0; + } + + *offs1 =3D regoff1[X86_MODRM_RM(insn->modrm.value)]; + *offs2 =3D regoff2[X86_MODRM_RM(insn->modrm.value)]; + + /* + * If ModRM.mod is 0 and ModRM.rm is 110b, then we use displacement- + * only addressing. This means that no registers are involved in + * computing the effective address. Thus, ensure that the first + * register offset is invalid. The second register offset is already + * invalid under the aforementioned conditions. + */ + if ((X86_MODRM_MOD(insn->modrm.value) =3D=3D 0) && + (X86_MODRM_RM(insn->modrm.value) =3D=3D 6)) + *offs1 =3D -EDOM; + + return 0; +} + +/** + * get_desc() - Obtain contents of a segment descriptor + * @out: Segment descriptor contents on success + * @sel: Segment selector + * + * Given a segment selector, obtain a pointer to the segment descriptor. + * Both global and local descriptor tables are supported. + * + * Returns: + * + * True on success, false on failure. + * + * NULL on error. + */ +static bool get_desc(struct desc_struct *out, unsigned short sel) +{ + struct desc_ptr gdt_desc =3D {0, 0}; + unsigned long desc_base; + +#ifdef CONFIG_MODIFY_LDT_SYSCALL + if ((sel & SEGMENT_TI_MASK) =3D=3D SEGMENT_LDT) { + bool success =3D false; + struct ldt_struct *ldt; + + /* Bits [15:3] contain the index of the desired entry. */ + sel >>=3D 3; + + /* + * If we're not in a valid context with a real (not just lazy) + * user mm, then don't even try. + */ + if (!nmi_uaccess_okay()) + return false; + + mutex_lock(¤t->mm->context.lock); + ldt =3D current->mm->context.ldt; + if (ldt && sel < ldt->nr_entries) { + *out =3D ldt->entries[sel]; + success =3D true; + } + + mutex_unlock(¤t->mm->context.lock); + + return success; + } +#endif + native_store_gdt(&gdt_desc); + + /* + * Segment descriptors have a size of 8 bytes. Thus, the index is + * multiplied by 8 to obtain the memory offset of the desired descriptor + * from the base of the GDT. As bits [15:3] of the segment selector + * contain the index, it can be regarded as multiplied by 8 already. + * All that remains is to clear bits [2:0]. + */ + desc_base =3D sel & ~(SEGMENT_RPL_MASK | SEGMENT_TI_MASK); + + if (desc_base > gdt_desc.size) + return false; + + *out =3D *(struct desc_struct *)(gdt_desc.address + desc_base); + return true; +} + +/** + * insn_get_seg_base() - Obtain base address of segment descriptor. + * @regs: Register values as seen when entering kernel mode + * @seg_reg_idx: Index of the segment register pointing to seg descriptor + * + * Obtain the base address of the segment as indicated by the segment desc= riptor + * pointed by the segment selector. The segment selector is obtained from = the + * input segment register index @seg_reg_idx. + * + * Returns: + * + * In protected mode, base address of the segment. Zero in long mode, + * except when FS or GS are used. In virtual-8086 mode, the segment + * selector shifted 4 bits to the right. + * + * -1L in case of error. + */ +unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx) +{ + struct desc_struct desc; + short sel; + + sel =3D get_segment_selector(regs, seg_reg_idx); + if (sel < 0) + return -1L; + + if (v8086_mode(regs)) + /* + * Base is simply the segment selector shifted 4 + * bits to the right. + */ + return (unsigned long)(sel << 4); + + if (any_64bit_mode(regs)) { + /* + * Only FS or GS will have a base address, the rest of + * the segments' bases are forced to 0. + */ + unsigned long base; + + if (seg_reg_idx =3D=3D INAT_SEG_REG_FS) { + rdmsrq(MSR_FS_BASE, base); + } else if (seg_reg_idx =3D=3D INAT_SEG_REG_GS) { + /* + * swapgs was called at the kernel entry point. Thus, + * MSR_KERNEL_GS_BASE will have the user-space GS base. + */ + if (user_mode(regs)) + rdmsrq(MSR_KERNEL_GS_BASE, base); + else + rdmsrq(MSR_GS_BASE, base); + } else { + base =3D 0; + } + return base; + } + + /* In protected mode the segment selector cannot be null. */ + if (!sel) + return -1L; + + if (!get_desc(&desc, sel)) + return -1L; + + return get_desc_base(&desc); +} + +/** + * get_seg_limit() - Obtain the limit of a segment descriptor + * @regs: Register values as seen when entering kernel mode + * @seg_reg_idx: Index of the segment register pointing to seg descriptor + * + * Obtain the limit of the segment as indicated by the segment descriptor + * pointed by the segment selector. The segment selector is obtained from = the + * input segment register index @seg_reg_idx. + * + * Returns: + * + * In protected mode, the limit of the segment descriptor in bytes. + * In long mode and virtual-8086 mode, segment limits are not enforced. Th= us, + * limit is returned as -1L to imply a limit-less segment. + * + * Zero is returned on error. + */ +static unsigned long get_seg_limit(struct pt_regs *regs, int seg_reg_idx) +{ + struct desc_struct desc; + unsigned long limit; + short sel; + + sel =3D get_segment_selector(regs, seg_reg_idx); + if (sel < 0) + return 0; + + if (any_64bit_mode(regs) || v8086_mode(regs)) + return -1L; + + if (!sel) + return 0; + + if (!get_desc(&desc, sel)) + return 0; + + /* + * If the granularity bit is set, the limit is given in multiples + * of 4096. This also means that the 12 least significant bits are + * not tested when checking the segment limits. In practice, + * this means that the segment ends in (limit << 12) + 0xfff. + */ + limit =3D get_desc_limit(&desc); + if (desc.g) + limit =3D (limit << 12) + 0xfff; + + return limit; +} + +/** + * insn_get_code_seg_params() - Obtain code segment parameters + * @regs: Structure with register values as seen when entering kernel mode + * + * Obtain address and operand sizes of the code segment. It is obtained fr= om the + * selector contained in the CS register in regs. In protected mode, the d= efault + * address is determined by inspecting the L and D bits of the segment + * descriptor. In virtual-8086 mode, the default is always two bytes for b= oth + * address and operand sizes. + * + * Returns: + * + * An int containing ORed-in default parameters on success. + * + * -EINVAL on error. + */ +int insn_get_code_seg_params(struct pt_regs *regs) +{ + struct desc_struct desc; + short sel; + + if (v8086_mode(regs)) + /* Address and operand size are both 16-bit. */ + return INSN_CODE_SEG_PARAMS(2, 2); + + sel =3D get_segment_selector(regs, INAT_SEG_REG_CS); + if (sel < 0) + return sel; + + if (!get_desc(&desc, sel)) + return -EINVAL; + + /* + * The most significant byte of the Type field of the segment descriptor + * determines whether a segment contains data or code. If this is a data + * segment, return error. + */ + if (!(desc.type & BIT(3))) + return -EINVAL; + + switch ((desc.l << 1) | desc.d) { + case 0: /* + * Legacy mode. CS.L=3D0, CS.D=3D0. Address and operand size are + * both 16-bit. + */ + return INSN_CODE_SEG_PARAMS(2, 2); + case 1: /* + * Legacy mode. CS.L=3D0, CS.D=3D1. Address and operand size are + * both 32-bit. + */ + return INSN_CODE_SEG_PARAMS(4, 4); + case 2: /* + * IA-32e 64-bit mode. CS.L=3D1, CS.D=3D0. Address size is 64-bit; + * operand size is 32-bit. + */ + return INSN_CODE_SEG_PARAMS(4, 8); + case 3: /* Invalid setting. CS.L=3D1, CS.D=3D1 */ + fallthrough; + default: + return -EINVAL; + } +} + +/** + * insn_get_modrm_rm_off() - Obtain register in r/m part of the ModRM byte + * @insn: Instruction containing the ModRM byte + * @regs: Register values as seen when entering kernel mode + * + * Returns: + * + * The register indicated by the r/m part of the ModRM byte. The + * register is obtained as an offset from the base of pt_regs. In specific + * cases, the returned value can be -EDOM to indicate that the particular = value + * of ModRM does not refer to a register and shall be ignored. + */ +int insn_get_modrm_rm_off(struct insn *insn, struct pt_regs *regs) +{ + return get_reg_offset(insn, regs, REG_TYPE_RM); +} + +/** + * insn_get_modrm_reg_off() - Obtain register in reg part of the ModRM byte + * @insn: Instruction containing the ModRM byte + * @regs: Register values as seen when entering kernel mode + * + * Returns: + * + * The register indicated by the reg part of the ModRM byte. The + * register is obtained as an offset from the base of pt_regs. + */ +int insn_get_modrm_reg_off(struct insn *insn, struct pt_regs *regs) +{ + return get_reg_offset(insn, regs, REG_TYPE_REG); +} + +/** + * insn_get_modrm_reg_ptr() - Obtain register pointer based on ModRM byte + * @insn: Instruction containing the ModRM byte + * @regs: Register values as seen when entering kernel mode + * + * Returns: + * + * The register indicated by the reg part of the ModRM byte. + * The register is obtained as a pointer within pt_regs. + */ +unsigned long *insn_get_modrm_reg_ptr(struct insn *insn, struct pt_regs *r= egs) +{ + int offset; + + offset =3D insn_get_modrm_reg_off(insn, regs); + if (offset < 0) + return NULL; + return (void *)regs + offset; +} + +/** + * get_seg_base_limit() - obtain base address and limit of a segment + * @insn: Instruction. Must be valid. + * @regs: Register values as seen when entering kernel mode + * @regoff: Operand offset, in pt_regs, used to resolve segment descriptor + * @base: Obtained segment base + * @limit: Obtained segment limit + * + * Obtain the base address and limit of the segment associated with the op= erand + * @regoff and, if any or allowed, override prefixes in @insn. This functi= on is + * different from insn_get_seg_base() as the latter does not resolve the s= egment + * associated with the instruction operand. If a limit is not needed (e.g., + * when running in long mode), @limit can be NULL. + * + * Returns: + * + * 0 on success. @base and @limit will contain the base address and of the + * resolved segment, respectively. + * + * -EINVAL on error. + */ +static int get_seg_base_limit(struct insn *insn, struct pt_regs *regs, + int regoff, unsigned long *base, + unsigned long *limit) +{ + int seg_reg_idx; + + if (!base) + return -EINVAL; + + seg_reg_idx =3D resolve_seg_reg(insn, regs, regoff); + if (seg_reg_idx < 0) + return seg_reg_idx; + + *base =3D insn_get_seg_base(regs, seg_reg_idx); + if (*base =3D=3D -1L) + return -EINVAL; + + if (!limit) + return 0; + + *limit =3D get_seg_limit(regs, seg_reg_idx); + if (!(*limit)) + return -EINVAL; + + return 0; +} + +/** + * get_eff_addr_reg() - Obtain effective address from register operand + * @insn: Instruction. Must be valid. + * @regs: Register values as seen when entering kernel mode + * @regoff: Obtained operand offset, in pt_regs, with the effective address + * @eff_addr: Obtained effective address + * + * Obtain the effective address stored in the register operand as indicate= d by + * the ModRM byte. This function is to be used only with register addressi= ng + * (i.e., ModRM.mod is 3). The effective address is saved in @eff_addr. T= he + * register operand, as an offset from the base of pt_regs, is saved in @r= egoff; + * such offset can then be used to resolve the segment associated with the + * operand. This function can be used with any of the supported address si= zes + * in x86. + * + * Returns: + * + * 0 on success. @eff_addr will have the effective address stored in the + * operand indicated by ModRM. @regoff will have such operand as an offset= from + * the base of pt_regs. + * + * -EINVAL on error. + */ +static int get_eff_addr_reg(struct insn *insn, struct pt_regs *regs, + int *regoff, long *eff_addr) +{ + int ret; + + ret =3D insn_get_modrm(insn); + if (ret) + return ret; + + if (X86_MODRM_MOD(insn->modrm.value) !=3D 3) + return -EINVAL; + + *regoff =3D get_reg_offset(insn, regs, REG_TYPE_RM); + if (*regoff < 0) + return -EINVAL; + + /* Ignore bytes that are outside the address size. */ + if (insn->addr_bytes =3D=3D 2) + *eff_addr =3D regs_get_register(regs, *regoff) & 0xffff; + else if (insn->addr_bytes =3D=3D 4) + *eff_addr =3D regs_get_register(regs, *regoff) & 0xffffffff; + else /* 64-bit address */ + *eff_addr =3D regs_get_register(regs, *regoff); + + return 0; +} + +/** + * get_eff_addr_modrm() - Obtain referenced effective address via ModRM + * @insn: Instruction. Must be valid. + * @regs: Register values as seen when entering kernel mode + * @regoff: Obtained operand offset, in pt_regs, associated with segment + * @eff_addr: Obtained effective address + * + * Obtain the effective address referenced by the ModRM byte of @insn. Aft= er + * identifying the registers involved in the register-indirect memory refe= rence, + * its value is obtained from the operands in @regs. The computed address = is + * stored @eff_addr. Also, the register operand that indicates the associa= ted + * segment is stored in @regoff, this parameter can later be used to deter= mine + * such segment. + * + * Returns: + * + * 0 on success. @eff_addr will have the referenced effective address. @re= goff + * will have a register, as an offset from the base of pt_regs, that can b= e used + * to resolve the associated segment. + * + * -EINVAL on error. + */ +static int get_eff_addr_modrm(struct insn *insn, struct pt_regs *regs, + int *regoff, long *eff_addr) +{ + long tmp; + int ret; + + if (insn->addr_bytes !=3D 8 && insn->addr_bytes !=3D 4) + return -EINVAL; + + ret =3D insn_get_modrm(insn); + if (ret) + return ret; + + if (X86_MODRM_MOD(insn->modrm.value) > 2) + return -EINVAL; + + *regoff =3D get_reg_offset(insn, regs, REG_TYPE_RM); + + /* + * -EDOM means that we must ignore the address_offset. In such a case, + * in 64-bit mode the effective address relative to the rIP of the + * following instruction. + */ + if (*regoff =3D=3D -EDOM) { + if (any_64bit_mode(regs)) + tmp =3D regs->ip + insn->length; + else + tmp =3D 0; + } else if (*regoff < 0) { + return -EINVAL; + } else { + tmp =3D regs_get_register(regs, *regoff); + } + + if (insn->addr_bytes =3D=3D 4) { + int addr32 =3D (int)(tmp & 0xffffffff) + insn->displacement.value; + + *eff_addr =3D addr32 & 0xffffffff; + } else { + *eff_addr =3D tmp + insn->displacement.value; + } + + return 0; +} + +/** + * get_eff_addr_modrm_16() - Obtain referenced effective address via ModRM + * @insn: Instruction. Must be valid. + * @regs: Register values as seen when entering kernel mode + * @regoff: Obtained operand offset, in pt_regs, associated with segment + * @eff_addr: Obtained effective address + * + * Obtain the 16-bit effective address referenced by the ModRM byte of @in= sn. + * After identifying the registers involved in the register-indirect memory + * reference, its value is obtained from the operands in @regs. The comput= ed + * address is stored @eff_addr. Also, the register operand that indicates + * the associated segment is stored in @regoff, this parameter can later b= e used + * to determine such segment. + * + * Returns: + * + * 0 on success. @eff_addr will have the referenced effective address. @re= goff + * will have a register, as an offset from the base of pt_regs, that can b= e used + * to resolve the associated segment. + * + * -EINVAL on error. + */ +static int get_eff_addr_modrm_16(struct insn *insn, struct pt_regs *regs, + int *regoff, short *eff_addr) +{ + int addr_offset1, addr_offset2, ret; + short addr1 =3D 0, addr2 =3D 0, displacement; + + if (insn->addr_bytes !=3D 2) + return -EINVAL; + + insn_get_modrm(insn); + + if (!insn->modrm.nbytes) + return -EINVAL; + + if (X86_MODRM_MOD(insn->modrm.value) > 2) + return -EINVAL; + + ret =3D get_reg_offset_16(insn, regs, &addr_offset1, &addr_offset2); + if (ret < 0) + return -EINVAL; + + /* + * Don't fail on invalid offset values. They might be invalid because + * they cannot be used for this particular value of ModRM. Instead, use + * them in the computation only if they contain a valid value. + */ + if (addr_offset1 !=3D -EDOM) + addr1 =3D regs_get_register(regs, addr_offset1) & 0xffff; + + if (addr_offset2 !=3D -EDOM) + addr2 =3D regs_get_register(regs, addr_offset2) & 0xffff; + + displacement =3D insn->displacement.value & 0xffff; + *eff_addr =3D addr1 + addr2 + displacement; + + /* + * The first operand register could indicate to use of either SS or DS + * registers to obtain the segment selector. The second operand + * register can only indicate the use of DS. Thus, the first operand + * will be used to obtain the segment selector. + */ + *regoff =3D addr_offset1; + + return 0; +} + +/** + * get_eff_addr_sib() - Obtain referenced effective address via SIB + * @insn: Instruction. Must be valid. + * @regs: Register values as seen when entering kernel mode + * @base_offset: Obtained operand offset, in pt_regs, associated with segm= ent + * @eff_addr: Obtained effective address + * + * Obtain the effective address referenced by the SIB byte of @insn. After + * identifying the registers involved in the indexed, register-indirect me= mory + * reference, its value is obtained from the operands in @regs. The comput= ed + * address is stored @eff_addr. Also, the register operand that indicates = the + * associated segment is stored in @base_offset; this parameter can later = be + * used to determine such segment. + * + * Returns: + * + * 0 on success. @eff_addr will have the referenced effective address. + * @base_offset will have a register, as an offset from the base of pt_reg= s, + * that can be used to resolve the associated segment. + * + * Negative value on error. + */ +static int get_eff_addr_sib(struct insn *insn, struct pt_regs *regs, + int *base_offset, long *eff_addr) +{ + long base, indx; + int indx_offset; + int ret; + + if (insn->addr_bytes !=3D 8 && insn->addr_bytes !=3D 4) + return -EINVAL; + + ret =3D insn_get_modrm(insn); + if (ret) + return ret; + + if (!insn->modrm.nbytes) + return -EINVAL; + + if (X86_MODRM_MOD(insn->modrm.value) > 2) + return -EINVAL; + + ret =3D insn_get_sib(insn); + if (ret) + return ret; + + if (!insn->sib.nbytes) + return -EINVAL; + + *base_offset =3D get_reg_offset(insn, regs, REG_TYPE_BASE); + indx_offset =3D get_reg_offset(insn, regs, REG_TYPE_INDEX); + + /* + * Negative values in the base and index offset means an error when + * decoding the SIB byte. Except -EDOM, which means that the registers + * should not be used in the address computation. + */ + if (*base_offset =3D=3D -EDOM) + base =3D 0; + else if (*base_offset < 0) + return -EINVAL; + else + base =3D regs_get_register(regs, *base_offset); + + if (indx_offset =3D=3D -EDOM) + indx =3D 0; + else if (indx_offset < 0) + return -EINVAL; + else + indx =3D regs_get_register(regs, indx_offset); + + if (insn->addr_bytes =3D=3D 4) { + int addr32, base32, idx32; + + base32 =3D base & 0xffffffff; + idx32 =3D indx & 0xffffffff; + + addr32 =3D base32 + idx32 * (1 << X86_SIB_SCALE(insn->sib.value)); + addr32 +=3D insn->displacement.value; + + *eff_addr =3D addr32 & 0xffffffff; + } else { + *eff_addr =3D base + indx * (1 << X86_SIB_SCALE(insn->sib.value)); + *eff_addr +=3D insn->displacement.value; + } + + return 0; +} + +/** + * get_addr_ref_16() - Obtain the 16-bit address referred by instruction + * @insn: Instruction containing ModRM byte and displacement + * @regs: Register values as seen when entering kernel mode + * + * This function is to be used with 16-bit address encodings. Obtain the m= emory + * address referred by the instruction's ModRM and displacement bytes. Als= o, the + * segment used as base is determined by either any segment override prefi= xes in + * @insn or the default segment of the registers involved in the address + * computation. In protected mode, segment limits are enforced. + * + * Returns: + * + * Linear address referenced by the instruction operands on success. + * + * -1L on error. + */ +static void __user *get_addr_ref_16(struct insn *insn, struct pt_regs *reg= s) +{ + unsigned long linear_addr =3D -1L, seg_base, seg_limit; + int ret, regoff; + short eff_addr; + long tmp; + + if (insn_get_displacement(insn)) + goto out; + + if (insn->addr_bytes !=3D 2) + goto out; + + if (X86_MODRM_MOD(insn->modrm.value) =3D=3D 3) { + ret =3D get_eff_addr_reg(insn, regs, ®off, &tmp); + if (ret) + goto out; + + eff_addr =3D tmp; + } else { + ret =3D get_eff_addr_modrm_16(insn, regs, ®off, &eff_addr); + if (ret) + goto out; + } + + ret =3D get_seg_base_limit(insn, regs, regoff, &seg_base, &seg_limit); + if (ret) + goto out; + + /* + * Before computing the linear address, make sure the effective address + * is within the limits of the segment. In virtual-8086 mode, segment + * limits are not enforced. In such a case, the segment limit is -1L to + * reflect this fact. + */ + if ((unsigned long)(eff_addr & 0xffff) > seg_limit) + goto out; + + linear_addr =3D (unsigned long)(eff_addr & 0xffff) + seg_base; + + /* Limit linear address to 20 bits */ + if (v8086_mode(regs)) + linear_addr &=3D 0xfffff; + +out: + return (void __user *)linear_addr; +} + +/** + * get_addr_ref_32() - Obtain a 32-bit linear address + * @insn: Instruction with ModRM, SIB bytes and displacement + * @regs: Register values as seen when entering kernel mode + * + * This function is to be used with 32-bit address encodings to obtain the + * linear memory address referred by the instruction's ModRM, SIB, + * displacement bytes and segment base address, as applicable. If in prote= cted + * mode, segment limits are enforced. + * + * Returns: + * + * Linear address referenced by instruction and registers on success. + * + * -1L on error. + */ +static void __user *get_addr_ref_32(struct insn *insn, struct pt_regs *reg= s) +{ + unsigned long linear_addr =3D -1L, seg_base, seg_limit; + int eff_addr, regoff; + long tmp; + int ret; + + if (insn->addr_bytes !=3D 4) + goto out; + + if (X86_MODRM_MOD(insn->modrm.value) =3D=3D 3) { + ret =3D get_eff_addr_reg(insn, regs, ®off, &tmp); + if (ret) + goto out; + + eff_addr =3D tmp; + + } else { + if (insn->sib.nbytes) { + ret =3D get_eff_addr_sib(insn, regs, ®off, &tmp); + if (ret) + goto out; + + eff_addr =3D tmp; + } else { + ret =3D get_eff_addr_modrm(insn, regs, ®off, &tmp); + if (ret) + goto out; + + eff_addr =3D tmp; + } + } + + ret =3D get_seg_base_limit(insn, regs, regoff, &seg_base, &seg_limit); + if (ret) + goto out; + + /* + * In protected mode, before computing the linear address, make sure + * the effective address is within the limits of the segment. + * 32-bit addresses can be used in long and virtual-8086 modes if an + * address override prefix is used. In such cases, segment limits are + * not enforced. When in virtual-8086 mode, the segment limit is -1L + * to reflect this situation. + * + * After computed, the effective address is treated as an unsigned + * quantity. + */ + if (!any_64bit_mode(regs) && ((unsigned int)eff_addr > seg_limit)) + goto out; + + /* + * Even though 32-bit address encodings are allowed in virtual-8086 + * mode, the address range is still limited to [0x-0xffff]. + */ + if (v8086_mode(regs) && (eff_addr & ~0xffff)) + goto out; + + /* + * Data type long could be 64 bits in size. Ensure that our 32-bit + * effective address is not sign-extended when computing the linear + * address. + */ + linear_addr =3D (unsigned long)(eff_addr & 0xffffffff) + seg_base; + + /* Limit linear address to 20 bits */ + if (v8086_mode(regs)) + linear_addr &=3D 0xfffff; + +out: + return (void __user *)linear_addr; +} + +/** + * get_addr_ref_64() - Obtain a 64-bit linear address + * @insn: Instruction struct with ModRM and SIB bytes and displacement + * @regs: Structure with register values as seen when entering kernel mode + * + * This function is to be used with 64-bit address encodings to obtain the + * linear memory address referred by the instruction's ModRM, SIB, + * displacement bytes and segment base address, as applicable. + * + * Returns: + * + * Linear address referenced by instruction and registers on success. + * + * -1L on error. + */ +#ifndef CONFIG_X86_64 +static void __user *get_addr_ref_64(struct insn *insn, struct pt_regs *reg= s) +{ + return (void __user *)-1L; +} +#else +static void __user *get_addr_ref_64(struct insn *insn, struct pt_regs *reg= s) +{ + unsigned long linear_addr =3D -1L, seg_base; + int regoff, ret; + long eff_addr; + + if (insn->addr_bytes !=3D 8) + goto out; + + if (X86_MODRM_MOD(insn->modrm.value) =3D=3D 3) { + ret =3D get_eff_addr_reg(insn, regs, ®off, &eff_addr); + if (ret) + goto out; + + } else { + if (insn->sib.nbytes) { + ret =3D get_eff_addr_sib(insn, regs, ®off, &eff_addr); + if (ret) + goto out; + } else { + ret =3D get_eff_addr_modrm(insn, regs, ®off, &eff_addr); + if (ret) + goto out; + } + + } + + ret =3D get_seg_base_limit(insn, regs, regoff, &seg_base, NULL); + if (ret) + goto out; + + linear_addr =3D (unsigned long)eff_addr + seg_base; + +out: + return (void __user *)linear_addr; +} +#endif /* CONFIG_X86_64 */ + +/** + * insn_get_addr_ref() - Obtain the linear address referred by instruction + * @insn: Instruction structure containing ModRM byte and displacement + * @regs: Structure with register values as seen when entering kernel mode + * + * Obtain the linear address referred by the instruction's ModRM, SIB and + * displacement bytes, and segment base, as applicable. In protected mode, + * segment limits are enforced. + * + * Returns: + * + * Linear address referenced by instruction and registers on success. + * + * -1L on error. + */ +void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs) +{ + if (!insn || !regs) + return (void __user *)-1L; + + if (insn_get_opcode(insn)) + return (void __user *)-1L; + + switch (insn->addr_bytes) { + case 2: + return get_addr_ref_16(insn, regs); + case 4: + return get_addr_ref_32(insn, regs); + case 8: + return get_addr_ref_64(insn, regs); + default: + return (void __user *)-1L; + } +} + +int insn_get_effective_ip(struct pt_regs *regs, unsigned long *ip) +{ + unsigned long seg_base =3D 0; + + /* + * If not in user-space long mode, a custom code segment could be in + * use. This is true in protected mode (if the process defined a local + * descriptor table), or virtual-8086 mode. In most of the cases + * seg_base will be zero as in USER_CS. + */ + if (!user_64bit_mode(regs)) { + seg_base =3D insn_get_seg_base(regs, INAT_SEG_REG_CS); + if (seg_base =3D=3D -1L) + return -EINVAL; + } + + *ip =3D seg_base + regs->ip; + + return 0; +} + +/** + * insn_fetch_from_user() - Copy instruction bytes from user-space memory + * @regs: Structure with register values as seen when entering kernel mode + * @buf: Array to store the fetched instruction + * + * Gets the linear address of the instruction and copies the instruction b= ytes + * to the buf. + * + * Returns: + * + * - number of instruction bytes copied. + * - 0 if nothing was copied. + * - -EINVAL if the linear address of the instruction could not be calcula= ted + */ +int insn_fetch_from_user(struct pt_regs *regs, unsigned char buf[MAX_INSN_= SIZE]) +{ + unsigned long ip; + int not_copied; + + if (insn_get_effective_ip(regs, &ip)) + return -EINVAL; + + not_copied =3D copy_from_user(buf, (void __user *)ip, MAX_INSN_SIZE); + + return MAX_INSN_SIZE - not_copied; +} + +/** + * insn_fetch_from_user_inatomic() - Copy instruction bytes from user-spac= e memory + * while in atomic code + * @regs: Structure with register values as seen when entering kernel mode + * @buf: Array to store the fetched instruction + * + * Gets the linear address of the instruction and copies the instruction b= ytes + * to the buf. This function must be used in atomic context. + * + * Returns: + * + * - number of instruction bytes copied. + * - 0 if nothing was copied. + * - -EINVAL if the linear address of the instruction could not be calcul= ated. + */ +int insn_fetch_from_user_inatomic(struct pt_regs *regs, unsigned char buf[= MAX_INSN_SIZE]) +{ + unsigned long ip; + int not_copied; + + if (insn_get_effective_ip(regs, &ip)) + return -EINVAL; + + not_copied =3D __copy_from_user_inatomic(buf, (void __user *)ip, MAX_INSN= _SIZE); + + return MAX_INSN_SIZE - not_copied; +} + +/** + * insn_decode_from_regs() - Decode an instruction + * @insn: Structure to store decoded instruction + * @regs: Structure with register values as seen when entering kernel mode + * @buf: Buffer containing the instruction bytes + * @buf_size: Number of instruction bytes available in buf + * + * Decodes the instruction provided in buf and stores the decoding results= in + * insn. Also determines the correct address and operand sizes. + * + * Returns: + * + * True if instruction was decoded, False otherwise. + */ +bool insn_decode_from_regs(struct insn *insn, struct pt_regs *regs, + unsigned char buf[MAX_INSN_SIZE], int buf_size) +{ + int seg_defs; + + insn_init(insn, buf, buf_size, user_64bit_mode(regs)); + + /* + * Override the default operand and address sizes with what is specified + * in the code segment descriptor. The instruction decoder only sets + * the address size it to either 4 or 8 address bytes and does nothing + * for the operand bytes. This OK for most of the cases, but we could + * have special cases where, for instance, a 16-bit code segment + * descriptor is used. + * If there is an address override prefix, the instruction decoder + * correctly updates these values, even for 16-bit defaults. + */ + seg_defs =3D insn_get_code_seg_params(regs); + if (seg_defs =3D=3D -EINVAL) + return false; + + insn->addr_bytes =3D INSN_CODE_SEG_ADDR_SZ(seg_defs); + insn->opnd_bytes =3D INSN_CODE_SEG_OPND_SZ(seg_defs); + + if (insn_get_length(insn)) + return false; + + if (buf_size < insn->length) + return false; + + return true; +} + +/** + * insn_decode_mmio() - Decode a MMIO instruction + * @insn: Structure to store decoded instruction + * @bytes: Returns size of memory operand + * + * Decodes instruction that used for Memory-mapped I/O. + * + * Returns: + * + * Type of the instruction. Size of the memory operand is stored in + * @bytes. If decode failed, INSN_MMIO_DECODE_FAILED returned. + */ +enum insn_mmio_type insn_decode_mmio(struct insn *insn, int *bytes) +{ + enum insn_mmio_type type =3D INSN_MMIO_DECODE_FAILED; + + *bytes =3D 0; + + if (insn_get_opcode(insn)) + return INSN_MMIO_DECODE_FAILED; + + switch (insn->opcode.bytes[0]) { + case 0x88: /* MOV m8,r8 */ + *bytes =3D 1; + fallthrough; + case 0x89: /* MOV m16/m32/m64, r16/m32/m64 */ + if (!*bytes) + *bytes =3D insn->opnd_bytes; + type =3D INSN_MMIO_WRITE; + break; + + case 0xc6: /* MOV m8, imm8 */ + *bytes =3D 1; + fallthrough; + case 0xc7: /* MOV m16/m32/m64, imm16/imm32/imm64 */ + if (!*bytes) + *bytes =3D insn->opnd_bytes; + type =3D INSN_MMIO_WRITE_IMM; + break; + + case 0x8a: /* MOV r8, m8 */ + *bytes =3D 1; + fallthrough; + case 0x8b: /* MOV r16/r32/r64, m16/m32/m64 */ + if (!*bytes) + *bytes =3D insn->opnd_bytes; + type =3D INSN_MMIO_READ; + break; + + case 0xa4: /* MOVS m8, m8 */ + *bytes =3D 1; + fallthrough; + case 0xa5: /* MOVS m16/m32/m64, m16/m32/m64 */ + if (!*bytes) + *bytes =3D insn->opnd_bytes; + type =3D INSN_MMIO_MOVS; + break; + + case 0x0f: /* Two-byte instruction */ + switch (insn->opcode.bytes[1]) { + case 0xb6: /* MOVZX r16/r32/r64, m8 */ + *bytes =3D 1; + fallthrough; + case 0xb7: /* MOVZX r32/r64, m16 */ + if (!*bytes) + *bytes =3D 2; + type =3D INSN_MMIO_READ_ZERO_EXTEND; + break; + + case 0xbe: /* MOVSX r16/r32/r64, m8 */ + *bytes =3D 1; + fallthrough; + case 0xbf: /* MOVSX r32/r64, m16 */ + if (!*bytes) + *bytes =3D 2; + type =3D INSN_MMIO_READ_SIGN_EXTEND; + break; + } + break; + } + + return type; +} --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from CO1PR03CU002.outbound.protection.outlook.com (mail-westus2azon11010046.outbound.protection.outlook.com [52.101.46.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B2E0830F538; Tue, 23 Sep 2025 05:13:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.46.46 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604433; cv=fail; b=bSfJ98PGlDZndwAkQ5kHVZCbCybS4/1hIG9NyKailZV18jGa+dywavKann7bS8KnsjNVP8cRw4PPROtONhcgwuK0v2juzDZK1v/hRWecjT0ayvn4/CwQcWwJAJHazGco/WuP/iXFVNuywzczWn0a5mDDZ7u+ToW5ThHPy+65GMg= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604433; c=relaxed/simple; bh=p8hgBTfoDfrkmfwESqPAax/RVXCd5v7ddkeb/yAgBQQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=j/jtogoB3gnzeARW4Y465q5mAOC7yV8/nm2qronXxpOeSLoXj+kKRHVz01mTjUQL6SAQN3f6E5+TWI8GMbYgu1bdyZ1FS6E8KwRDRdFxRo0FJ8WjZRgoUD9RTABdMGFxdKsCrBgMg5++BNgg9OpGzNsbDhuXoOgfP+2K5BsrUX4= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=gzl5I6PU; arc=fail smtp.client-ip=52.101.46.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="gzl5I6PU" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=XN5RoZwQ0U5l5o5whdIWe8VMmiCmFDkVAkQZ0U85isGGPhHq/2pMLWPnWFZvR4mDWmujBWLO8kzWRWVXgQLE/sPmjXjdLd9q01WqUU4ltxf/8sHRZ3CGpwCx8MzWNoK0sI509xPLEtF9X3O0c8TIX8G50be7VmlCI6gHBKJL+2kBwXlSv2FQ6shiNWa3Ih9FuBajhU7eeQx3eRf8QW+/00DwJoaABz4roCW8BCqe1R/pRLIOcEP+Yw3HG0luYg2FV1yJOoA7xKmVFbf81jHK4qA5k65B6RR3+t96mTiAen5sBFKbuiB0mjeu10IsHlYg8STSTVqrIWz/ZgPklg7ZiA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=zd4saNNzqUcd8EcyjlWa8wF+1gEk/Y7CgGq/tuJNvXM=; b=IbUQPeoQOn2tlsvMTK+7UpFcg8/fylOgQgfAFe+zehH8l+H9Kei7XcBe1zxMq3faxduDzFivmhYxqBMY6W+HFV+2MqGVahexhOJvcguOIVEbIrjpPsu40CZUV+pdq16V7FcauDD+SHNBtiha6yOUWkz2mlBF/vNdT7wI4XU2qvvbEslfo1pQrG5vbjIiqhxc5s9oEf+CGDT9hrZyuNdwFE2JtcoveoRTWXmUWr1/mVCMDXZV3jdQqsVSV3SNZu3W8ABCHNw4lR893UvQ+cK2uW0PMDcbyRDHE4P7jDhtOXGq5StgdHtPqx4opG1z66OH+QLxDeyN8mA9dvKE6t9nXg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=zd4saNNzqUcd8EcyjlWa8wF+1gEk/Y7CgGq/tuJNvXM=; b=gzl5I6PUXCqWFqtsc5gwWKKMIQQK/3APl84vxsL9DE+u6vOapoSTVIh1dFbxnBLxZ6+EebIYNtgfhQolqtNM7YnBz5Ol9lXAOPFZ+s5GdGg/ITb6BS4PPJ63/oAQxmebNIzd2B7Aroc+Vwh8FvvHVvBlAp23goOvMogBm5Naqvw= Received: from CH2PR07CA0059.namprd07.prod.outlook.com (2603:10b6:610:5b::33) by DS0PR12MB8042.namprd12.prod.outlook.com (2603:10b6:8:141::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.19; Tue, 23 Sep 2025 05:13:46 +0000 Received: from CH2PEPF0000013C.namprd02.prod.outlook.com (2603:10b6:610:5b:cafe::df) by CH2PR07CA0059.outlook.office365.com (2603:10b6:610:5b::33) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.19 via Frontend Transport; Tue, 23 Sep 2025 05:13:46 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF0000013C.mail.protection.outlook.com (10.167.244.73) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:13:46 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:13:41 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 13/35] KVM: selftests: Adapt instruction decoder library for userspace Date: Tue, 23 Sep 2025 10:39:20 +0530 Message-ID: <20250923050942.206116-14-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF0000013C:EE_|DS0PR12MB8042:EE_ X-MS-Office365-Filtering-Correlation-Id: 56bef6c2-f2c6-4b9a-5f15-08ddfa5ff945 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|376014|36860700013|82310400026; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?SKnlOPcF/0r6/3Q/evNDbP1NEFFj8QmcvklvfXk+yasnfSK8iTS8pK7lHnrV?= =?us-ascii?Q?2LD7Qxtfr6RBOUiJMOi+FpeoVzw26OvrfO1WBhAXzHmQBtyuGoGkR6aDuUx0?= =?us-ascii?Q?miJJB9SmsU81pndv0Ga9f+iXjzWRiRlENETQUw+8LX+c5fsIXyFRLurOpJ4U?= =?us-ascii?Q?aLOxZBrWegdAyzNbFFoKPwCCUJoKnpttGdA7CDKtmilqfRJe5WU8jZbJ6C+Z?= =?us-ascii?Q?CzwevbWxOpNhSC0daH07Mgt5MCsSC2R5GaMUOI+Atovj5RCY9PeYGWkgw/ls?= =?us-ascii?Q?8N9Z/2x5biRjQiwwwyTnPTe2th6w90g3kUxHeO7v+mbYqw1+gey0fC8BDPSM?= =?us-ascii?Q?sRt2Fj1xtrZLrODerFiwXmrEQPRtNqVfmzhJhOUqbI1caJP+qrYl66IJOrB0?= =?us-ascii?Q?vTcxdGms2684eahv4cXq6HDywuHZsx1A/O2ZD6mUU9Vd5pL8XopEIzgV+P+B?= =?us-ascii?Q?kUxnDGMGPNOTEINi8cP6tIh9NFhDZ7InoWsXHpy6ZJnLIssxnVZBWxPZg18d?= =?us-ascii?Q?z/rlZ1dPipBmQoBhJDBzQ3PMHHK4rZlASSKr1sXyyyIX6e1kY0yfWuXoJR6q?= =?us-ascii?Q?W77eOXrIqxOtaCbAtC5hAvbmKP1dTWQSp0Sc+bnhSjAB/4asJUXtjnL9dl+/?= =?us-ascii?Q?K9Bnq5uHSvsNB0rBqvTUP0Fp5NGxdKbp/EkkeMqTV//YYWMFrno/9fzjV9fA?= =?us-ascii?Q?Z5XrQzCOsK0gLsFLbDHV6pAO8qhCCT/81u6qiOxR3ePRRz5admdaWsLYtB2U?= =?us-ascii?Q?8Vt+rHgaOn/nKR+hK21EDtqtyUvew/fLg95/67ZPZyk5qvvAyfLrZLL50eOd?= =?us-ascii?Q?hD8xZO6HFZ4+MFhXUOmTZoyBBh+6bd975OB2wxsDOCLbeIj4qTxxmfVHEvrk?= =?us-ascii?Q?lZP8w1Otzh5R5n+NmBczWzsj21hdeevnfRkvFp9hsvdmTdv3mx717vt7gXuN?= =?us-ascii?Q?TZJXj646wut9SNXKh4x44zK+Ezxf8feypdYviJYcFnvN1MFc3UVwawq8Esst?= =?us-ascii?Q?bOm6j9sI7tFIG31I+ydQnfiyah2FCQraTlsnKNEEGrZA2nf87bswJYc7aFhm?= =?us-ascii?Q?JvjC4oHm01eqViZe0CojX1PksSZ+bQL5zLPXSZxgwaV0xa77Dp0ijKOacZnh?= =?us-ascii?Q?Nai0np2uDBTGXc3qcHLJ2ucEM+msIlygAbIawawQymLJVGmomGMq72cTQrYl?= =?us-ascii?Q?c8pP2Q901owKeZdKQKuBRKMFUd1n4cQrqz4wvyY4HOrNqnIhvzw3Wr6HmQkA?= =?us-ascii?Q?k7HkdkdHZo/woCFJD/CPGDQ/PhPwBTHyfkUf+f0ahSaLU3TVeV3Hj4k1U0SN?= =?us-ascii?Q?pa7hRNVOcHlafOVkTPUZpjXsBuDr4imurteaY0tKJTiXFfRqG563QvWdvZNC?= =?us-ascii?Q?6mnpPhRRTaZnU/HE4y7oT+kFCo8o8P1IRxwC1TsrPZKtadGNdYLxW/pNDeS8?= =?us-ascii?Q?IPcW929oOgSVLH5MmJTiqG+wZ+/3U4gq9MAF1WHu4M6SwpX/NIBT6UxkvsU9?= =?us-ascii?Q?CTVRhtny6Se8zq/EXmUocqh2s2ynzC1ZkZwe?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(376014)(36860700013)(82310400026);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:13:46.6852 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 56bef6c2-f2c6-4b9a-5f15-08ddfa5ff945 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF0000013C.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS0PR12MB8042 Content-Type: text/plain; charset="utf-8" The insn-eval.c library, recently added for SEV-ES #VC emulation, is from arch/x86/lib/ and contains dependencies on kernel-specific headers and macros (e.g., , pr_err_ratelimited). These dependencies prevent it from being compiled directly within the userspace selftest framework. Adapt the library to be buildable in a userspace environment for selftests: - Replace kernel headers with standard C library and selftest-specific headers. - Translate a kernel-level warning or error into a selftest failure. - Remove kernel-specfic annotations. Signed-off-by: Neeraj Upadhyay --- .../selftests/kvm/include/x86/insn-eval.h | 5 +--- .../testing/selftests/kvm/lib/x86/insn-eval.c | 30 +++++++------------ 2 files changed, 12 insertions(+), 23 deletions(-) diff --git a/tools/testing/selftests/kvm/include/x86/insn-eval.h b/tools/te= sting/selftests/kvm/include/x86/insn-eval.h index 54368a43abf6..68d49199f991 100644 --- a/tools/testing/selftests/kvm/include/x86/insn-eval.h +++ b/tools/testing/selftests/kvm/include/x86/insn-eval.h @@ -6,10 +6,7 @@ * of the registers indicated by operands. */ =20 -#include -#include -#include -#include +#include =20 #define INSN_CODE_SEG_ADDR_SZ(params) ((params >> 4) & 0xf) #define INSN_CODE_SEG_OPND_SZ(params) (params & 0xf) diff --git a/tools/testing/selftests/kvm/lib/x86/insn-eval.c b/tools/testin= g/selftests/kvm/lib/x86/insn-eval.c index 4e385cbfd444..a47c01977e72 100644 --- a/tools/testing/selftests/kvm/lib/x86/insn-eval.c +++ b/tools/testing/selftests/kvm/lib/x86/insn-eval.c @@ -3,18 +3,17 @@ * * Copyright (C) Intel Corporation 2017 */ -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include + #include #include -#include -#include -#include -#include + +#include "insn-eval.h" +#include "kselftest.h" +#include "ucall_common.h" =20 #undef pr_fmt #define pr_fmt(fmt) "insn: " fmt @@ -509,12 +508,12 @@ static int get_regno(struct insn *insn, enum reg_type= type) break; =20 default: - pr_err_ratelimited("invalid register type: %d\n", type); + __GUEST_ASSERT(false, "invalid register type: %d\n", type); return -EINVAL; } =20 if (regno >=3D nr_registers) { - WARN_ONCE(1, "decoded an instruction with an invalid register"); + __GUEST_ASSERT(false, "decoded an instruction with an invalid register"); return -EINVAL; } return regno; @@ -842,7 +841,6 @@ int insn_get_code_seg_params(struct pt_regs *regs) */ return INSN_CODE_SEG_PARAMS(4, 8); case 3: /* Invalid setting. CS.L=3D1, CS.D=3D1 */ - fallthrough; default: return -EINVAL; } @@ -1617,7 +1615,6 @@ enum insn_mmio_type insn_decode_mmio(struct insn *ins= n, int *bytes) switch (insn->opcode.bytes[0]) { case 0x88: /* MOV m8,r8 */ *bytes =3D 1; - fallthrough; case 0x89: /* MOV m16/m32/m64, r16/m32/m64 */ if (!*bytes) *bytes =3D insn->opnd_bytes; @@ -1626,7 +1623,6 @@ enum insn_mmio_type insn_decode_mmio(struct insn *ins= n, int *bytes) =20 case 0xc6: /* MOV m8, imm8 */ *bytes =3D 1; - fallthrough; case 0xc7: /* MOV m16/m32/m64, imm16/imm32/imm64 */ if (!*bytes) *bytes =3D insn->opnd_bytes; @@ -1635,7 +1631,6 @@ enum insn_mmio_type insn_decode_mmio(struct insn *ins= n, int *bytes) =20 case 0x8a: /* MOV r8, m8 */ *bytes =3D 1; - fallthrough; case 0x8b: /* MOV r16/r32/r64, m16/m32/m64 */ if (!*bytes) *bytes =3D insn->opnd_bytes; @@ -1644,7 +1639,6 @@ enum insn_mmio_type insn_decode_mmio(struct insn *ins= n, int *bytes) =20 case 0xa4: /* MOVS m8, m8 */ *bytes =3D 1; - fallthrough; case 0xa5: /* MOVS m16/m32/m64, m16/m32/m64 */ if (!*bytes) *bytes =3D insn->opnd_bytes; @@ -1655,7 +1649,6 @@ enum insn_mmio_type insn_decode_mmio(struct insn *ins= n, int *bytes) switch (insn->opcode.bytes[1]) { case 0xb6: /* MOVZX r16/r32/r64, m8 */ *bytes =3D 1; - fallthrough; case 0xb7: /* MOVZX r32/r64, m16 */ if (!*bytes) *bytes =3D 2; @@ -1664,7 +1657,6 @@ enum insn_mmio_type insn_decode_mmio(struct insn *ins= n, int *bytes) =20 case 0xbe: /* MOVSX r16/r32/r64, m8 */ *bytes =3D 1; - fallthrough; case 0xbf: /* MOVSX r32/r64, m16 */ if (!*bytes) *bytes =3D 2; --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from DM5PR21CU001.outbound.protection.outlook.com (mail-centralusazon11011046.outbound.protection.outlook.com [52.101.62.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 08DB330DEA6; Tue, 23 Sep 2025 05:14:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.62.46 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604454; cv=fail; b=XsQXvU/rfIb0DydOlYVlab1Xa5K9I4M0uOGhspWZiwIyPTJuTgOHodssO+UMLIC6C5IMByuUaWxY7zkq0VHKON1+TJyctK+/LedxERa5BSSM6eDAsUQWUI/ccpEP3y41FbpqWCY7EQhsJUvxmVjw2LMFYHsMx9QJHmZ5qgalQxk= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604454; c=relaxed/simple; bh=dYB7OTHtndsE84RqpgEDqzIjhveRSEgOo5u6rscM0po=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=MwR9iW8wRgSwb7/hIUl3C24qFaCtLGTlVFBJn790dLvF1cNjh8GVE6MGFChNaBJRSNQUDjB6zxxTceAYESNEsfOHOUSumpWhcf9TblVs4ugChZYwv6sV6X/wDkOoqYFOtHwQnK77npWz16sGCjhKmWK8AhIJeSJrZSUteoJp8BU= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=z+mdCRme; arc=fail smtp.client-ip=52.101.62.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="z+mdCRme" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=l+6tMgwFqcPjjViox21isy+5AAA0dO/s/+dOMW41sRLXbwVjikt70dKW/jt9qvcTdafiHN+W5fRTBI/qtEI49HJx9OBLmnNx/D56K8kTwh+NY3Z7U0Y3xGOS8zVwQg9d/n8KyA8Dl/1XrqlyEmx3EG0lWeUQzBFSECDLcSbjF0teCp2GzyPoNc6L4mBZApCG2eMuFS+/eoyYEZ1QIf+foUFtjBmD3An5WprbUWXvZNx9LLe8X8hTOS6UaYByfN/kR2QTUva89i0EOfmoemX+KmB9t8f5rcbwxVkDRy6kFgpkVFBAsZdUwICK4TazD049ynMhJ4vJau2hEqMIUgCNTg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=MwtfR0N/72g2u/+A6NqlDhnhhzAfM4oWCwA2QTxOwRk=; b=Krmk1Kpp9HkIC60NKzYxsGCvtF17H441l+GoIxpoXJKogD9WxBwS8x0NkeDtgYF/NDBq82Dac6H4vFtmYssm/HnCmWXi5zxdGD94U9TecdqcVz6M5/+qqRQktP5vdOtO4flVXhjLXsuAqbBzqmOSob4iTxq+/0td+/RyWkjo9L7uAJq67UACV4JpAfJWWslQmRB7BnRKEyNYoaralsgUoQ4GP+ZT263rRtklGs4JDABWwAz2toPG+izSQXu9k/4uJIlMMrdCvZ8hSyNnRPd9BXDYp+cmvnCgeJw2pwNSsdgO+B4hj+bBocKqHPJ+eZC4zul1maJ02+tWzhj8YQDVBA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=MwtfR0N/72g2u/+A6NqlDhnhhzAfM4oWCwA2QTxOwRk=; b=z+mdCRmeH/X54ExIBQjsn4IOS6wsGWvD9rbMNiKrVD6khYaE1O/90soqAzwaD12s86HTx4QYVbu0DC5kLnXd5cuLANW5Mh2OhCynRru4qyrh7Fqebd2Y/aSZRWgLmORgDbX4qWkrGgiEFPVGEOcmuViiWEOv9HbqXgxWx3ShO6k= Received: from CH2PR16CA0022.namprd16.prod.outlook.com (2603:10b6:610:50::32) by BL4PR12MB9505.namprd12.prod.outlook.com (2603:10b6:208:591::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.19; Tue, 23 Sep 2025 05:14:06 +0000 Received: from CH2PEPF0000013B.namprd02.prod.outlook.com (2603:10b6:610:50:cafe::4f) by CH2PR16CA0022.outlook.office365.com (2603:10b6:610:50::32) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:14:06 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF0000013B.mail.protection.outlook.com (10.167.244.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:14:06 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:13:59 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 14/35] KVM: selftests: Restrict instruction decoder to x86_64 only Date: Tue, 23 Sep 2025 10:39:21 +0530 Message-ID: <20250923050942.206116-15-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF0000013B:EE_|BL4PR12MB9505:EE_ X-MS-Office365-Filtering-Correlation-Id: 1720b982-1e1b-481a-53c8-08ddfa600501 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|36860700013|1800799024|376014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?f3rl34KkV0GWNxgFJ/wd17RDebG2ria9uckkBCgnP1JcurLQPchLSRlw6owv?= =?us-ascii?Q?UADfVH6MPF09UuVOFqjcu1sLQGiRAY2bM0JL1lPc+7Ml9d1RLf7JJ/oUuRPP?= =?us-ascii?Q?GyqBGrhZ8zil8q1VUtbUdxz/D7JLdJF5oBd30YmDEEnt5Rl5cWd3CflCQcuj?= =?us-ascii?Q?Me+sj30K3oLpl2fCWdNX8+QpHOe/V2P81hB8I+tJ35b7/PEWyyIddUgkDEPh?= =?us-ascii?Q?wFY1rbf9SvEkHOsKzXZoYkvXjsB0s4i+pdPg2NVorjYRxnOQilPwPu5B8na0?= =?us-ascii?Q?WAODW2lxpzvDQnx4o014Now3iAVhm3+lSvL72YqZH0+AQkEFKHJJlDUCzxWR?= =?us-ascii?Q?mGz6Z/DBtcrHrZmwBIJKSK4b459ZKNa258Z1xsKPg+JMXaBNzDJJenCaPvkh?= =?us-ascii?Q?yHaePUtOXlvOhVm5DSlg7NQtTNwU5iN/pxhU1ybyOVE6tFfZSe3Y4ir5dKdA?= =?us-ascii?Q?oB6Px8WDbsTtFGi6BIyGYWyR4aTRJEkv2EYnqCZQMGXySMbuv8381b+E1PUy?= =?us-ascii?Q?NyBA2aRha/8QYYE3I1JahZyT5Kl9liMDr8ux5WsgRQxm7VTAbJhwS+iK3zj9?= =?us-ascii?Q?d5DXU/aXYuwQZ9wou2Wg72ymaK3LvjJNZ/lsHrT7D4EDK/ugZ0pP0oCumrst?= =?us-ascii?Q?L8koK6zTmcd3L6IFC4GrjXHeHlpEq5sHDH034qeQ1Eppv3GoZfSvkyJOpmM+?= =?us-ascii?Q?YFp9ccmO+XpwhGmgPX6pfDs4zxKTURB41OYWYTDi7gcFzXKItHzshnWFKLGL?= =?us-ascii?Q?biAcB9iNaMrfFlggXz1yq5E7jQe6lE9g96278fcMK+lcMIr1p/5HO4pG2Zh8?= =?us-ascii?Q?/SEvjpJsonRuEzA/sqSp0bI8VXf1yshw6e7QEeIYSz64/+Q+hfPq0uzkBz7v?= =?us-ascii?Q?CCGqMvI9APRpddIZEZOwj1FflCNTHduaR3uA2tU3Kz3PHaU05JhldI0IpKhZ?= =?us-ascii?Q?DtIPUrO3hQi6T+XmnwPqQnULBjbToL5wknX65z15Pvx+JqdUShNXPpD/gjK9?= =?us-ascii?Q?VVPYkV+EMRO+U57/B8N9cNn3/h01h0EKL54xoQMhzFQByiX7ccT/Jt+8+0Iv?= =?us-ascii?Q?6YER1SzsZPk0ZZi/aoyDHhulr4wV56CWtHMgLwJGrBnj6Nvs53S6hhdIUmu0?= =?us-ascii?Q?eE6ZGZYFTbiT1qWyWFi789ifp2eFinVi82a7k/NNbs0iMHyFl5ZaKbkD61Ot?= =?us-ascii?Q?BuHRmUGBeEWDjoymoUzeI+ADzWqJ0Erk1/GfcA3iCpWR+2qN4A6ox3mqPr7U?= =?us-ascii?Q?0H4cIygnkkPJ5NRYO/OJW+XePrx5XpmE0/yRiBGbygi12fdm5iyR8uZ/LuLD?= =?us-ascii?Q?/m+u3b7rbWvTvn6EX8gguVgOSL+mE9FignqcpLoqH6EcSuJWXYxTnNwhPbCm?= =?us-ascii?Q?t5CHy/M3drc1AY8OdY1SxqkVfe41S4C4q9ohuapcjyrnXlB0ERgLTo39LDxB?= =?us-ascii?Q?iNvIb50ZUQruRGn/1th2GLhcMg21cztTdp4FLlZO/DGPQc/TSbYf5z2WYLEH?= =?us-ascii?Q?+8U2xmIHh6p+EW9hFmfHb3CXb5Ltd6IlaQ+O?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(36860700013)(1800799024)(376014);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:14:06.3708 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 1720b982-1e1b-481a-53c8-08ddfa600501 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF0000013B.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BL4PR12MB9505 Content-Type: text/plain; charset="utf-8" The insn-eval.c library was recently imported from the kernel source and contains a significant amount of code to support legacy x86 operating modes, such as 32-bit protected mode, 16-bit addressing, and v8086 mode. The KVM selftests, particularly for features like SEV-ES, exclusively target the 64-bit architecture with guest kernel running in kernel mode. Simplify the decoder by removing all logic not relevant to 64-bit mode. This involves: - Remove all CONFIG_X86_32 and v8086_mode conditional logic. - Simplify resolve_default_seg to always assume 64-bit segmentation rules (i.e., most segments are ignored). - Rework insn_get_seg_base to only handle the 64-bit model where FS/GS bases are read from MSRs. - Delete support for 16-bit address decoding. - Remove complex segment descriptor lookups, which are not used in the 64-bit flat memory model. This makes the library smaller and easier to maintain for its intended purpose within the selftests. Signed-off-by: Neeraj Upadhyay --- .../testing/selftests/kvm/lib/x86/insn-eval.c | 254 ++---------------- 1 file changed, 28 insertions(+), 226 deletions(-) diff --git a/tools/testing/selftests/kvm/lib/x86/insn-eval.c b/tools/testin= g/selftests/kvm/lib/x86/insn-eval.c index a47c01977e72..cf751e4e36ec 100644 --- a/tools/testing/selftests/kvm/lib/x86/insn-eval.c +++ b/tools/testing/selftests/kvm/lib/x86/insn-eval.c @@ -178,52 +178,7 @@ static bool check_seg_overrides(struct insn *insn, int= regoff) */ static int resolve_default_seg(struct insn *insn, struct pt_regs *regs, in= t off) { - if (any_64bit_mode(regs)) - return INAT_SEG_REG_IGNORE; - /* - * Resolve the default segment register as described in Section 3.7.4 - * of the Intel Software Development Manual Vol. 1: - * - * + DS for all references involving r[ABCD]X, and rSI. - * + If used in a string instruction, ES for rDI. Otherwise, DS. - * + AX, CX and DX are not valid register operands in 16-bit address - * encodings but are valid for 32-bit and 64-bit encodings. - * + -EDOM is reserved to identify for cases in which no register - * is used (i.e., displacement-only addressing). Use DS. - * + SS for rSP or rBP. - * + CS for rIP. - */ - - switch (off) { - case offsetof(struct pt_regs, ax): - case offsetof(struct pt_regs, cx): - case offsetof(struct pt_regs, dx): - /* Need insn to verify address size. */ - if (insn->addr_bytes =3D=3D 2) - return -EINVAL; - - fallthrough; - - case -EDOM: - case offsetof(struct pt_regs, bx): - case offsetof(struct pt_regs, si): - return INAT_SEG_REG_DS; - - case offsetof(struct pt_regs, di): - if (is_string_insn(insn)) - return INAT_SEG_REG_ES; - return INAT_SEG_REG_DS; - - case offsetof(struct pt_regs, bp): - case offsetof(struct pt_regs, sp): - return INAT_SEG_REG_SS; - - case offsetof(struct pt_regs, ip): - return INAT_SEG_REG_CS; - - default: - return -EINVAL; - } + return INAT_SEG_REG_IGNORE; } =20 /** @@ -288,12 +243,8 @@ static int resolve_seg_reg(struct insn *insn, struct p= t_regs *regs, int regoff) * be used. Hence, it is not necessary to inspect the instruction, * which may be invalid at this point. */ - if (regoff =3D=3D offsetof(struct pt_regs, ip)) { - if (any_64bit_mode(regs)) - return INAT_SEG_REG_IGNORE; - else - return INAT_SEG_REG_CS; - } + if (regoff =3D=3D offsetof(struct pt_regs, ip)) + return INAT_SEG_REG_IGNORE; =20 if (!insn) return -EINVAL; @@ -312,11 +263,8 @@ static int resolve_seg_reg(struct insn *insn, struct p= t_regs *regs, int regoff) * In long mode, segment override prefixes are ignored, except for * overrides for FS and GS. */ - if (any_64bit_mode(regs)) { - if (idx !=3D INAT_SEG_REG_FS && - idx !=3D INAT_SEG_REG_GS) - idx =3D INAT_SEG_REG_IGNORE; - } + if (idx !=3D INAT_SEG_REG_FS && idx !=3D INAT_SEG_REG_GS) + idx =3D INAT_SEG_REG_IGNORE; =20 return idx; } @@ -327,11 +275,9 @@ static int resolve_seg_reg(struct insn *insn, struct p= t_regs *regs, int regoff) * @seg_reg_idx: Segment register index to use * * Obtain the segment selector from any of the CS, SS, DS, ES, FS, GS segm= ent - * registers. In CONFIG_X86_32, the segment is obtained from either pt_reg= s or - * kernel_vm86_regs as applicable. In CONFIG_X86_64, CS and SS are obtained - * from pt_regs. DS, ES, FS and GS are obtained by reading the actual CPU - * registers. This done for only for completeness as in CONFIG_X86_64 segm= ent - * registers are ignored. + * registers. CS and SS are obtained from pt_regs. DS, ES, FS and GS are + * obtained by reading the actual CPU registers. This done for only for + * completeness as in X86_64 segment registers are ignored. * * Returns: * @@ -344,7 +290,6 @@ static short get_segment_selector(struct pt_regs *regs,= int seg_reg_idx) { unsigned short sel; =20 -#ifdef CONFIG_X86_64 switch (seg_reg_idx) { case INAT_SEG_REG_IGNORE: return 0; @@ -367,48 +312,6 @@ static short get_segment_selector(struct pt_regs *regs= , int seg_reg_idx) default: return -EINVAL; } -#else /* CONFIG_X86_32 */ - struct kernel_vm86_regs *vm86regs =3D (struct kernel_vm86_regs *)regs; - - if (v8086_mode(regs)) { - switch (seg_reg_idx) { - case INAT_SEG_REG_CS: - return (unsigned short)(regs->cs & 0xffff); - case INAT_SEG_REG_SS: - return (unsigned short)(regs->ss & 0xffff); - case INAT_SEG_REG_DS: - return vm86regs->ds; - case INAT_SEG_REG_ES: - return vm86regs->es; - case INAT_SEG_REG_FS: - return vm86regs->fs; - case INAT_SEG_REG_GS: - return vm86regs->gs; - case INAT_SEG_REG_IGNORE: - default: - return -EINVAL; - } - } - - switch (seg_reg_idx) { - case INAT_SEG_REG_CS: - return (unsigned short)(regs->cs & 0xffff); - case INAT_SEG_REG_SS: - return (unsigned short)(regs->ss & 0xffff); - case INAT_SEG_REG_DS: - return (unsigned short)(regs->ds & 0xffff); - case INAT_SEG_REG_ES: - return (unsigned short)(regs->es & 0xffff); - case INAT_SEG_REG_FS: - return (unsigned short)(regs->fs & 0xffff); - case INAT_SEG_REG_GS: - savesegment(gs, sel); - return sel; - case INAT_SEG_REG_IGNORE: - default: - return -EINVAL; - } -#endif /* CONFIG_X86_64 */ } =20 static const int pt_regoff[] =3D { @@ -420,7 +323,6 @@ static const int pt_regoff[] =3D { offsetof(struct pt_regs, bp), offsetof(struct pt_regs, si), offsetof(struct pt_regs, di), -#ifdef CONFIG_X86_64 offsetof(struct pt_regs, r8), offsetof(struct pt_regs, r9), offsetof(struct pt_regs, r10), @@ -429,12 +331,6 @@ static const int pt_regoff[] =3D { offsetof(struct pt_regs, r13), offsetof(struct pt_regs, r14), offsetof(struct pt_regs, r15), -#else - offsetof(struct pt_regs, ds), - offsetof(struct pt_regs, es), - offsetof(struct pt_regs, fs), - offsetof(struct pt_regs, gs), -#endif }; =20 int pt_regs_offset(struct pt_regs *regs, int regno) @@ -453,9 +349,6 @@ static int get_regno(struct insn *insn, enum reg_type t= ype) * Don't possibly decode a 32-bit instructions as * reading a 64-bit-only register. */ - if (IS_ENABLED(CONFIG_X86_64) && !insn->x86_64) - nr_registers -=3D 8; - switch (type) { case REG_TYPE_RM: regno =3D X86_MODRM_RM(insn->modrm.value); @@ -687,52 +580,33 @@ static bool get_desc(struct desc_struct *out, unsigne= d short sel) */ unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx) { - struct desc_struct desc; + unsigned long base; short sel; =20 sel =3D get_segment_selector(regs, seg_reg_idx); if (sel < 0) return -1L; =20 - if (v8086_mode(regs)) - /* - * Base is simply the segment selector shifted 4 - * bits to the right. - */ - return (unsigned long)(sel << 4); + /* + * Only FS or GS will have a base address, the rest of + * the segments' bases are forced to 0. + */ =20 - if (any_64bit_mode(regs)) { + if (seg_reg_idx =3D=3D INAT_SEG_REG_FS) { + rdmsrq(MSR_FS_BASE, base); + } else if (seg_reg_idx =3D=3D INAT_SEG_REG_GS) { /* - * Only FS or GS will have a base address, the rest of - * the segments' bases are forced to 0. + * swapgs was called at the kernel entry point. Thus, + * MSR_KERNEL_GS_BASE will have the user-space GS base. */ - unsigned long base; - - if (seg_reg_idx =3D=3D INAT_SEG_REG_FS) { - rdmsrq(MSR_FS_BASE, base); - } else if (seg_reg_idx =3D=3D INAT_SEG_REG_GS) { - /* - * swapgs was called at the kernel entry point. Thus, - * MSR_KERNEL_GS_BASE will have the user-space GS base. - */ - if (user_mode(regs)) - rdmsrq(MSR_KERNEL_GS_BASE, base); - else - rdmsrq(MSR_GS_BASE, base); - } else { - base =3D 0; - } - return base; + if (user_mode(regs)) + rdmsrq(MSR_KERNEL_GS_BASE, base); + else + rdmsrq(MSR_GS_BASE, base); + } else { + base =3D 0; } - - /* In protected mode the segment selector cannot be null. */ - if (!sel) - return -1L; - - if (!get_desc(&desc, sel)) - return -1L; - - return get_desc_base(&desc); + return base; } =20 /** @@ -762,26 +636,7 @@ static unsigned long get_seg_limit(struct pt_regs *reg= s, int seg_reg_idx) if (sel < 0) return 0; =20 - if (any_64bit_mode(regs) || v8086_mode(regs)) - return -1L; - - if (!sel) - return 0; - - if (!get_desc(&desc, sel)) - return 0; - - /* - * If the granularity bit is set, the limit is given in multiples - * of 4096. This also means that the 12 least significant bits are - * not tested when checking the segment limits. In practice, - * this means that the segment ends in (limit << 12) + 0xfff. - */ - limit =3D get_desc_limit(&desc); - if (desc.g) - limit =3D (limit << 12) + 0xfff; - - return limit; + return -1L; } =20 /** @@ -805,10 +660,6 @@ int insn_get_code_seg_params(struct pt_regs *regs) struct desc_struct desc; short sel; =20 - if (v8086_mode(regs)) - /* Address and operand size are both 16-bit. */ - return INSN_CODE_SEG_PARAMS(2, 2); - sel =3D get_segment_selector(regs, INAT_SEG_REG_CS); if (sel < 0) return sel; @@ -1042,10 +893,7 @@ static int get_eff_addr_modrm(struct insn *insn, stru= ct pt_regs *regs, * following instruction. */ if (*regoff =3D=3D -EDOM) { - if (any_64bit_mode(regs)) - tmp =3D regs->ip + insn->length; - else - tmp =3D 0; + tmp =3D regs->ip + insn->length; } else if (*regoff < 0) { return -EINVAL; } else { @@ -1277,9 +1125,6 @@ static void __user *get_addr_ref_16(struct insn *insn= , struct pt_regs *regs) =20 linear_addr =3D (unsigned long)(eff_addr & 0xffff) + seg_base; =20 - /* Limit linear address to 20 bits */ - if (v8086_mode(regs)) - linear_addr &=3D 0xfffff; =20 out: return (void __user *)linear_addr; @@ -1338,27 +1183,6 @@ static void __user *get_addr_ref_32(struct insn *ins= n, struct pt_regs *regs) if (ret) goto out; =20 - /* - * In protected mode, before computing the linear address, make sure - * the effective address is within the limits of the segment. - * 32-bit addresses can be used in long and virtual-8086 modes if an - * address override prefix is used. In such cases, segment limits are - * not enforced. When in virtual-8086 mode, the segment limit is -1L - * to reflect this situation. - * - * After computed, the effective address is treated as an unsigned - * quantity. - */ - if (!any_64bit_mode(regs) && ((unsigned int)eff_addr > seg_limit)) - goto out; - - /* - * Even though 32-bit address encodings are allowed in virtual-8086 - * mode, the address range is still limited to [0x-0xffff]. - */ - if (v8086_mode(regs) && (eff_addr & ~0xffff)) - goto out; - /* * Data type long could be 64 bits in size. Ensure that our 32-bit * effective address is not sign-extended when computing the linear @@ -1366,9 +1190,6 @@ static void __user *get_addr_ref_32(struct insn *insn= , struct pt_regs *regs) */ linear_addr =3D (unsigned long)(eff_addr & 0xffffffff) + seg_base; =20 - /* Limit linear address to 20 bits */ - if (v8086_mode(regs)) - linear_addr &=3D 0xfffff; =20 out: return (void __user *)linear_addr; @@ -1389,12 +1210,6 @@ static void __user *get_addr_ref_32(struct insn *ins= n, struct pt_regs *regs) * * -1L on error. */ -#ifndef CONFIG_X86_64 -static void __user *get_addr_ref_64(struct insn *insn, struct pt_regs *reg= s) -{ - return (void __user *)-1L; -} -#else static void __user *get_addr_ref_64(struct insn *insn, struct pt_regs *reg= s) { unsigned long linear_addr =3D -1L, seg_base; @@ -1431,7 +1246,6 @@ static void __user *get_addr_ref_64(struct insn *insn= , struct pt_regs *regs) out: return (void __user *)linear_addr; } -#endif /* CONFIG_X86_64 */ =20 /** * insn_get_addr_ref() - Obtain the linear address referred by instruction @@ -1472,18 +1286,6 @@ int insn_get_effective_ip(struct pt_regs *regs, unsi= gned long *ip) { unsigned long seg_base =3D 0; =20 - /* - * If not in user-space long mode, a custom code segment could be in - * use. This is true in protected mode (if the process defined a local - * descriptor table), or virtual-8086 mode. In most of the cases - * seg_base will be zero as in USER_CS. - */ - if (!user_64bit_mode(regs)) { - seg_base =3D insn_get_seg_base(regs, INAT_SEG_REG_CS); - if (seg_base =3D=3D -1L) - return -EINVAL; - } - *ip =3D seg_base + regs->ip; =20 return 0; @@ -1563,7 +1365,7 @@ bool insn_decode_from_regs(struct insn *insn, struct = pt_regs *regs, { int seg_defs; =20 - insn_init(insn, buf, buf_size, user_64bit_mode(regs)); + insn_init(insn, buf, buf_size, true); =20 /* * Override the default operand and address sizes with what is specified --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from CY3PR05CU001.outbound.protection.outlook.com (mail-westcentralusazon11013006.outbound.protection.outlook.com [40.93.201.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 96BB730CDAF; Tue, 23 Sep 2025 05:14:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.201.6 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604469; cv=fail; b=kaYNWhyUmkIU4z65Pd337awZqNAL8r2ujaH4nsF7e362Zqfz87HPp/lisKsYhKzCcTWALfmHZJU4PSnPAt0LH4hcLGbkpwHZkAdm9ynI8oLTfKJ1GGEiwNhsEeSRVDxVZF+1HoBlfTCEUoq3NX7nldUYhzLwtoQB7Fyjsiki+a4= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604469; c=relaxed/simple; bh=OkXjb5H/WvS3pQh17h5aC8N7YiPGNO6vOgjFGuBQoUA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=YVvsASh/2/puNcPS/f5aRwm9J7lzzgMsMlRxuXID80b0Rr6ZMwPYxQ/3qI669RLoBcqReg2gM2L8sRG+3AaPsQtTjediYqPU/qEJnfBo+jUicWBy8dvI5VRzMSzsx3j+9rNY5nOEeA0IWWhnUEKb43KTaJxhxMoEQwP1Gtre1Y4= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=2MjuEjaj; arc=fail smtp.client-ip=40.93.201.6 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="2MjuEjaj" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=TYuf+Il3HdpIFB1dWtueRCSZ7RwWjw+CNhy/FTk0cLzZMGTMv0tS3Tzjp/SE1oCbtwQsoT8MZ0oR0h8kqzJcUvrsh3difJPshXyjLU2W3Hm0zhHTNT6A4Y2gLOjqzw0qqQDNwKVT3itL5z8Kcz2tKrv4Le+vul6fQ03aPl8SUc5umYb4O+HkrxTvCRN/r9GWfJSjiIgA6Ry+QqlKRBn2j/5xTHp/JqC7mFyy9n76QFloAJJIndpSAz/ZtKfy9CogLf+S7ZtKMS73MqHrGCZUDy21ZnxGFQQ4Nq8DTBTdP4ZTBwk/mNlMp1sULE43Ziupl3Zxd7BJBl1SnMYzHKghZA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=X1eCsN1nJcf0JXsIzwAG7fjbPWHVVklu4f8DcQj4uCs=; b=NKKUa6yqF/6LKJRKPJ0MJd02Jil1TNkroLGPac8buJgPIu/l4OW6zVBNp53LEvI2BPcCemDgwCACJjLcWoPTCue8aVXE0Egz/Av6rG4ANbijRBQrbP825dRKpgwTmiCPSXhu0maoss1gUMMVyeqUxbrLHHjsFUleR+N6MrxZBnaW/d/EOVOknmB5ER3uwg7JrIIbjaJWJQAbKylhV60UzwLCnkQ3Vn1LQULUsJBgNpr7q+yljArRYacMze4tfxoHQUJHEJhGA2fgWO7vlcCMVPNeiHCQM29/uZyvSji/OqXsdPKsM4uJHyhmGoJVsxcaptcvf7e0O8F8Q3wx+Ja1Lw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=X1eCsN1nJcf0JXsIzwAG7fjbPWHVVklu4f8DcQj4uCs=; b=2MjuEjajrIul2G+UQnt8QfWpFYQAje3yQAJ9ocRss/v9MBxw3PNieNC4aOQJKjGmKhnFDR7RLzJd+9FKcC8Yn/ZfVQsbn/7NeU6pO6W2tBd8GtKERjUF++KEUdDg/9ls4CYFhX7Fo3Pj5Byjyptm8IGEiuyxDY39+fsuctjZXs0= Received: from CH2PR04CA0021.namprd04.prod.outlook.com (2603:10b6:610:52::31) by DM4PR12MB6423.namprd12.prod.outlook.com (2603:10b6:8:bd::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.20; Tue, 23 Sep 2025 05:14:22 +0000 Received: from CH2PEPF0000013F.namprd02.prod.outlook.com (2603:10b6:610:52:cafe::bb) by CH2PR04CA0021.outlook.office365.com (2603:10b6:610:52::31) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:14:22 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF0000013F.mail.protection.outlook.com (10.167.244.71) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:14:22 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:14:17 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 15/35] KVM: selftests: Remove unneeded functions from instruction decoder Date: Tue, 23 Sep 2025 10:39:22 +0530 Message-ID: <20250923050942.206116-16-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF0000013F:EE_|DM4PR12MB6423:EE_ X-MS-Office365-Filtering-Correlation-Id: fdea0a07-af08-479a-012e-08ddfa600e89 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|1800799024|376014|36860700013; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?idnt3zxLSQTOZSLbu4I3MnUeO7Y7eJLB1CaHMyVMi3jUXeqMa2nzMTadmJ1V?= =?us-ascii?Q?ZAbSpHg3jcwHVn9Ek9xzOrlSgSVIE5PDhW2LVwdR/kQnzinjvhI0gbb01ryJ?= =?us-ascii?Q?Mn7HUQCxzOGxve0O801LH2EmCIYH+tDY0j8BW6aNz0pchHFTLso/4ohxwarp?= =?us-ascii?Q?uAnhyWIiDsO4K2jB3i6yP69HBI8B8hWWdCIwxpH5jIZBHHi/U9aoYi3JFMGc?= =?us-ascii?Q?GIlGPThLCLjZWnIUmL+tNOiecWBtJpvfcdpK8XpwHwRfrlU+ZF8HTqWAUqoo?= =?us-ascii?Q?S/k2Jo9+1b1q+Jd2F1pGg99nuaOs3u9VyOywJXT3hTWneKfxK5oYbf5huMkV?= =?us-ascii?Q?KUozX7xVNJtqwwAJPLknjGIFRACH+/i3tjOgtrHJ0yAVMFCd/WS4yZQZLwUK?= =?us-ascii?Q?eoRa5alDOQRu05b8+srd+CvnUcqlnxXlb2/CZRyAHJjpV88tPNNVfvLX9YR2?= =?us-ascii?Q?7jbZgIYL64nCTvfQL4jld6HZ1iB463EfRkAjxwJPYwi1mEUylBO5BwB+12Pf?= =?us-ascii?Q?Ph7vVl4Wc865cKmmM4jusimr2P7ZlU6FLm2j/2x60BouDzaTXt0lI909SX8a?= =?us-ascii?Q?0YahT84HEKTwC7LcE3N238k/m13gkUX2JNQAMAwEdZHjIkseqgNtEciThTr7?= =?us-ascii?Q?LsgGGLJ1hgvDgckvJiWwPiwbfXyUUCYI7q1/S8JqB+2yw42Gf3teuDhTWx6I?= =?us-ascii?Q?oTE4THgCf2OCamO0p/VdON3vM/UvMhdHEC+p72gnRA6VRxkJq/EV4fnYWVHk?= =?us-ascii?Q?35mh4vAnFWqGZJdRCJOaNSDWZjsSVMw0wBUeDAo21NAc0PfxU9PZIlPB1g88?= =?us-ascii?Q?ziKBi8DwruIrQH0K4qVqiT6/4MyQ7BYtU3mY8xRpnSVNAu1zVPRYu46Ii+T+?= =?us-ascii?Q?8B9Cr3rvHjxqXUTgVgnttTcs7qevIxsgZeHMUR2asEzB1X+jXOcahAiAaCyo?= =?us-ascii?Q?pe6AwOw5G53wziTWP+YlNc3qZFpFx7xKTp00nZwa9LRJIoxvrUGMvUE86NOJ?= =?us-ascii?Q?tGaA1QItPqRDj4vnZrrcPOZTQcpeEIrT5TzTGmTq3nvkOL+1TCPIxGymz5XS?= =?us-ascii?Q?BfGtY+VWCVvgSm94b9bMPls+6TS61K3f66T8nCqUl43QKK5NjJX7nIdsnFLf?= =?us-ascii?Q?J+rM53haZYr9VotpS1ggs5KwHHZsttzcZFFYqKXh1niCLQqrTBR6bbuPfyaB?= =?us-ascii?Q?P1/l6mi9WaRyo2iVBsSG7eg26jfqCSixK5GAf8FHyWSP3ZJ32JA+F1uJLjIp?= =?us-ascii?Q?WtJjK5HlK3z7nAL6VYD6OSt4VixbkLmRfK7C0D3DD3x3BvC7MStfHJia734I?= =?us-ascii?Q?4KQ32x54SAPnC8ZIvpHfqQ/f+418Ov541m5trJ31NKe79bq1tbxcWi/Tg+OG?= =?us-ascii?Q?WsN7YRm+XVnJW5JxeTU7gend5W7XbkjvjPdGCTWAqOhtdRbJ75lmR/DTpv/K?= =?us-ascii?Q?aAc1XOTtSi/OoPOWDFOElNaq8AmKd8b2FNOsqvEyx55MQAoYiz3O20kmJb/S?= =?us-ascii?Q?y7vK5sQxGNA1Dkh/fncMqREiYvg34t7eoLH+?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(1800799024)(376014)(36860700013);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:14:22.3584 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: fdea0a07-af08-479a-012e-08ddfa600e89 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF0000013F.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM4PR12MB6423 Content-Type: text/plain; charset="utf-8" The instruction decoder library was added to support SEV-ES #VC exception handling, where its only required function is to decode MMIO instructions. The library, as imported from the kernel, contains several high-level helper functions that are not needed for this purpose. Remove this unneeded code to strip the library down to the minimum required for its purpose within the selftests, reducing its size and maintenance complexity. While at it, convert the function header comments to not be part of kernel documentation. Signed-off-by: Neeraj Upadhyay --- .../testing/selftests/kvm/lib/x86/insn-eval.c | 297 ++---------------- 1 file changed, 22 insertions(+), 275 deletions(-) diff --git a/tools/testing/selftests/kvm/lib/x86/insn-eval.c b/tools/testin= g/selftests/kvm/lib/x86/insn-eval.c index cf751e4e36ec..bb7845500f3c 100644 --- a/tools/testing/selftests/kvm/lib/x86/insn-eval.c +++ b/tools/testing/selftests/kvm/lib/x86/insn-eval.c @@ -25,7 +25,7 @@ enum reg_type { REG_TYPE_BASE, }; =20 -/** +/* * is_string_insn() - Determine if instruction is a string instruction * @insn: Instruction containing the opcode to inspect * @@ -51,7 +51,7 @@ static bool is_string_insn(struct insn *insn) } } =20 -/** +/* * insn_has_rep_prefix() - Determine if instruction has a REP prefix * @insn: Instruction containing the prefix to inspect * @@ -74,7 +74,7 @@ bool insn_has_rep_prefix(struct insn *insn) return false; } =20 -/** +/* * get_seg_reg_override_idx() - obtain segment register override index * @insn: Valid instruction with segment override prefixes * @@ -137,7 +137,7 @@ static int get_seg_reg_override_idx(struct insn *insn) return idx; } =20 -/** +/* * check_seg_overrides() - check if segment override prefixes are allowed * @insn: Valid instruction with segment override prefixes * @regoff: Operand offset, in pt_regs, for which the check is performed @@ -159,7 +159,7 @@ static bool check_seg_overrides(struct insn *insn, int = regoff) return true; } =20 -/** +/* * resolve_default_seg() - resolve default segment register index for an o= perand * @insn: Instruction with opcode and address size. Must be valid. * @regs: Register values as seen when entering kernel mode @@ -181,7 +181,7 @@ static int resolve_default_seg(struct insn *insn, struc= t pt_regs *regs, int off) return INAT_SEG_REG_IGNORE; } =20 -/** +/* * resolve_seg_reg() - obtain segment register index * @insn: Instruction with operands * @regs: Register values as seen when entering kernel mode @@ -268,8 +268,7 @@ static int resolve_seg_reg(struct insn *insn, struct pt= _regs *regs, int regoff) =20 return idx; } - -/** +/* * get_segment_selector() - obtain segment selector * @regs: Register values as seen when entering kernel mode * @seg_reg_idx: Segment register index to use @@ -423,7 +422,7 @@ static int get_reg_offset(struct insn *insn, struct pt_= regs *regs, return pt_regs_offset(regs, regno); } =20 -/** +/* * get_reg_offset_16() - Obtain offset of register indicated by instruction * @insn: Instruction containing ModRM byte * @regs: Register values as seen when entering kernel mode @@ -497,71 +496,7 @@ static int get_reg_offset_16(struct insn *insn, struct= pt_regs *regs, return 0; } =20 -/** - * get_desc() - Obtain contents of a segment descriptor - * @out: Segment descriptor contents on success - * @sel: Segment selector - * - * Given a segment selector, obtain a pointer to the segment descriptor. - * Both global and local descriptor tables are supported. - * - * Returns: - * - * True on success, false on failure. - * - * NULL on error. - */ -static bool get_desc(struct desc_struct *out, unsigned short sel) -{ - struct desc_ptr gdt_desc =3D {0, 0}; - unsigned long desc_base; - -#ifdef CONFIG_MODIFY_LDT_SYSCALL - if ((sel & SEGMENT_TI_MASK) =3D=3D SEGMENT_LDT) { - bool success =3D false; - struct ldt_struct *ldt; - - /* Bits [15:3] contain the index of the desired entry. */ - sel >>=3D 3; - - /* - * If we're not in a valid context with a real (not just lazy) - * user mm, then don't even try. - */ - if (!nmi_uaccess_okay()) - return false; - - mutex_lock(¤t->mm->context.lock); - ldt =3D current->mm->context.ldt; - if (ldt && sel < ldt->nr_entries) { - *out =3D ldt->entries[sel]; - success =3D true; - } - - mutex_unlock(¤t->mm->context.lock); - - return success; - } -#endif - native_store_gdt(&gdt_desc); - - /* - * Segment descriptors have a size of 8 bytes. Thus, the index is - * multiplied by 8 to obtain the memory offset of the desired descriptor - * from the base of the GDT. As bits [15:3] of the segment selector - * contain the index, it can be regarded as multiplied by 8 already. - * All that remains is to clear bits [2:0]. - */ - desc_base =3D sel & ~(SEGMENT_RPL_MASK | SEGMENT_TI_MASK); - - if (desc_base > gdt_desc.size) - return false; - - *out =3D *(struct desc_struct *)(gdt_desc.address + desc_base); - return true; -} - -/** +/* * insn_get_seg_base() - Obtain base address of segment descriptor. * @regs: Register values as seen when entering kernel mode * @seg_reg_idx: Index of the segment register pointing to seg descriptor @@ -609,7 +544,7 @@ unsigned long insn_get_seg_base(struct pt_regs *regs, i= nt seg_reg_idx) return base; } =20 -/** +/* * get_seg_limit() - Obtain the limit of a segment descriptor * @regs: Register values as seen when entering kernel mode * @seg_reg_idx: Index of the segment register pointing to seg descriptor @@ -628,8 +563,6 @@ unsigned long insn_get_seg_base(struct pt_regs *regs, i= nt seg_reg_idx) */ static unsigned long get_seg_limit(struct pt_regs *regs, int seg_reg_idx) { - struct desc_struct desc; - unsigned long limit; short sel; =20 sel =3D get_segment_selector(regs, seg_reg_idx); @@ -639,82 +572,7 @@ static unsigned long get_seg_limit(struct pt_regs *reg= s, int seg_reg_idx) return -1L; } =20 -/** - * insn_get_code_seg_params() - Obtain code segment parameters - * @regs: Structure with register values as seen when entering kernel mode - * - * Obtain address and operand sizes of the code segment. It is obtained fr= om the - * selector contained in the CS register in regs. In protected mode, the d= efault - * address is determined by inspecting the L and D bits of the segment - * descriptor. In virtual-8086 mode, the default is always two bytes for b= oth - * address and operand sizes. - * - * Returns: - * - * An int containing ORed-in default parameters on success. - * - * -EINVAL on error. - */ -int insn_get_code_seg_params(struct pt_regs *regs) -{ - struct desc_struct desc; - short sel; - - sel =3D get_segment_selector(regs, INAT_SEG_REG_CS); - if (sel < 0) - return sel; - - if (!get_desc(&desc, sel)) - return -EINVAL; - - /* - * The most significant byte of the Type field of the segment descriptor - * determines whether a segment contains data or code. If this is a data - * segment, return error. - */ - if (!(desc.type & BIT(3))) - return -EINVAL; - - switch ((desc.l << 1) | desc.d) { - case 0: /* - * Legacy mode. CS.L=3D0, CS.D=3D0. Address and operand size are - * both 16-bit. - */ - return INSN_CODE_SEG_PARAMS(2, 2); - case 1: /* - * Legacy mode. CS.L=3D0, CS.D=3D1. Address and operand size are - * both 32-bit. - */ - return INSN_CODE_SEG_PARAMS(4, 4); - case 2: /* - * IA-32e 64-bit mode. CS.L=3D1, CS.D=3D0. Address size is 64-bit; - * operand size is 32-bit. - */ - return INSN_CODE_SEG_PARAMS(4, 8); - case 3: /* Invalid setting. CS.L=3D1, CS.D=3D1 */ - default: - return -EINVAL; - } -} - -/** - * insn_get_modrm_rm_off() - Obtain register in r/m part of the ModRM byte - * @insn: Instruction containing the ModRM byte - * @regs: Register values as seen when entering kernel mode - * - * Returns: - * - * The register indicated by the r/m part of the ModRM byte. The - * register is obtained as an offset from the base of pt_regs. In specific - * cases, the returned value can be -EDOM to indicate that the particular = value - * of ModRM does not refer to a register and shall be ignored. - */ -int insn_get_modrm_rm_off(struct insn *insn, struct pt_regs *regs) -{ - return get_reg_offset(insn, regs, REG_TYPE_RM); -} - -/** +/* * insn_get_modrm_reg_off() - Obtain register in reg part of the ModRM byte * @insn: Instruction containing the ModRM byte * @regs: Register values as seen when entering kernel mode @@ -729,7 +587,7 @@ int insn_get_modrm_reg_off(struct insn *insn, struct pt= _regs *regs) return get_reg_offset(insn, regs, REG_TYPE_REG); } =20 -/** +/* * insn_get_modrm_reg_ptr() - Obtain register pointer based on ModRM byte * @insn: Instruction containing the ModRM byte * @regs: Register values as seen when entering kernel mode @@ -749,7 +607,7 @@ unsigned long *insn_get_modrm_reg_ptr(struct insn *insn= , struct pt_regs *regs) return (void *)regs + offset; } =20 -/** +/* * get_seg_base_limit() - obtain base address and limit of a segment * @insn: Instruction. Must be valid. * @regs: Register values as seen when entering kernel mode @@ -797,7 +655,7 @@ static int get_seg_base_limit(struct insn *insn, struct= pt_regs *regs, return 0; } =20 -/** +/* * get_eff_addr_reg() - Obtain effective address from register operand * @insn: Instruction. Must be valid. * @regs: Register values as seen when entering kernel mode @@ -847,7 +705,7 @@ static int get_eff_addr_reg(struct insn *insn, struct p= t_regs *regs, return 0; } =20 -/** +/* * get_eff_addr_modrm() - Obtain referenced effective address via ModRM * @insn: Instruction. Must be valid. * @regs: Register values as seen when entering kernel mode @@ -911,7 +769,7 @@ static int get_eff_addr_modrm(struct insn *insn, struct= pt_regs *regs, return 0; } =20 -/** +/* * get_eff_addr_modrm_16() - Obtain referenced effective address via ModRM * @insn: Instruction. Must be valid. * @regs: Register values as seen when entering kernel mode @@ -979,7 +837,7 @@ static int get_eff_addr_modrm_16(struct insn *insn, str= uct pt_regs *regs, return 0; } =20 -/** +/* * get_eff_addr_sib() - Obtain referenced effective address via SIB * @insn: Instruction. Must be valid. * @regs: Register values as seen when entering kernel mode @@ -1068,7 +926,7 @@ static int get_eff_addr_sib(struct insn *insn, struct = pt_regs *regs, return 0; } =20 -/** +/* * get_addr_ref_16() - Obtain the 16-bit address referred by instruction * @insn: Instruction containing ModRM byte and displacement * @regs: Register values as seen when entering kernel mode @@ -1130,7 +988,7 @@ static void __user *get_addr_ref_16(struct insn *insn,= struct pt_regs *regs) return (void __user *)linear_addr; } =20 -/** +/* * get_addr_ref_32() - Obtain a 32-bit linear address * @insn: Instruction with ModRM, SIB bytes and displacement * @regs: Register values as seen when entering kernel mode @@ -1195,7 +1053,7 @@ static void __user *get_addr_ref_32(struct insn *insn= , struct pt_regs *regs) return (void __user *)linear_addr; } =20 -/** +/* * get_addr_ref_64() - Obtain a 64-bit linear address * @insn: Instruction struct with ModRM and SIB bytes and displacement * @regs: Structure with register values as seen when entering kernel mode @@ -1247,7 +1105,7 @@ static void __user *get_addr_ref_64(struct insn *insn= , struct pt_regs *regs) return (void __user *)linear_addr; } =20 -/** +/* * insn_get_addr_ref() - Obtain the linear address referred by instruction * @insn: Instruction structure containing ModRM byte and displacement * @regs: Structure with register values as seen when entering kernel mode @@ -1282,118 +1140,7 @@ void __user *insn_get_addr_ref(struct insn *insn, s= truct pt_regs *regs) } } =20 -int insn_get_effective_ip(struct pt_regs *regs, unsigned long *ip) -{ - unsigned long seg_base =3D 0; - - *ip =3D seg_base + regs->ip; - - return 0; -} - -/** - * insn_fetch_from_user() - Copy instruction bytes from user-space memory - * @regs: Structure with register values as seen when entering kernel mode - * @buf: Array to store the fetched instruction - * - * Gets the linear address of the instruction and copies the instruction b= ytes - * to the buf. - * - * Returns: - * - * - number of instruction bytes copied. - * - 0 if nothing was copied. - * - -EINVAL if the linear address of the instruction could not be calcula= ted - */ -int insn_fetch_from_user(struct pt_regs *regs, unsigned char buf[MAX_INSN_= SIZE]) -{ - unsigned long ip; - int not_copied; - - if (insn_get_effective_ip(regs, &ip)) - return -EINVAL; - - not_copied =3D copy_from_user(buf, (void __user *)ip, MAX_INSN_SIZE); - - return MAX_INSN_SIZE - not_copied; -} - -/** - * insn_fetch_from_user_inatomic() - Copy instruction bytes from user-spac= e memory - * while in atomic code - * @regs: Structure with register values as seen when entering kernel mode - * @buf: Array to store the fetched instruction - * - * Gets the linear address of the instruction and copies the instruction b= ytes - * to the buf. This function must be used in atomic context. - * - * Returns: - * - * - number of instruction bytes copied. - * - 0 if nothing was copied. - * - -EINVAL if the linear address of the instruction could not be calcul= ated. - */ -int insn_fetch_from_user_inatomic(struct pt_regs *regs, unsigned char buf[= MAX_INSN_SIZE]) -{ - unsigned long ip; - int not_copied; - - if (insn_get_effective_ip(regs, &ip)) - return -EINVAL; - - not_copied =3D __copy_from_user_inatomic(buf, (void __user *)ip, MAX_INSN= _SIZE); - - return MAX_INSN_SIZE - not_copied; -} - -/** - * insn_decode_from_regs() - Decode an instruction - * @insn: Structure to store decoded instruction - * @regs: Structure with register values as seen when entering kernel mode - * @buf: Buffer containing the instruction bytes - * @buf_size: Number of instruction bytes available in buf - * - * Decodes the instruction provided in buf and stores the decoding results= in - * insn. Also determines the correct address and operand sizes. - * - * Returns: - * - * True if instruction was decoded, False otherwise. - */ -bool insn_decode_from_regs(struct insn *insn, struct pt_regs *regs, - unsigned char buf[MAX_INSN_SIZE], int buf_size) -{ - int seg_defs; - - insn_init(insn, buf, buf_size, true); - - /* - * Override the default operand and address sizes with what is specified - * in the code segment descriptor. The instruction decoder only sets - * the address size it to either 4 or 8 address bytes and does nothing - * for the operand bytes. This OK for most of the cases, but we could - * have special cases where, for instance, a 16-bit code segment - * descriptor is used. - * If there is an address override prefix, the instruction decoder - * correctly updates these values, even for 16-bit defaults. - */ - seg_defs =3D insn_get_code_seg_params(regs); - if (seg_defs =3D=3D -EINVAL) - return false; - - insn->addr_bytes =3D INSN_CODE_SEG_ADDR_SZ(seg_defs); - insn->opnd_bytes =3D INSN_CODE_SEG_OPND_SZ(seg_defs); - - if (insn_get_length(insn)) - return false; - - if (buf_size < insn->length) - return false; - - return true; -} - -/** +/* * insn_decode_mmio() - Decode a MMIO instruction * @insn: Structure to store decoded instruction * @bytes: Returns size of memory operand --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from CH5PR02CU005.outbound.protection.outlook.com (mail-northcentralusazon11012017.outbound.protection.outlook.com [40.107.200.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4D01230DED5; Tue, 23 Sep 2025 05:14:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.200.17 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604485; cv=fail; b=MFLsa46STz4GOTiUkgb7ltYGeucbRvbZM8N2aiE4zxO/92bNjS/WHfpPU5gmhQ1H0Ida+Uq/Qu7Zh6VWaAZCtE+Lhza81BMzK/d5ZlRbF6ZqnNdAgoHHm+FN5W2nrVCz762iKW9VoZHHxI6pCcI5tdLJf+9sUKwKNpMU6twojBg= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604485; c=relaxed/simple; bh=EbBnoGfT4A+ZFrqRrHxBh6EnYpSdJwQzA4xUra9+3cU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=DIMjkqkiumlE2rL8wWx/1B3Y0KjzOuJwhTcGXj49ObS3BMjaJX+6QvXg6ol6JFe6I9cHHkwoUQi6n7+BsYXq9akH2UvWaRbLbXzfT77h9QSZwvbwSjCKmJcETLIfAH5xnx/+ZmsgfZ27nCWIag9frUMPvKRwt4qcNX+Jd2whwQk= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=4JCbMrKg; arc=fail smtp.client-ip=40.107.200.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="4JCbMrKg" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=t8lP65gkTyAINo2vGqxWA+IdIhtxzROq6aC5cGpGfeUlUVafJu+i5j0b8vDVYHdL96L+/mNYn4O3KObLEZfdRTMnt5OIdPQgTHFHWXUs2oVNieaEIiaoRlk/Ou+WyCzrHThUIW/kwgWRU5KpBIx2qXbL6rwsXwlZeTL4m5lBepTygmRtrzE6vfR6ZYY6U/WKkM/Azv95Gcjoe1aD59fEGGV8ZAzS5gS59kM3LhSvFVudVnY02Grd8i+AZWO4Ga8bN78P7ib5zzdoSlQ0+jYLfNSKENHqNNTjxjQPRbm1Dn8WwYXJ0X4LA/kUgMFKCBVyYgxhAH5DNXgLlokVCbs8eA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=OqFuot1mkSbkCTrID+FJNynNOrSt8B64kmVv0cYS3cM=; b=VxWtBOZnY1wRpCyTfhrwd9en8LY+fwueIuZtac7Ef5lUBxfNfIWoqLa29mBQVJ5ihnL+MopvSyPn85Rw2wbPEt1TeW6jqm1JnzBpW1Cp+UykiwYjxDSGOsx0pr1n8RUQlqgnFMQUM4tfyUHfwF92c3HITRN9qT/D/LxyfSAUPl3fswiD+ZJG2QMBQxlAKXKCp6hXUjjwXNZZlXuaThfDmJ2oMasjkqgCoQxk90ose1+RzMiIt849BHXBLxZu8HLEuUywiuCjZg6sb7JGyzThRBgiaFxARojceldESyVqzc1jqDnPU5SG+NewliLdADZPoXX6BEyMkigb5sdfg0lKQw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=OqFuot1mkSbkCTrID+FJNynNOrSt8B64kmVv0cYS3cM=; b=4JCbMrKgFAKs4zD3mmlDw7RVJ4IR89vO6Eh9BbRgtFtndcWfCH8ef8dZj+je7U21if9CNQhvJcGVi1RYatOdT2KwKldqnQjJaUcB1YwV86x7IfJVeHaBqlPhj5M9xNOlQfgbPWXtFCbdqpkNn6mR2xX5Fad/P60bd20PCpnk67Q= Received: from CH0PR07CA0021.namprd07.prod.outlook.com (2603:10b6:610:32::26) by SA3PR12MB7781.namprd12.prod.outlook.com (2603:10b6:806:31a::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.19; Tue, 23 Sep 2025 05:14:40 +0000 Received: from CH2PEPF0000013D.namprd02.prod.outlook.com (2603:10b6:610:32:cafe::6f) by CH0PR07CA0021.outlook.office365.com (2603:10b6:610:32::26) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:14:40 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF0000013D.mail.protection.outlook.com (10.167.244.69) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:14:40 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:14:35 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 16/35] KVM: selftests: Fix missing definitions in x86 instruction decoder Date: Tue, 23 Sep 2025 10:39:23 +0530 Message-ID: <20250923050942.206116-17-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF0000013D:EE_|SA3PR12MB7781:EE_ X-MS-Office365-Filtering-Correlation-Id: cb3c1816-ddfd-4eee-97c9-08ddfa601911 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|376014|36860700013|82310400026; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?f1J9J6tSvA6rUxd5ljIqP5OwyTu3fc8hVrp132cKMNpq34znCuvbzsVYiH/Y?= =?us-ascii?Q?xZBNgBlP8EGYJQCWT23JA2mtkjz1z4YY+3FiXjjr/t6AREiV5OeOhbaBSahP?= =?us-ascii?Q?vTklNiNVY5Fx8PCi9LUF0rSWnaBwRr4OOKbB2rTFPT9KnwozA4F8H4JJBFB3?= =?us-ascii?Q?HG2GAmk4UE5mOaMfdykoSHggN6w5s3/xsB3QqrdNbujRrI7ofRobJgynTA9T?= =?us-ascii?Q?JV49Ij0OX76B6acC7vSEmeK33jzPmK11OompZwIAPAbW7IDJfBZ+4N3C5fK1?= =?us-ascii?Q?orOWmENGlww6dagHTQxOHsZQGwUqq96/+VLGYUq6PlobiH14YAo41I1DnGY6?= =?us-ascii?Q?bdrKZnZz8ouW2kev/KHm5BxEDhNtDE9140WL6wQu11m+4IIqfPQyOngH7YwY?= =?us-ascii?Q?Fp61UuaYxl7sSRD/qagA9pShBSaOqHnJBBsz4KM1d61Cj6F+FwwUP8Nw2d7Z?= =?us-ascii?Q?7uefd03n3P3DTKMz9ZNjtrncjnYYFwgjZxTqkIidhs1QU/EHpsTAQ4uEj9lO?= =?us-ascii?Q?vHZhTYNeA2USWDpHNqDiZlrtFo6QXq8GSbPAH0HdL+e24lMwN5d+RqJus4ul?= =?us-ascii?Q?w1XztiR/gCHGk4+jw5TePkYYzaowWcbSoyKHqoH9sI3tsoCyT3O7axp7A0vC?= =?us-ascii?Q?SnS4Ni2QKEpBy77KXNvxM+U0D7KZ9krUfqtQ8d9gLFxdFOi0n7dkoDAdE900?= =?us-ascii?Q?UUjLoA4ls6RHtEEF/GClQ+VpV1lVRxb2PZ5UsSGatUPteRXCJJ8whwVqe3GG?= =?us-ascii?Q?O/zuSYvLhNQ+3XDMhRw2VE7a2dnFNJ9/Km1O+sg1R9I5FA+6SJqntapMAD5i?= =?us-ascii?Q?V58KBODrBBJcWQb6HTR+6P6LRNfY1QmCCnMpUPHGsDjSHydifHJ7D9B5ee4o?= =?us-ascii?Q?z+9iqrm4y8Lpbyi5H5k1wpbYTT4XCz3JrggS94OEW7Enn2wyt3F8nzEMkwZU?= =?us-ascii?Q?q4veOaPrqJatPg8Px4t4jkmn2WjG0H6KDG9u2oSBixrtrKt+jSgZN8SwoLtw?= =?us-ascii?Q?Zljgjqs6b+CNS8Y5Yq2TSliNSifiDP6HujouI/Iw6L95AX/TEfmR+2WYP035?= =?us-ascii?Q?OAd/gHxBhzEFzU30hg22clIWjiJqrgHo0Rwz7hrwm6N+yli0WNnNI7RjMTT2?= =?us-ascii?Q?vEttrzgURsFPlgrobd2ImGDbKunUqo4zL01vwWPZGuTVgEwHkFZ36zZtMccE?= =?us-ascii?Q?choVEL1mF+VcEefbhUFET8uVQ7U7IlvLbc0NsssbAWCKsh3uGh63F5M4ECF2?= =?us-ascii?Q?pJ4ihYU/RLXLwOeZ4n6cxOalsVunfwdxz8mdwx6YQIKl8fSTRHaY1+x1OY6Z?= =?us-ascii?Q?Tkmrj53CYG21gmD/Y57IWTiH3R0wZ40MmpuDwQg6oYwyBOcCVPD3+I/z9lB/?= =?us-ascii?Q?rInsLsKpZtBvXZdXjTX3NmHob/H6MiS6JNeU0QP0yXiE6PDmXfMBD7LN1mQU?= =?us-ascii?Q?I1dBxORLJo3+D33wsOk+KV7UJxLU2/L3LmiCiW53qyM6jl87NArePHGpSffJ?= =?us-ascii?Q?6IdbkSZAWT2fdS6RAlnOUV109BMFF3//MvlR?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(376014)(36860700013)(82310400026);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:14:40.0321 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: cb3c1816-ddfd-4eee-97c9-08ddfa601911 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF0000013D.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA3PR12MB7781 Content-Type: text/plain; charset="utf-8" The insn-eval x86 selftest lib uses kernel-internal macros savesegment and rdmsrq, which are typically defined in kernel headers like and . These headers are not available in the userspace build environment for selftests, leading to build failures. Fix this by providing local definitions for the missing symbols and replacing with the functional equivalent definitions available to the selftest. Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/lib/x86/insn-eval.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/kvm/lib/x86/insn-eval.c b/tools/testin= g/selftests/kvm/lib/x86/insn-eval.c index bb7845500f3c..fb393aaf9f7f 100644 --- a/tools/testing/selftests/kvm/lib/x86/insn-eval.c +++ b/tools/testing/selftests/kvm/lib/x86/insn-eval.c @@ -18,6 +18,9 @@ #undef pr_fmt #define pr_fmt(fmt) "insn: " fmt =20 +#define savesegment(seg, value) \ + asm("mov %%" #seg ",%0":"=3Dr" (value) : : "memory") + enum reg_type { REG_TYPE_RM =3D 0, REG_TYPE_REG, @@ -25,6 +28,11 @@ enum reg_type { REG_TYPE_BASE, }; =20 +static __always_inline int user_mode(struct pt_regs *regs) +{ + return !!(regs->cs & 3); +} + /* * is_string_insn() - Determine if instruction is a string instruction * @insn: Instruction containing the opcode to inspect @@ -528,16 +536,16 @@ unsigned long insn_get_seg_base(struct pt_regs *regs,= int seg_reg_idx) */ =20 if (seg_reg_idx =3D=3D INAT_SEG_REG_FS) { - rdmsrq(MSR_FS_BASE, base); + base =3D rdmsr(MSR_FS_BASE); } else if (seg_reg_idx =3D=3D INAT_SEG_REG_GS) { /* * swapgs was called at the kernel entry point. Thus, * MSR_KERNEL_GS_BASE will have the user-space GS base. */ if (user_mode(regs)) - rdmsrq(MSR_KERNEL_GS_BASE, base); + base =3D rdmsr(MSR_KERNEL_GS_BASE); else - rdmsrq(MSR_GS_BASE, base); + base =3D rdmsr(MSR_GS_BASE); } else { base =3D 0; } --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from SN4PR0501CU005.outbound.protection.outlook.com (mail-southcentralusazon11011066.outbound.protection.outlook.com [40.93.194.66]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E8A5130E82A; Tue, 23 Sep 2025 05:15:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.194.66 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604507; cv=fail; b=SehWOHzf3OIydIkZZm7BlDZPfqKsz6Yt7Qs9vRQmu43Ce8LfE9XART1Njkx9EelGlzJH7F40OGEyNiR+BHl/ICULbcjq8Le3VuYJzwj/2Aj3rE0RYfBaSvr2OokYOBHHjhOvaeJDdCoseY8ouwAZ4mrkozAVefHejqEYyUkcnYo= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604507; c=relaxed/simple; bh=KXDWZNG6Ap/6Gefx7y9IWYh26V454/olqvOMA4i9W2g=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=jGge66DUEKUJzev1Bq8u44upPPNsF4UUtLRuZDShgfi8klZ01cjZwNP3Q/fUhllgipDX1VkHrO9GzghoXYUPemOr3nimQ7I1WcttYTDSVO43ru1yKYPpddMYrZgptHooZXjPpLTQ+XEtL78G46rpRa64ZEUt4tJF1Y+79cp+Qxg= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=STVluzmq; arc=fail smtp.client-ip=40.93.194.66 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="STVluzmq" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=FwwK7UM1nkOoaqrxtp8CtnMLjsdIqjPI1kT2iN8HefcobSnPYdaayWUSCVwHXfpvMAw69q0NIixVWdSMZGZdMitZ0+y9Z0YJYREb8Cgq9HNcciUTSScHNVa98A4Wpemo/YDTqNlCX+kwmAStQ3N/GCEBSB6KPQGEUZTcccynuf/9e467wVN4j6vWH57onbNrf13ElqHBUXGoB0fOL7M0arcCVHFwjFOD+dHpyBBilKT9Q0WV9yDjGWt/QINo/uoOd8iWK6j6/meoWRcNbpnAtD+3s/s2K4S5GnOUOJuMbftKjJXjZ4RrCrRrb/1iFsVTl4as8Vsv2zvqDEj8jAFycg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=VWJMBUpVPhroSV8f77RjqnSwQsLsxGJS7nBtw+5eMCE=; b=q6otPQQlsPMLVoKASKI79rmIGww09fUwG128zpXt0lZ1zy2ZrZtgTj4mUZLvC3ktZ7i1qOo6wGQFS51urWx6nPV8bWpaKyPth6ZxVjp/ULY+sqI7/M5hNbA1oXEAa3rTDlamZz28ysK4M3GkVvKcE92AEVInZlOx8lTYdxhfvhTTNMCAjX6yLoyDrAPaAhy7VfBKD5AY6FBPw9TOp9xs9qaiQvNU9IKoShbI+EURgQv/YE8F2/bgzvmdaKt8O1PVTMBbKTPPfvLzsh1tqy7zuGQiyPsn27KfGRVTG8inSs8mC8mh3NFfpZr44q8u4FEoo1iYnxdhbHbekTgUe1E6Qg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=VWJMBUpVPhroSV8f77RjqnSwQsLsxGJS7nBtw+5eMCE=; b=STVluzmq24xgm3+YD9Qs3mbT1LvabLfSCWl/y91tBihW/6+UtHhflEsQDol/FeYKKWExWcLCznKMCP5TLfyy9RRtSlonwsH5bEI8HRHvRcMRt2SR0sRSe8gotxF/bn69DRY8V3BWUhrMmdm8U5gPOET5lgHEyFQ02fDh0L+VHYo= Received: from CH0PR07CA0017.namprd07.prod.outlook.com (2603:10b6:610:32::22) by IA1PR12MB9063.namprd12.prod.outlook.com (2603:10b6:208:3a9::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.17; Tue, 23 Sep 2025 05:14:58 +0000 Received: from CH2PEPF0000013D.namprd02.prod.outlook.com (2603:10b6:610:32:cafe::44) by CH0PR07CA0017.outlook.office365.com (2603:10b6:610:32::22) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:14:57 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF0000013D.mail.protection.outlook.com (10.167.244.69) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:14:57 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:14:52 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 17/35] KVM: selftests: Change pt_regs to ex_regs for selftest use Date: Tue, 23 Sep 2025 10:39:24 +0530 Message-ID: <20250923050942.206116-18-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF0000013D:EE_|IA1PR12MB9063:EE_ X-MS-Office365-Filtering-Correlation-Id: 04c4b7e4-603f-4f82-d267-08ddfa6023ba X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|376014|36860700013|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?O2klLh43wDCpw2WFnIIvK1jV2Yd21wSBAdupa6h4BoAtTVVQMnmP4VIqLVQV?= =?us-ascii?Q?O/I10vV357qTLrd3XTgebk2vsYtN+PrlpwERgyYrObEP0vUKGcMusL7r2CUH?= =?us-ascii?Q?lcjyfdYSJ/I2ih9QRkfbwXKQLqM6tmqU4UXbbb6tFz5O/8MoRBfohYqzfOTv?= =?us-ascii?Q?S+q3/K4iw2ABnRhE3knvr7oUM0WFDcl9ETk7UGYQBsNRkxnCSkC2f8t1MqVL?= =?us-ascii?Q?DAusZ1NhzejMe2Wmsf87Jyy8UyoFENTummSvKl20R12OvbYhKpDQ8TBL3Vo3?= =?us-ascii?Q?FDv5F7Rz70RTB+ZhSOIyDGhTY/LIwh7arhWuaLiM+jIG8aLJf1blDBjY3LRk?= =?us-ascii?Q?YUB7eN6rPRZSqKToQMEwZ+b2KpEd85GYQVYOOyy2uKEPMMU6EZkPGFkKNBYM?= =?us-ascii?Q?u2iNM8WYBCkolH5MhrTHHXI8F7RldQZDc1Wni5p4Rd7AkbZUYq885yCDUfZ5?= =?us-ascii?Q?FipI0IgRFtUWYoYsaBRoun5MmpOA84pPCQUQLAeYjLqEppa2rnH9e7rFe5te?= =?us-ascii?Q?kcyw9KfZBxTIRSEQiuUddPcEckV/8kogTRfL+/hr3rtzj7oI5nDBD7C6fSSz?= =?us-ascii?Q?bbSWm5IX6AyAE4e922c3otnJo5ggLlQLPzdnbzq56NgA6E1CDfHWozIXmVnp?= =?us-ascii?Q?u+V2xfH5Jd/1fR64QyZ55Qesrh3vbJSs4mM9tvU6SoOVkSnRllLy/ArKmmeb?= =?us-ascii?Q?Ys2wTH/xewTLNkYF/86CqZgYJWyA9oQ+MCCcSfdxQEbP3MBvF0kh3Bd1WnBF?= =?us-ascii?Q?/l3t5TISsxTqrAHi84jamsqoWmv4M2VL3THGyFQlSZUO/KqvmgjjjyMULOi6?= =?us-ascii?Q?8ABxN+r3toqdoR64JA6OqdH52amfhoVtCa3oKohuArPd9NJWv15Kfds7wRjZ?= =?us-ascii?Q?6CwvD+TXnaVBPuPNUtDpENj0uPB4uNKkWWQywU6C42gGaGTF6f06GI39af45?= =?us-ascii?Q?UFYPMM4gGIj9n08rD81PAHnjxD2N5VrnFt1/mwwcx0qRz3/8m0ec95KXNVjQ?= =?us-ascii?Q?J+/uHFGFzCjmEVdUHEDAO4rSVDr1y9r8q0SpaEOZgdRcGGi83c14bhiaRY7O?= =?us-ascii?Q?WXnqUUyqUGrYS/92o3QfXJSWGbJzCxKtteCwHSed7bv9dKXvXwgYCG6HIpb1?= =?us-ascii?Q?HmPOEDDuV1YEGqo98G/2alT+9Yoin8lS9+QSwWYyPUbhgDeo/y6PJdvusq4Z?= =?us-ascii?Q?kmNOktjjSxKf/nrnd6eEkl89JQCxzG+hFmfC7Kf7TIGd1FtFmnAKSpX0VEGQ?= =?us-ascii?Q?XJ34xtiekb9IvbXUI1TEK/YC9hgyJQj82nxA51wppEqAQfreXs8kcbcGxhIG?= =?us-ascii?Q?Mno1HLXCW51o47cgn2/AQhLyP5p/Z/JVYAs2f/NSBwUZOT6Ebv58VCr4X8GW?= =?us-ascii?Q?VxIIn5fZ1P6OiJsmqfvWSk/UIO4dF772/6n9qbQnR9MR1Fy8TaqJBupvR/bI?= =?us-ascii?Q?twaDOOR1PuyQwH3kYip0EHx+PONV/XKpfOGZ2oXrXIMXwgV4FlOqn/3HR2TF?= =?us-ascii?Q?/hO5PaTghPig7lHj3zJB4iYyYStfDGcB+li6?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(376014)(36860700013)(1800799024);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:14:57.9196 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 04c4b7e4-603f-4f82-d267-08ddfa6023ba X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF0000013D.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA1PR12MB9063 Content-Type: text/plain; charset="utf-8" Signed-off-by: Neeraj Upadhyay --- .../selftests/kvm/include/x86/insn-eval.h | 24 +-- .../selftests/kvm/include/x86/processor.h | 2 + .../testing/selftests/kvm/lib/x86/insn-eval.c | 159 +++++++++--------- 3 files changed, 96 insertions(+), 89 deletions(-) diff --git a/tools/testing/selftests/kvm/include/x86/insn-eval.h b/tools/te= sting/selftests/kvm/include/x86/insn-eval.h index 68d49199f991..0547b622295a 100644 --- a/tools/testing/selftests/kvm/include/x86/insn-eval.h +++ b/tools/testing/selftests/kvm/include/x86/insn-eval.h @@ -8,25 +8,27 @@ =20 #include =20 +#include "processor.h" + #define INSN_CODE_SEG_ADDR_SZ(params) ((params >> 4) & 0xf) #define INSN_CODE_SEG_OPND_SZ(params) (params & 0xf) #define INSN_CODE_SEG_PARAMS(oper_sz, addr_sz) (oper_sz | (addr_sz << 4)) =20 -int pt_regs_offset(struct pt_regs *regs, int regno); +int ex_regs_offset(struct ex_regs *regs, int regno); =20 bool insn_has_rep_prefix(struct insn *insn); -void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs); -int insn_get_modrm_rm_off(struct insn *insn, struct pt_regs *regs); -int insn_get_modrm_reg_off(struct insn *insn, struct pt_regs *regs); -unsigned long *insn_get_modrm_reg_ptr(struct insn *insn, struct pt_regs *r= egs); -unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx); -int insn_get_code_seg_params(struct pt_regs *regs); -int insn_get_effective_ip(struct pt_regs *regs, unsigned long *ip); -int insn_fetch_from_user(struct pt_regs *regs, +void __user *insn_get_addr_ref(struct insn *insn, struct ex_regs *regs); +int insn_get_modrm_rm_off(struct insn *insn, struct ex_regs *regs); +int insn_get_modrm_reg_off(struct insn *insn, struct ex_regs *regs); +unsigned long *insn_get_modrm_reg_ptr(struct insn *insn, struct ex_regs *r= egs); +unsigned long insn_get_seg_base(struct ex_regs *regs, int seg_reg_idx); +int insn_get_code_seg_params(struct ex_regs *regs); +int insn_get_effective_ip(struct ex_regs *regs, unsigned long *ip); +int insn_fetch_from_user(struct ex_regs *regs, unsigned char buf[MAX_INSN_SIZE]); -int insn_fetch_from_user_inatomic(struct pt_regs *regs, +int insn_fetch_from_user_inatomic(struct ex_regs *regs, unsigned char buf[MAX_INSN_SIZE]); -bool insn_decode_from_regs(struct insn *insn, struct pt_regs *regs, +bool insn_decode_from_regs(struct insn *insn, struct ex_regs *regs, unsigned char buf[MAX_INSN_SIZE], int buf_size); =20 enum insn_mmio_type { diff --git a/tools/testing/selftests/kvm/include/x86/processor.h b/tools/te= sting/selftests/kvm/include/x86/processor.h index 2efb05c2f2fb..035ced9130c2 100644 --- a/tools/testing/selftests/kvm/include/x86/processor.h +++ b/tools/testing/selftests/kvm/include/x86/processor.h @@ -1161,6 +1161,8 @@ struct ex_regs { uint64_t rip; uint64_t cs; uint64_t rflags; + uint64_t rsp; + uint64_t ss; }; =20 struct idt_entry { diff --git a/tools/testing/selftests/kvm/lib/x86/insn-eval.c b/tools/testin= g/selftests/kvm/lib/x86/insn-eval.c index fb393aaf9f7f..369530badba9 100644 --- a/tools/testing/selftests/kvm/lib/x86/insn-eval.c +++ b/tools/testing/selftests/kvm/lib/x86/insn-eval.c @@ -21,6 +21,12 @@ #define savesegment(seg, value) \ asm("mov %%" #seg ",%0":"=3Dr" (value) : : "memory") =20 +static inline unsigned long regs_get_register(struct ex_regs *regs, + unsigned int offset) +{ + return *(unsigned long *)((unsigned long)regs + offset); +} + enum reg_type { REG_TYPE_RM =3D 0, REG_TYPE_REG, @@ -28,7 +34,7 @@ enum reg_type { REG_TYPE_BASE, }; =20 -static __always_inline int user_mode(struct pt_regs *regs) +static __always_inline int user_mode(struct ex_regs *regs) { return !!(regs->cs & 3); } @@ -148,7 +154,7 @@ static int get_seg_reg_override_idx(struct insn *insn) /* * check_seg_overrides() - check if segment override prefixes are allowed * @insn: Valid instruction with segment override prefixes - * @regoff: Operand offset, in pt_regs, for which the check is performed + * @regoff: Operand offset, in ex_regs, for which the check is performed * * For a particular register used in register-indirect addressing, determi= ne if * segment override prefixes can be used. Specifically, no overrides are a= llowed @@ -161,7 +167,7 @@ static int get_seg_reg_override_idx(struct insn *insn) */ static bool check_seg_overrides(struct insn *insn, int regoff) { - if (regoff =3D=3D offsetof(struct pt_regs, di) && is_string_insn(insn)) + if (regoff =3D=3D offsetof(struct ex_regs, rdi) && is_string_insn(insn)) return false; =20 return true; @@ -171,7 +177,7 @@ static bool check_seg_overrides(struct insn *insn, int = regoff) * resolve_default_seg() - resolve default segment register index for an o= perand * @insn: Instruction with opcode and address size. Must be valid. * @regs: Register values as seen when entering kernel mode - * @off: Operand offset, in pt_regs, for which resolution is needed + * @off: Operand offset, in ex_regs, for which resolution is needed * * Resolve the default segment register index associated with the instruct= ion * operand register indicated by @off. Such index is resolved based on def= aults @@ -184,7 +190,7 @@ static bool check_seg_overrides(struct insn *insn, int = regoff) * * -EINVAL in case of error. */ -static int resolve_default_seg(struct insn *insn, struct pt_regs *regs, in= t off) +static int resolve_default_seg(struct insn *insn, struct ex_regs *regs, in= t off) { return INAT_SEG_REG_IGNORE; } @@ -193,7 +199,7 @@ static int resolve_default_seg(struct insn *insn, struc= t pt_regs *regs, int off) * resolve_seg_reg() - obtain segment register index * @insn: Instruction with operands * @regs: Register values as seen when entering kernel mode - * @regoff: Operand offset, in pt_regs, used to determine segment register + * @regoff: Operand offset, in ex_regs, used to determine segment register * * Determine the segment register associated with the operands and, if * applicable, prefixes and the instruction pointed by @insn. @@ -221,7 +227,7 @@ static int resolve_default_seg(struct insn *insn, struc= t pt_regs *regs, int off) * are done using helper functions. * * The operand register, @regoff, is represented as the offset from the ba= se of - * pt_regs. + * ex_regs. * * As stated, the main use of this function is to determine the segment re= gister * index based on the instruction, its operands and prefixes. Hence, @insn @@ -241,7 +247,7 @@ static int resolve_default_seg(struct insn *insn, struc= t pt_regs *regs, int off) * * -EINVAL in case of error. */ -static int resolve_seg_reg(struct insn *insn, struct pt_regs *regs, int re= goff) +static int resolve_seg_reg(struct insn *insn, struct ex_regs *regs, int re= goff) { int idx; =20 @@ -251,7 +257,7 @@ static int resolve_seg_reg(struct insn *insn, struct pt= _regs *regs, int regoff) * be used. Hence, it is not necessary to inspect the instruction, * which may be invalid at this point. */ - if (regoff =3D=3D offsetof(struct pt_regs, ip)) + if (regoff =3D=3D offsetof(struct ex_regs, rip)) return INAT_SEG_REG_IGNORE; =20 if (!insn) @@ -282,7 +288,7 @@ static int resolve_seg_reg(struct insn *insn, struct pt= _regs *regs, int regoff) * @seg_reg_idx: Segment register index to use * * Obtain the segment selector from any of the CS, SS, DS, ES, FS, GS segm= ent - * registers. CS and SS are obtained from pt_regs. DS, ES, FS and GS are + * registers. CS and SS are obtained from ex_regs. DS, ES, FS and GS are * obtained by reading the actual CPU registers. This done for only for * completeness as in X86_64 segment registers are ignored. * @@ -293,7 +299,7 @@ static int resolve_seg_reg(struct insn *insn, struct pt= _regs *regs, int regoff) * * -EINVAL on error. */ -static short get_segment_selector(struct pt_regs *regs, int seg_reg_idx) +static short get_segment_selector(struct ex_regs *regs, int seg_reg_idx) { unsigned short sel; =20 @@ -321,35 +327,35 @@ static short get_segment_selector(struct pt_regs *reg= s, int seg_reg_idx) } } =20 -static const int pt_regoff[] =3D { - offsetof(struct pt_regs, ax), - offsetof(struct pt_regs, cx), - offsetof(struct pt_regs, dx), - offsetof(struct pt_regs, bx), - offsetof(struct pt_regs, sp), - offsetof(struct pt_regs, bp), - offsetof(struct pt_regs, si), - offsetof(struct pt_regs, di), - offsetof(struct pt_regs, r8), - offsetof(struct pt_regs, r9), - offsetof(struct pt_regs, r10), - offsetof(struct pt_regs, r11), - offsetof(struct pt_regs, r12), - offsetof(struct pt_regs, r13), - offsetof(struct pt_regs, r14), - offsetof(struct pt_regs, r15), +static const int ex_regoff[] =3D { + offsetof(struct ex_regs, rax), + offsetof(struct ex_regs, rcx), + offsetof(struct ex_regs, rdx), + offsetof(struct ex_regs, rbx), + offsetof(struct ex_regs, rsp), + offsetof(struct ex_regs, rbp), + offsetof(struct ex_regs, rsi), + offsetof(struct ex_regs, rdi), + offsetof(struct ex_regs, r8), + offsetof(struct ex_regs, r9), + offsetof(struct ex_regs, r10), + offsetof(struct ex_regs, r11), + offsetof(struct ex_regs, r12), + offsetof(struct ex_regs, r13), + offsetof(struct ex_regs, r14), + offsetof(struct ex_regs, r15), }; =20 -int pt_regs_offset(struct pt_regs *regs, int regno) +int ex_regs_offset(struct ex_regs *regs, int regno) { - if ((unsigned)regno < ARRAY_SIZE(pt_regoff)) - return pt_regoff[regno]; + if ((unsigned)regno < ARRAY_SIZE(ex_regoff)) + return ex_regoff[regno]; return -EDOM; } =20 static int get_regno(struct insn *insn, enum reg_type type) { - int nr_registers =3D ARRAY_SIZE(pt_regoff); + int nr_registers =3D ARRAY_SIZE(ex_regoff); int regno =3D 0; =20 /* @@ -419,7 +425,7 @@ static int get_regno(struct insn *insn, enum reg_type t= ype) return regno; } =20 -static int get_reg_offset(struct insn *insn, struct pt_regs *regs, +static int get_reg_offset(struct insn *insn, struct ex_regs *regs, enum reg_type type) { int regno =3D get_regno(insn, type); @@ -427,7 +433,7 @@ static int get_reg_offset(struct insn *insn, struct pt_= regs *regs, if (regno < 0) return regno; =20 - return pt_regs_offset(regs, regno); + return ex_regs_offset(regs, regno); } =20 /* @@ -437,7 +443,7 @@ static int get_reg_offset(struct insn *insn, struct pt_= regs *regs, * @offs1: Offset of the first operand register * @offs2: Offset of the second operand register, if applicable * - * Obtain the offset, in pt_regs, of the registers indicated by the ModRM = byte + * Obtain the offset, in ex_regs, of the registers indicated by the ModRM = byte * in @insn. This function is to be used with 16-bit address encodings. The * @offs1 and @offs2 will be written with the offset of the two registers * indicated by the instruction. In cases where any of the registers is not @@ -447,7 +453,7 @@ static int get_reg_offset(struct insn *insn, struct pt_= regs *regs, * * 0 on success, -EINVAL on error. */ -static int get_reg_offset_16(struct insn *insn, struct pt_regs *regs, +static int get_reg_offset_16(struct insn *insn, struct ex_regs *regs, int *offs1, int *offs2) { /* @@ -456,21 +462,21 @@ static int get_reg_offset_16(struct insn *insn, struc= t pt_regs *regs, * ModR/M Byte" of the Intel Software Development Manual. */ static const int regoff1[] =3D { - offsetof(struct pt_regs, bx), - offsetof(struct pt_regs, bx), - offsetof(struct pt_regs, bp), - offsetof(struct pt_regs, bp), - offsetof(struct pt_regs, si), - offsetof(struct pt_regs, di), - offsetof(struct pt_regs, bp), - offsetof(struct pt_regs, bx), + offsetof(struct ex_regs, rbx), + offsetof(struct ex_regs, rbx), + offsetof(struct ex_regs, rbp), + offsetof(struct ex_regs, rbp), + offsetof(struct ex_regs, rsi), + offsetof(struct ex_regs, rdi), + offsetof(struct ex_regs, rbp), + offsetof(struct ex_regs, rbx), }; =20 static const int regoff2[] =3D { - offsetof(struct pt_regs, si), - offsetof(struct pt_regs, di), - offsetof(struct pt_regs, si), - offsetof(struct pt_regs, di), + offsetof(struct ex_regs, rsi), + offsetof(struct ex_regs, rdi), + offsetof(struct ex_regs, rsi), + offsetof(struct ex_regs, rdi), -EDOM, -EDOM, -EDOM, @@ -521,7 +527,7 @@ static int get_reg_offset_16(struct insn *insn, struct = pt_regs *regs, * * -1L in case of error. */ -unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx) +unsigned long insn_get_seg_base(struct ex_regs *regs, int seg_reg_idx) { unsigned long base; short sel; @@ -542,10 +548,7 @@ unsigned long insn_get_seg_base(struct pt_regs *regs, = int seg_reg_idx) * swapgs was called at the kernel entry point. Thus, * MSR_KERNEL_GS_BASE will have the user-space GS base. */ - if (user_mode(regs)) - base =3D rdmsr(MSR_KERNEL_GS_BASE); - else - base =3D rdmsr(MSR_GS_BASE); + base =3D rdmsr(MSR_GS_BASE); } else { base =3D 0; } @@ -569,7 +572,7 @@ unsigned long insn_get_seg_base(struct pt_regs *regs, i= nt seg_reg_idx) * * Zero is returned on error. */ -static unsigned long get_seg_limit(struct pt_regs *regs, int seg_reg_idx) +static unsigned long get_seg_limit(struct ex_regs *regs, int seg_reg_idx) { short sel; =20 @@ -588,9 +591,9 @@ static unsigned long get_seg_limit(struct pt_regs *regs= , int seg_reg_idx) * Returns: * * The register indicated by the reg part of the ModRM byte. The - * register is obtained as an offset from the base of pt_regs. + * register is obtained as an offset from the base of ex_regs. */ -int insn_get_modrm_reg_off(struct insn *insn, struct pt_regs *regs) +int insn_get_modrm_reg_off(struct insn *insn, struct ex_regs *regs) { return get_reg_offset(insn, regs, REG_TYPE_REG); } @@ -603,9 +606,9 @@ int insn_get_modrm_reg_off(struct insn *insn, struct pt= _regs *regs) * Returns: * * The register indicated by the reg part of the ModRM byte. - * The register is obtained as a pointer within pt_regs. + * The register is obtained as a pointer within ex_regs. */ -unsigned long *insn_get_modrm_reg_ptr(struct insn *insn, struct pt_regs *r= egs) +unsigned long *insn_get_modrm_reg_ptr(struct insn *insn, struct ex_regs *r= egs) { int offset; =20 @@ -619,7 +622,7 @@ unsigned long *insn_get_modrm_reg_ptr(struct insn *insn= , struct pt_regs *regs) * get_seg_base_limit() - obtain base address and limit of a segment * @insn: Instruction. Must be valid. * @regs: Register values as seen when entering kernel mode - * @regoff: Operand offset, in pt_regs, used to resolve segment descriptor + * @regoff: Operand offset, in ex_regs, used to resolve segment descriptor * @base: Obtained segment base * @limit: Obtained segment limit * @@ -636,7 +639,7 @@ unsigned long *insn_get_modrm_reg_ptr(struct insn *insn= , struct pt_regs *regs) * * -EINVAL on error. */ -static int get_seg_base_limit(struct insn *insn, struct pt_regs *regs, +static int get_seg_base_limit(struct insn *insn, struct ex_regs *regs, int regoff, unsigned long *base, unsigned long *limit) { @@ -667,13 +670,13 @@ static int get_seg_base_limit(struct insn *insn, stru= ct pt_regs *regs, * get_eff_addr_reg() - Obtain effective address from register operand * @insn: Instruction. Must be valid. * @regs: Register values as seen when entering kernel mode - * @regoff: Obtained operand offset, in pt_regs, with the effective address + * @regoff: Obtained operand offset, in ex_regs, with the effective address * @eff_addr: Obtained effective address * * Obtain the effective address stored in the register operand as indicate= d by * the ModRM byte. This function is to be used only with register addressi= ng * (i.e., ModRM.mod is 3). The effective address is saved in @eff_addr. T= he - * register operand, as an offset from the base of pt_regs, is saved in @r= egoff; + * register operand, as an offset from the base of ex_regs, is saved in @r= egoff; * such offset can then be used to resolve the segment associated with the * operand. This function can be used with any of the supported address si= zes * in x86. @@ -682,11 +685,11 @@ static int get_seg_base_limit(struct insn *insn, stru= ct pt_regs *regs, * * 0 on success. @eff_addr will have the effective address stored in the * operand indicated by ModRM. @regoff will have such operand as an offset= from - * the base of pt_regs. + * the base of ex_regs. * * -EINVAL on error. */ -static int get_eff_addr_reg(struct insn *insn, struct pt_regs *regs, +static int get_eff_addr_reg(struct insn *insn, struct ex_regs *regs, int *regoff, long *eff_addr) { int ret; @@ -717,7 +720,7 @@ static int get_eff_addr_reg(struct insn *insn, struct p= t_regs *regs, * get_eff_addr_modrm() - Obtain referenced effective address via ModRM * @insn: Instruction. Must be valid. * @regs: Register values as seen when entering kernel mode - * @regoff: Obtained operand offset, in pt_regs, associated with segment + * @regoff: Obtained operand offset, in ex_regs, associated with segment * @eff_addr: Obtained effective address * * Obtain the effective address referenced by the ModRM byte of @insn. Aft= er @@ -730,12 +733,12 @@ static int get_eff_addr_reg(struct insn *insn, struct= pt_regs *regs, * Returns: * * 0 on success. @eff_addr will have the referenced effective address. @re= goff - * will have a register, as an offset from the base of pt_regs, that can b= e used + * will have a register, as an offset from the base of ex_regs, that can b= e used * to resolve the associated segment. * * -EINVAL on error. */ -static int get_eff_addr_modrm(struct insn *insn, struct pt_regs *regs, +static int get_eff_addr_modrm(struct insn *insn, struct ex_regs *regs, int *regoff, long *eff_addr) { long tmp; @@ -759,7 +762,7 @@ static int get_eff_addr_modrm(struct insn *insn, struct= pt_regs *regs, * following instruction. */ if (*regoff =3D=3D -EDOM) { - tmp =3D regs->ip + insn->length; + tmp =3D regs->rip + insn->length; } else if (*regoff < 0) { return -EINVAL; } else { @@ -781,7 +784,7 @@ static int get_eff_addr_modrm(struct insn *insn, struct= pt_regs *regs, * get_eff_addr_modrm_16() - Obtain referenced effective address via ModRM * @insn: Instruction. Must be valid. * @regs: Register values as seen when entering kernel mode - * @regoff: Obtained operand offset, in pt_regs, associated with segment + * @regoff: Obtained operand offset, in ex_regs, associated with segment * @eff_addr: Obtained effective address * * Obtain the 16-bit effective address referenced by the ModRM byte of @in= sn. @@ -794,12 +797,12 @@ static int get_eff_addr_modrm(struct insn *insn, stru= ct pt_regs *regs, * Returns: * * 0 on success. @eff_addr will have the referenced effective address. @re= goff - * will have a register, as an offset from the base of pt_regs, that can b= e used + * will have a register, as an offset from the base of ex_regs, that can b= e used * to resolve the associated segment. * * -EINVAL on error. */ -static int get_eff_addr_modrm_16(struct insn *insn, struct pt_regs *regs, +static int get_eff_addr_modrm_16(struct insn *insn, struct ex_regs *regs, int *regoff, short *eff_addr) { int addr_offset1, addr_offset2, ret; @@ -849,7 +852,7 @@ static int get_eff_addr_modrm_16(struct insn *insn, str= uct pt_regs *regs, * get_eff_addr_sib() - Obtain referenced effective address via SIB * @insn: Instruction. Must be valid. * @regs: Register values as seen when entering kernel mode - * @base_offset: Obtained operand offset, in pt_regs, associated with segm= ent + * @base_offset: Obtained operand offset, in ex_regs, associated with segm= ent * @eff_addr: Obtained effective address * * Obtain the effective address referenced by the SIB byte of @insn. After @@ -862,12 +865,12 @@ static int get_eff_addr_modrm_16(struct insn *insn, s= truct pt_regs *regs, * Returns: * * 0 on success. @eff_addr will have the referenced effective address. - * @base_offset will have a register, as an offset from the base of pt_reg= s, + * @base_offset will have a register, as an offset from the base of ex_reg= s, * that can be used to resolve the associated segment. * * Negative value on error. */ -static int get_eff_addr_sib(struct insn *insn, struct pt_regs *regs, +static int get_eff_addr_sib(struct insn *insn, struct ex_regs *regs, int *base_offset, long *eff_addr) { long base, indx; @@ -951,7 +954,7 @@ static int get_eff_addr_sib(struct insn *insn, struct p= t_regs *regs, * * -1L on error. */ -static void __user *get_addr_ref_16(struct insn *insn, struct pt_regs *reg= s) +static void __user *get_addr_ref_16(struct insn *insn, struct ex_regs *reg= s) { unsigned long linear_addr =3D -1L, seg_base, seg_limit; int ret, regoff; @@ -1012,7 +1015,7 @@ static void __user *get_addr_ref_16(struct insn *insn= , struct pt_regs *regs) * * -1L on error. */ -static void __user *get_addr_ref_32(struct insn *insn, struct pt_regs *reg= s) +static void __user *get_addr_ref_32(struct insn *insn, struct ex_regs *reg= s) { unsigned long linear_addr =3D -1L, seg_base, seg_limit; int eff_addr, regoff; @@ -1076,7 +1079,7 @@ static void __user *get_addr_ref_32(struct insn *insn= , struct pt_regs *regs) * * -1L on error. */ -static void __user *get_addr_ref_64(struct insn *insn, struct pt_regs *reg= s) +static void __user *get_addr_ref_64(struct insn *insn, struct ex_regs *reg= s) { unsigned long linear_addr =3D -1L, seg_base; int regoff, ret; @@ -1128,7 +1131,7 @@ static void __user *get_addr_ref_64(struct insn *insn= , struct pt_regs *regs) * * -1L on error. */ -void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs) +void __user *insn_get_addr_ref(struct insn *insn, struct ex_regs *regs) { if (!insn || !regs) return (void __user *)-1L; --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from CO1PR03CU002.outbound.protection.outlook.com (mail-westus2azon11010051.outbound.protection.outlook.com [52.101.46.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 474AE30DEA0; Tue, 23 Sep 2025 05:15:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.46.51 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604524; cv=fail; b=OMpE+DcoOTmyezj/BVGTqhL1E5SSOA5Cf6C76L7SUSiyZVTkyDisqlciWgPNY33PgJXOjSR4jZNUUBBPjSi49/zPPdEgdBxS91/6pLFxmuqBLH6BUHYuO1iFk8JeUZm7Xold1LY/lUwEsgJKN80YVKOuIDjwpOI5Hh8daiNSlbU= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604524; c=relaxed/simple; bh=O5u7bZDATTLx+Hb2V6DP/e7nhkUlhTyAEPbMxXUWof0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=JotJJv6AhFjBEpuW1wFJs2a2ot6JUyiBt30977YAUw72nXbqsU/wqiUItsQabyEaF51yxwBxmN0fos/3Ztp0P6P7Fjb0GjOQtlQWA0MKBwmF5T5vz6SYRNuX52kiIHYaRUOaPm2Mrg+gstr2e/6wwgAYxAArfyEtYvAuHd1J/2Q= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=JN+sfmVo; arc=fail smtp.client-ip=52.101.46.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="JN+sfmVo" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=Bs74x+u+IjE/FElZo29n69zAYjoygjkDkwPgKhVFzk3JFMwe5gWyKLfqrQd1pMuoNvNFKkvTx1O/CUd+JqVptbI4Qv0Y4zo5I+EEXY7vrSee2//PAamtG2a3Ix9HC/XsvJWguRHxhFMAj7+rAYHw+FH2Q1AmtMxUgeeRYBOztPA1UpebMKjs0WZgPUAY5qUfhOmNP/1qz3sNJfKl/Crgj6lTYmFtu9nNfKRsmEAcphnC/zaq6Q8K7q7sbgrgUtMoh+FydR1jX0EBBPDLz/g3qj4P29isbPF+6bKxZf/6PIuXNXRITT8Zt52P+G0XFteknVPwkz0jj2Xlrxvw92iowg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=qRZ79i3OYun0giPHo2gKR/+rKAMBoH5rek6YJujAiPQ=; b=O3NjzOGIqfbXa/SDGr4fh0lsTruBXbQ9YqgwmahjesC54C8nex7+MPY35aurOemdPQB7H7mO1qa83gsV82HQuHa7giL9Jnx5DIMrcdlvibyzzsVqAODrzBocbaY54Zsnm9mUoI0LSqGhIsNqU/jwEL0Gwd20lJX2PHI5DXktaPPKYr6Lsm4MxBbAU2OL6zi8jIncJEu3bov/rTDgvf+Ps09hqvMOV5bV5popgXjsdqFOPivnCOCidSuE8eVl804bv0eQY0Z2zlatyAxcNGVOMW71qj8BC0H8KUp98M1pvQxDPfr7Kt9ZsJIP8aGuTMsHMAcG01gcbCQ+qtY8cyRXaw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=temperror (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=temperror action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=qRZ79i3OYun0giPHo2gKR/+rKAMBoH5rek6YJujAiPQ=; b=JN+sfmVofo2RJw44VDLtuGyhilJR/lok62PwQMrcXU0yTX4emRE3sS0fsGA/A96TtPZJGtUkK0dJsRc9LedlQ0q+ZAg8/1V+r/DQWupvn3bB0Kp8WpdkSmDPFZW0sGyPe16AaiGtGcBo9nQplXUNPBoO8QkQ/n1wXixf88eHS8I= Received: from IA4P220CA0008.NAMP220.PROD.OUTLOOK.COM (2603:10b6:208:558::6) by DM4PR12MB9071.namprd12.prod.outlook.com (2603:10b6:8:bd::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.19; Tue, 23 Sep 2025 05:15:16 +0000 Received: from BL6PEPF0001AB72.namprd02.prod.outlook.com (2603:10b6:208:558:cafe::44) by IA4P220CA0008.outlook.office365.com (2603:10b6:208:558::6) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.21 via Frontend Transport; Tue, 23 Sep 2025 05:15:23 +0000 X-MS-Exchange-Authentication-Results: spf=temperror (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=temperror action=none header.from=amd.com; Received-SPF: TempError (protection.outlook.com: error in processing during lookup of amd.com: DNS Timeout) Received: from satlexmb07.amd.com (165.204.84.17) by BL6PEPF0001AB72.mail.protection.outlook.com (10.167.242.165) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:15:15 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:15:10 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 18/35] KVM: selftests: Add compilation for instruction decoder library Date: Tue, 23 Sep 2025 10:39:25 +0530 Message-ID: <20250923050942.206116-19-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BL6PEPF0001AB72:EE_|DM4PR12MB9071:EE_ X-MS-Office365-Filtering-Correlation-Id: 2798cfa4-bc9b-42a0-503a-08ddfa602e4f X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|376014|36860700013|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?vMTZXPeQ12zpUKN8sbIoy98uz0+NQAlJh0Egv7GXmr3dehSGyR3ZvneeXNsp?= =?us-ascii?Q?h4J3/vVuNQre3siD07VF8njdQIITw2QRykvuT2g9WQSswDIWwGMwJKeHNYL9?= =?us-ascii?Q?VAp+aVzAa8AoK+c8yMjYfs5eSjr5nLvDrQgXln0VYkDe/Mfimfwf/Y2RtR/7?= =?us-ascii?Q?/cIr7YJeEcO9+RcUnv3AUbS+iuJ3a2dQ/qiptFJ8pferHn1FGHgihFkC7dRU?= =?us-ascii?Q?eMK/26LTKh578G4jz4SmFt/NWvFojlcDbvEnT6jDB5BWzZ5Wm00KWdlf5PTl?= =?us-ascii?Q?X9Hjlphndfa8xVRbbKDGwi0GB6IZjsyk5GA5rwYCQ34ekOqwfSaNWUQQWp07?= =?us-ascii?Q?DgmX2wT5enrJjzHGb4A1vunkjmlnCVa/YEvQg4UBc78WGDzCye+pItSqiLFi?= =?us-ascii?Q?p735b5fl65zfg6QAcJFm5AUuCwFFfqhlmDh9vt4I/sr7lG2csLuahKPnKFRj?= =?us-ascii?Q?6kQJPy1vf3vzdD+koAAkz50W62HgCvl3bxnZ462R0wUWICTsYg0ID3zSojvW?= =?us-ascii?Q?/2939CoSRTo48W+iJ5qjGl8OjliKlHT+69P/QhWa+dA91Id/xvtAGTUNxfIe?= =?us-ascii?Q?o/72jbbFeUG4kGg/FS7KMHbkl6jygGNEvbn+1H50FDKe4wHm6Fp8fAif2LsR?= =?us-ascii?Q?NdSgU9WyxIkbUwHnZSlWGF7ppzbuRNVOvoiTUrOtHEMihFwX65UwFnm8arTi?= =?us-ascii?Q?sfyPkc6awJG+dTXrEY5Y4c92sywpKh9Me/3X5h5yfrKQQN8LW4wLb2viiOTW?= =?us-ascii?Q?XokydR6JeR0GvP5M+fyrfiZNuTWscF+KZWVDzctF+sNOkcAEwjvbiPF7UOcZ?= =?us-ascii?Q?x0ZpbunNiWLzAO+Brz3HjjMjCY7TfC8vSeiGtRHSWqpywdz8lMt2bC4t5TVd?= =?us-ascii?Q?kFbQyhk48ke2Dl2clJXZhxzm8bnVJUkiKZLv8lvJEtcWD1fEHRYspwKg6p/E?= =?us-ascii?Q?rYF/hvHVheTSUN7USYTIl+bKK8SYPG8f74NocOep2uJbjeSQ2gCT7423F2QI?= =?us-ascii?Q?SVSzY9foQsfNACm1Ni4VHuOdafT77/36pinBiaii/CJgtoPxSP1nqmspGr01?= =?us-ascii?Q?c8LUQvs/r8Qxf6q2l/IjytfNm7tIyxsZHEkhwoCFPNJBByaJAVXIHuWYE987?= =?us-ascii?Q?zzP3EsO3M2UcBUL2aMcTeT8dANnGjFEg5b+SBx6fctgo4bKH/Ux+X25UHkKM?= =?us-ascii?Q?DiHoUw93O49QjWC/po4r9ZzAJcgqG9SYxU3dF5qD7tSZ6XK0tQUUzC5pdKm3?= =?us-ascii?Q?rxnPfnidbz8ctvhAdJZ1ruaGVmDwX9LTQ5tS3GMrzTwbvxVYnqekhbhB/czU?= =?us-ascii?Q?UE/T2IeX6lcD+XGivcDfHl8FoYmYFKWBq4/M5k1jMYC+tjRvllf9qrG+LWSP?= =?us-ascii?Q?1gtDt2o2AIoQ0vSY3Fwc/YjyGKo2ouecO2fwqXDGOLS4Cl1lc+EvJi7xO24R?= =?us-ascii?Q?zC/x5jpf2VF4xVkpq+sH3VLHuh23eKZT0mdi8orgsBm2LlQDoGuWW4B8+4Rf?= =?us-ascii?Q?f+YA62+68NYweVKdPLewZm7jyPo/2V4Jqsuo?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(376014)(36860700013)(1800799024);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:15:15.6796 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 2798cfa4-bc9b-42a0-503a-08ddfa602e4f X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: BL6PEPF0001AB72.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM4PR12MB9071 Content-Type: text/plain; charset="utf-8" The x86 instruction decoder library (insn-eval.c) has been adapted for selftests, but it is not yet compiled and linked into the KVM selftest binaries. Update Makefile.kvm to build the instruction decoder and its dependencies, making them available to x86 KVM selftests. With these changes, the instruction decoder library is fully integrated into the selftest build process and can be used for decoding instructions for emulating MMIO accesses for SEV-ES guests. Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/Makefile.kvm | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selft= ests/kvm/Makefile.kvm index 6dd8675b4861..41aa99e5e0c4 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -22,6 +22,7 @@ LIBKVM_STRING +=3D lib/string_override.c LIBKVM_x86 +=3D lib/x86/apic.c LIBKVM_x86 +=3D lib/x86/handlers.S LIBKVM_x86 +=3D lib/x86/hyperv.c +LIBKVM_x86 +=3D lib/x86/insn-eval.c LIBKVM_x86 +=3D lib/x86/memstress.c LIBKVM_x86 +=3D lib/x86/pmu.c LIBKVM_x86 +=3D lib/x86/processor.c @@ -249,6 +250,15 @@ ifeq ($(ARCH),x86) ifeq ($(shell echo "void foo(void) { }" | $(CC) -march=3Dx86-64-v2 -x c - = -c -o /dev/null 2>/dev/null; echo "$$?"),0) CFLAGS +=3D -march=3Dx86-64-v2 endif +tools_lib_dir :=3D $(top_srcdir)/tools/arch/x86/lib +inat_tables_script =3D $(top_srcdir)/tools/arch/x86/tools/gen-insn-attr-x8= 6.awk +inat_tables_maps =3D $(top_srcdir)/tools/arch/x86/lib/x86-opcode-map.txt +$(shell awk -f $(inat_tables_script) $(inat_tables_maps) > $(tools_lib_dir= )/inat-tables.c) +LIBKVM_x86 +=3D $(tools_lib_dir)/insn.c +LIBKVM_x86 +=3D $(tools_lib_dir)/inat.c +EXTRA_CLEAN +=3D $(tools_lib_dir)/inat-tables.c +EXTRA_CLEAN +=3D $(tools_lib_dir)/insn.o +EXTRA_CLEAN +=3D $(tools_lib_dir)/inat.o endif ifeq ($(ARCH),arm64) tools_dir :=3D $(top_srcdir)/tools --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from BL0PR03CU003.outbound.protection.outlook.com (mail-eastusazon11012016.outbound.protection.outlook.com [52.101.53.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1469830DD29; Tue, 23 Sep 2025 05:15:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.53.16 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604537; cv=fail; b=F+b1RFR96vRYzQ0TxazAmOePDGSHpy+tw7Ib5KU5410/Y5eH4kL6yN5hAZVE6kguGJCfutdwkw+ikrdkyZq8kllvOHZcYW7yU9h6BdNtS+7nK55GvIUSVLvSFgAd0ePR6895472gNk5Fy28Fg/8zBKA8F+lTln/LTAzhogWmg4g= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604537; c=relaxed/simple; bh=UqaM+07P9YA7Tw08pAd/2XhNDqvDAIq2I6A1sDazCVo=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=o3YUg+v2piaW7+feYFi85+au/8YdWVqvIX8YhHENzheD7mOeM4VP1VKmezlu+VPTG5RinSbLcySVQ486W/jSocTId5989QHyeHJh7StyhCxCLZ32fN2aFHccYdXuGQy3QwG3jN5kxnF83x03YlHmDL7Yn9zdrlU5Ck7cgCVTFJM= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=iNnKANXv; arc=fail smtp.client-ip=52.101.53.16 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="iNnKANXv" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=JH7+/JSd7ePwhf9uLTv0QQYQPciBVZOSuW5y3JElxX01JPPzY1yzz/AgvuM96RYreWCP4PJG+BXafuz/EWFQ0zgFDsRPLjbbWSALLulWceBXTINM+5RnDgbu6ls/LuTTa4MU2Dc+smtnXcwO772/uxv6gLzfWGh8vIhOgTmvLts9sgwjhDe+jBYC3FgyrVScvvfcFaE66gn9pMPDZZubgSCuigrISAOsEGJREr4MyrZUOpluWrOcsMYmjeu7yyRc2icR8cNhnGRJmeHzYoxBb/MZqOGwqG9vwx46qNh8uwwj1jUqHop1/np21972ItXnuSWoJBS9jhig3Xq2nz0HCA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=mJs8HpH6e9P6rVzxnitZJxaWNtdX80r5jwo2//Luo8M=; b=XICxiB8PXQBlExPzf2s58tfN3Svs6zFF0530O8C77OAg7vLyiSmzvNTmiox9jQwXAwZeDMt3iScJQSpAxrFFQVCQvLFFhUPMZmd2sGby9yKX0QP7KXXE3sjcI30cKKJ4lyOBKhCHPbu5AAXAVKSBTrrCXtooMGufqNpZns0yeLa/gTwobE2LMiEY/alM2ptqjiXCjvGdaPXCSUIQdTPhvfmWdco1rFTW9an8D6C132VSFCMlRRqrWjGp4Up1nmleGE5u1Jhv4IQmeF9zI6VwTWw4vYfHEom0ogPWonJCjiWhLOVpoUB1h45OOqOUHYuSC545OfRXdI17flQXdhm2AQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=mJs8HpH6e9P6rVzxnitZJxaWNtdX80r5jwo2//Luo8M=; b=iNnKANXv7+NETcGf7MPY7afPB25EICtmmLLGZ3e+Rd/9uZtOYg7FIF8KUTW0HlAfXB8uZruKKt6S20GnqPrL6TEzH5L8n7J5VwQ3cb12RneEuut2BIEmN+iP3Ox/KJPZlI0b9zWVKXi/hiJN3gvG9A3mBpwrxUzDtOCq8e0KMaU= Received: from CH2PR16CA0020.namprd16.prod.outlook.com (2603:10b6:610:50::30) by CYYPR12MB9016.namprd12.prod.outlook.com (2603:10b6:930:c4::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.19; Tue, 23 Sep 2025 05:15:33 +0000 Received: from CH2PEPF0000013B.namprd02.prod.outlook.com (2603:10b6:610:50:cafe::a7) by CH2PR16CA0020.outlook.office365.com (2603:10b6:610:50::30) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:15:33 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF0000013B.mail.protection.outlook.com (10.167.244.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:15:33 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:15:28 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 19/35] KVM: selftests: Add MMIO #VC exception handling for SEV-ES guests Date: Tue, 23 Sep 2025 10:39:26 +0530 Message-ID: <20250923050942.206116-20-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF0000013B:EE_|CYYPR12MB9016:EE_ X-MS-Office365-Filtering-Correlation-Id: 7e41617b-94d1-4002-616b-08ddfa6038db X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|36860700013|376014|82310400026; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?PpgIAaQb6g0OLiR/y5Wpd3E+6yNQj4fHNNIPnBhcC0/GFPNcfvLZsxiIsEc3?= =?us-ascii?Q?v8EYWjEZPInabKUaJVyWtOCyo43wdpDBaVZqtUWNicfTOU1rVAEKpJCNFIEc?= =?us-ascii?Q?y96Dblo03e9GgeBAByWhd+Ys1MTQe9d7WKQpPfAZVnGRZgqUKmsq+KKMM/bv?= =?us-ascii?Q?N7+BcDjQGWxwCeC94IV3UkO3KlPQEN4QREV+wOiR9eMer+Z49hoaaNQS1nXU?= =?us-ascii?Q?zavRdiWkVwoxETZ0vD/8bDltW7kEeK661qf+kv0LK+s/jtiFV5IVg+CF1M0t?= =?us-ascii?Q?Bf1DomLd7FqqaaQRnlxlitcBR0DXmOD2zWiuf4YoryoEK/7o+AGUK3Xycztd?= =?us-ascii?Q?dxMuTpAQbrlmBed5Fn7c1aZcjn5AR+j9h8RIeLv94S7PeirMoeV3OvMZiXFt?= =?us-ascii?Q?QUZlOdBVE7oZI+B/GI1Kh34gaLfQaiJjiJW4IFlxQfjE5pDxOEsDOJiLKOSL?= =?us-ascii?Q?FlZ3w/n5cZBPp+L21jXVQ2X5upTtZXtxx5UQ1fmaPP4pHjYyUCFbHjWfskjJ?= =?us-ascii?Q?IqCxY/oReNt7x56Ln3a8XwsWDVgDNA17Rwe2Im2hO1oHie52e6pSxvht+zmD?= =?us-ascii?Q?GfHh5Noqr2sqYbdREeuRc5ubZNsNpomTlKaStqy/mJWn3zf+DGicjIouootA?= =?us-ascii?Q?R0t27pjiXiL05Dz84mCMKckbbrLoiAPzBO9o3VMIqLEqH5oSmjydUUpep8a0?= =?us-ascii?Q?RXCbY4ZkhGreAyz+noPUxmjrUoGMl/2r/tSLFKmGu5e/FNO1KWOWBEiWgV82?= =?us-ascii?Q?7zDruUDTyW4SwqzHvus5CLPqWtfrViKNxm2ogNkTaMaoMzeu/PUpang7lMa5?= =?us-ascii?Q?HpTL/8Gq3/cnZXyfOG6ZZ3+f4YDKz78oOEX5YIzRb3D9C9z83/ruIuTF0Sp+?= =?us-ascii?Q?ZbnqG4TsGZJywfv+7ZbY7ECQJaK9vXPXRxeDW1M26khJ7aY/aS5ujmxp1ISY?= =?us-ascii?Q?2pY5o0XaYvPxnW0DYDT/wZHQgtvjijxoxvD5ndm+UiEryw8v5T9q4qBSk2cR?= =?us-ascii?Q?m6p2e4/isXvR4h0QDEvOjDFjhNqStkjsFadqVIPS6151s6yQFFF/MZhifF/Y?= =?us-ascii?Q?YCg/1asznqghGOMheKJSJODxbg0LX5tU3b0PZqMSAaVI3ZJJlb16gIYMQizf?= =?us-ascii?Q?mXRlYgfH0O4b/d6BxLHyN6FM9sqHpTOP1MIzw5JzQJWleA22an8qRR9cyhrY?= =?us-ascii?Q?xYUPLgT9fOZPbebqam66dtqz2XlZcvYMc93oOgGDSbxGqIa16YshVSYC4siX?= =?us-ascii?Q?wwPXflsrqHSzmESczzCPhCH+88gyeBvsOLTDzD3Zzjj0IWxuby3/OMAkDImJ?= =?us-ascii?Q?vpiNK9LSmxQF4+Rudl9WFHSyBwHwNlIbwfNSftDARVGQexBg1JoaHI5/DKNI?= =?us-ascii?Q?WLMlW+C7gBVgKdsamY+RbYWqVkfvCF9hYAsKf2lsRmWiibN3lzkCUJ1MiEvS?= =?us-ascii?Q?d4h2sIrxObb4CksJlzTFhLeznFLr4t2qjd5W5oobG3p+643TEdZu04hBmGjz?= =?us-ascii?Q?/dLi1UNeSbr5NSSKvac52/2uRt6HT82r/Z72?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(36860700013)(376014)(82310400026);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:15:33.3642 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 7e41617b-94d1-4002-616b-08ddfa6038db X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF0000013B.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CYYPR12MB9016 Content-Type: text/plain; charset="utf-8" In SEV-ES encrypted guests, access to memory-mapped I/O (MMIO) regions like the local APIC triggers a #VC (Virtualization Exception) with a nested page fault (SVM_EXIT_NPF) exit type. To emulate the MMIO, the guest must provide a #VC handler to process these faults. Implement MMIO handling for SEV-ES guests within the selftest framework. Extend the #VC handler to catch SVM_EXIT_NPF exceptions. Additionally, add a new paravirtualized (PV) interface . This function allows guest code to request an MMIO operation directly via a VMGEXIT, bypassing the more expensive #VC exception path. This is useful for contexts outside the #VC handler where an MMIO access is known to be required. This functionality is a prerequisite for enabling local xAPIC access in SEV-ES selftests, which is required for testing interrupts flow for SEV-ES guests. Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/include/x86/sev.h | 1 + tools/testing/selftests/kvm/lib/x86/sev.c | 259 +++++++++++++++++- 2 files changed, 256 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/kvm/include/x86/sev.h b/tools/testing/= selftests/kvm/include/x86/sev.h index 9c1fe6be5e68..d9794f5c2c16 100644 --- a/tools/testing/selftests/kvm/include/x86/sev.h +++ b/tools/testing/selftests/kvm/include/x86/sev.h @@ -167,4 +167,5 @@ void sev_es_ucall_port_write(uint32_t port, uint64_t da= ta); =20 void sev_es_vc_handler(struct ex_regs *regs); void sev_es_pv_msr_rw(uint64_t msr, uint64_t *data, bool write); +void sev_es_pv_mmio_rw(uint32_t *reg_gpa, uint32_t *data, bool write); #endif /* SELFTEST_KVM_SEV_H */ diff --git a/tools/testing/selftests/kvm/lib/x86/sev.c b/tools/testing/self= tests/kvm/lib/x86/sev.c index 57ae5a388b8c..610342b8e479 100644 --- a/tools/testing/selftests/kvm/lib/x86/sev.c +++ b/tools/testing/selftests/kvm/lib/x86/sev.c @@ -1,7 +1,9 @@ // SPDX-License-Identifier: GPL-2.0-only #include #include +#include =20 +#include "insn-eval.h" #include "sev.h" #include "linux/bitmap.h" #include "svm.h" @@ -14,6 +16,8 @@ =20 #define SW_EXIT_CODE_IOIO 0x7b #define SW_EXIT_CODE_MSR 0x7c +#define SVM_VMGEXIT_MMIO_READ 0x80000001 +#define SVM_VMGEXIT_MMIO_WRITE 0x80000002 =20 struct ghcb_entry { struct ghcb ghcb; @@ -314,10 +318,10 @@ static uint64_t setup_exitinfo1_portio(uint32_t port) =20 #define GHCB_MSR_REG_GPA_REQ 0x012 #define GHCB_MSR_REG_GPA_REQ_VAL(v) \ - /* GHCBData[63:12] */ \ - (((u64)((v) & GENMASK_ULL(51, 0)) << 12) | \ - /* GHCBData[11:0] */ \ - GHCB_MSR_REG_GPA_REQ) + /* GHCBData[63:12] */ \ + (((u64)((v) & GENMASK_ULL(51, 0)) << 12) | \ + /* GHCBData[11:0] */ \ + GHCB_MSR_REG_GPA_REQ) =20 static void register_ghcb_page(uint64_t ghcb_gpa) { @@ -423,6 +427,250 @@ static void sev_es_vc_msr_handler(struct ex_regs *reg= s) ghcb_free(entry); } =20 +static void __sev_es_hv_mmio_rw(struct ghcb_entry *entry, uint32_t *reg_gp= a, + unsigned int bytes, bool write) +{ + uint64_t exitinfo1 =3D (uint64_t)reg_gpa; + struct ghcb *ghcb =3D &entry->ghcb; + int ret; + + if (write) + ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_MMIO_WRITE); + else + ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_MMIO_READ); + ghcb_set_sw_exit_info_1(ghcb, exitinfo1); + ghcb_set_sw_exit_info_2(ghcb, bytes); + ghcb_set_sw_scratch(ghcb, entry->gpa + offsetof(struct ghcb, shared_buffe= r)); + do_vmg_exit(entry->gpa); + ret =3D ghcb->save.sw_exit_info_1 & 0xffffffff; + __GUEST_ASSERT(!ret, "mmio %s failed, ret: %d", + write ? "write" : "read", ret); +} + +void sev_es_pv_mmio_rw(uint32_t *reg_gpa, uint32_t *data, bool write) +{ + struct ghcb_entry *entry; + struct ghcb *ghcb; + + entry =3D ghcb_alloc(); + ghcb =3D &entry->ghcb; + + register_ghcb_page(entry->gpa); + + if (write) + memcpy(&ghcb->shared_buffer, data, sizeof(*data)); + + __sev_es_hv_mmio_rw(entry, reg_gpa, sizeof(*data), write); + + if (!write) + memcpy(data, &ghcb->shared_buffer, sizeof(*data)); + + ghcb_free(entry); +} + +static void do_mmio(struct ghcb_entry *entry, struct ex_regs *regs, + struct insn *insn, unsigned int bytes, bool read) +{ + void *ref =3D insn_get_addr_ref(insn, regs); + + register_ghcb_page(entry->gpa); + __sev_es_hv_mmio_rw(entry, ref, bytes, !read); +} + +static int vc_write_mem(struct ex_regs *regs, struct insn *insn, + unsigned char *dst, unsigned char *buf, size_t size) +{ + uint8_t *buffer =3D (uint8_t *)buf; + + switch (size) { + case 1: { + uint8_t *target =3D (uint8_t *)dst; + + memcpy(target, buffer, 1); + break; + } + case 2: { + uint16_t *target =3D (uint16_t *)dst; + + memcpy(target, buffer, 2); + break; + } + case 4: { + uint32_t *target =3D (uint32_t *)dst; + + memcpy(target, buffer, 4); + break; + } + case 8: { + uint64_t *target =3D (uint64_t *)dst; + + memcpy(target, buffer, 8); + break; + } + default: + return -1; + } + + return 0; +} + +static int vc_read_mem(struct ex_regs *regs, struct insn *insn, + unsigned char *src, unsigned char *buf, size_t size) +{ + switch (size) { + case 1: { + uint8_t *s =3D (uint8_t *)src; + + memcpy(buf, s, 1); + break; + } + case 2: { + uint16_t *s =3D (uint16_t *)src; + + memcpy(buf, s, 1); + break; + } + case 4: { + uint32_t *s =3D (uint32_t *)src; + + memcpy(buf, s, 1); + break; + } + case 8: { + uint64_t *s =3D (uint64_t *)src; + + memcpy(buf, s, 1); + break; + } + default: + return -1; + } + + return 0; +} + + +static int vc_handle_mmio_movs(struct ex_regs *regs, struct insn *insn, un= signed int bytes) +{ + unsigned long ds_base, es_base; + unsigned char *src, *dst; + unsigned char buffer[8]; + int ret; + bool rep; + int off; + + ds_base =3D insn_get_seg_base(regs, INAT_SEG_REG_DS); + es_base =3D insn_get_seg_base(regs, INAT_SEG_REG_ES); + + if (ds_base =3D=3D -1L || es_base =3D=3D -1L) + return -1; + + src =3D ds_base + (unsigned char *)regs->rsi; + dst =3D es_base + (unsigned char *)regs->rdi; + + ret =3D vc_read_mem(regs, insn, src, buffer, bytes); + if (ret !=3D 0) + return ret; + + ret =3D vc_write_mem(regs, insn, dst, buffer, bytes); + if (ret !=3D 0) + return ret; + +#define X86_EFLAGS_DF (1UL << 10) + if (regs->rflags & X86_EFLAGS_DF) + off =3D -bytes; + else + off =3D bytes; + + regs->rsi +=3D off; + regs->rdi +=3D off; + + rep =3D insn_has_rep_prefix(insn); + if (rep) + regs->rcx -=3D 1; + + if (!rep || regs->rcx =3D=3D 0) + return 0; + else + return 1; +} + +static void sev_es_vc_mmio_handler(struct ex_regs *regs) +{ + char buffer[MAX_INSN_SIZE]; + struct ghcb_entry *entry; + enum insn_mmio_type mmio; + unsigned long *reg_data; + unsigned int bytes; + struct ghcb *ghcb; + uint8_t sign_byte; + struct insn insn; + int ret; + + memcpy(buffer, (uint8_t *)regs->rip, MAX_INSN_SIZE); + ret =3D insn_decode(&insn, buffer, MAX_INSN_SIZE, INSN_MODE_64); + + if (ret < 0) + __GUEST_ASSERT(0, "Instruction decode failed, ret: %d\n", ret); + + mmio =3D insn_decode_mmio(&insn, (int *)&bytes); + __GUEST_ASSERT(!(mmio =3D=3D INSN_MMIO_DECODE_FAILED), " MMIO decode fail= ed\n"); + + if (mmio !=3D INSN_MMIO_WRITE_IMM && mmio !=3D INSN_MMIO_MOVS) { + reg_data =3D insn_get_modrm_reg_ptr(&insn, regs); + __GUEST_ASSERT(reg_data, "insn_get_modrm_reg_ptr failed\n"); + } + + entry =3D ghcb_alloc(); + ghcb =3D &entry->ghcb; + + switch (mmio) { + case INSN_MMIO_WRITE: + memcpy(ghcb->shared_buffer, reg_data, bytes); + do_mmio(entry, regs, &insn, bytes, false); + break; + case INSN_MMIO_WRITE_IMM: + memcpy(ghcb->shared_buffer, insn.immediate1.bytes, bytes); + do_mmio(entry, regs, &insn, bytes, false); + break; + case INSN_MMIO_READ: + do_mmio(entry, regs, &insn, bytes, true); + if (bytes =3D=3D 4) + *reg_data =3D 0; + memcpy(reg_data, ghcb->shared_buffer, bytes); + break; + case INSN_MMIO_READ_ZERO_EXTEND: + do_mmio(entry, regs, &insn, bytes, true); + memset(reg_data, 0, insn.opnd_bytes); + memcpy(reg_data, ghcb->shared_buffer, bytes); + break; + case INSN_MMIO_READ_SIGN_EXTEND: + do_mmio(entry, regs, &insn, bytes, true); + if (bytes =3D=3D 1) { + uint8_t *val =3D (uint8_t *)ghcb->shared_buffer; + + sign_byte =3D (*val & 0x80) ? 0xff : 0x00; + } else { + uint16_t *val =3D (uint16_t *)ghcb->shared_buffer; + + sign_byte =3D (*val & 0x8000) ? 0xff : 0x00; + } + + /* Sign extend based on operand size */ + memset(reg_data, sign_byte, insn.opnd_bytes); + memcpy(reg_data, ghcb->shared_buffer, bytes); + break; + case INSN_MMIO_MOVS: + ret =3D vc_handle_mmio_movs(regs, &insn, bytes); + break; + default: + break; + } + + ghcb_free(entry); + regs->rip +=3D insn.length; +} + void sev_es_vc_handler(struct ex_regs *regs) { uint64_t exit_code =3D regs->error_code; @@ -433,6 +681,9 @@ void sev_es_vc_handler(struct ex_regs *regs) /* rdmsr/wrmsr instruction size =3D 2 */ regs->rip +=3D 2; break; + case SVM_EXIT_NPF: + sev_es_vc_mmio_handler(regs); + break; default: __GUEST_ASSERT(0, "No VC handler\n"); } --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from CH1PR05CU001.outbound.protection.outlook.com (mail-northcentralusazon11010033.outbound.protection.outlook.com [52.101.193.33]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 292FE30DD29; Tue, 23 Sep 2025 05:15:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.193.33 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604556; cv=fail; b=VPjrPZsKAnsEzvgAwQU98DuZ70oSzaQREtkmPv0XSisQS+u/Uhip01puwq6cAl/OCQSFVx53A7ArWOnLwRclZP57Z+/r/LMqbxGnZHQqWw1vXX3HyAIEJF2ptfCczSwhrV0Jt7FM1nOsCRYa6PmLtxdgI4v8YA4+uqUGTmigqBs= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604556; c=relaxed/simple; bh=AgXPabw3DDbaE0F5W/SEvErDlrK9zQ66sDJKfUixsTQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=eti0lwQfUaQ8Wk6e01mkc1HjB33C5eccPSt8uS6J+i2JeQqionPS1eEev6aNASJXOPGHmGnTS+iSiRu6dg/4hiVcUpO/wlDiqsf5ZxIngac1PwInU20DsInITiGtTim6c7QM1atfIry0LdSjqL2WB+A1W71Q2N2MpuQ0WIyrC/k= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=iQ9dQkTQ; arc=fail smtp.client-ip=52.101.193.33 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="iQ9dQkTQ" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=K63WZaqDORGwO6n7fGzFs3tnlyAPrq3XZ3mG3ek122/7en2bbt3W1yvxFH9O3HWqVfQ0ea8VyEHIjj0UA+e+feKpkk4mUirks9+kh+5tpr0prQMptTTQfnbOyG6WJpqD9rlEGK52MFOzUS/QFCc3kX11wcycNZ4jM5rH/w9fz4jNGjMq2vyeLa8hBiEKHs7SGVpyMX+PLCA5OjVMu25c6qoS5sKo1GlN3olRk4660WgTkR8Wydd6ZqfSQjQSiifzZZ4Z9555SD2egZneMIY3luLJJpW4ic4H/faiY7tqT+TDByRWTliePIhar1L5m9TX9UxyK7JvBPHeoAFbUiLsrQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=b4EW6KnXNPeHrTO6otr1T7qE1RE9/+V98mwK327+xFY=; b=XQgor+cGr2wUntv15OGTLdetrHOFX1a1EbsADOXfksI+HFDEn5w21HmpeOOrnKZoVDapjbmqUbVcULn93jbKMXZDKtpLK1B6L/CaSNxUmILLi88Vck/C8+ozZiQUF9TagG5z4zydd7aR32D5t2XKxoLTxU5rtXxyqv10GjAfkSzE7fdWlvY8Ke13XLrn6RjpOgr85LCS/brDfhQl22Y3sWvEcWr3R2kVRM05IhaBFNDGp3vunD3bdJD9JRQPqA+4eEy5gReuDId+D7A58yKDqXom7a2JGQLm2OhwMI6QmgPnVi8S0wdJvkoi4fo5FL7MqNH1gXZZOONAOaQnGuMviw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=b4EW6KnXNPeHrTO6otr1T7qE1RE9/+V98mwK327+xFY=; b=iQ9dQkTQ56yBZeLskPFUOMGeTMF/z2VW39EQbERA0UQicIJYWnPV7FnkvdWrf/drShej70KUVzAk8YLRdCfDVDWKp2htY1bJyCjLqXqgGNhNoQroj/yUBUDSumEv4mnP0lG+ZekK6yiJzgG9cjhy8O/aesKLWE5vEUBHrr+7cwk= Received: from CH5P223CA0012.NAMP223.PROD.OUTLOOK.COM (2603:10b6:610:1f3::26) by CH2PR12MB4039.namprd12.prod.outlook.com (2603:10b6:610:a8::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.20; Tue, 23 Sep 2025 05:15:51 +0000 Received: from CH2PEPF0000013F.namprd02.prod.outlook.com (2603:10b6:610:1f3:cafe::cd) by CH5P223CA0012.outlook.office365.com (2603:10b6:610:1f3::26) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:15:51 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF0000013F.mail.protection.outlook.com (10.167.244.71) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:15:51 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:15:46 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 20/35] KVM: selftests: Add instruction decoding for movabs instructions Date: Tue, 23 Sep 2025 10:39:27 +0530 Message-ID: <20250923050942.206116-21-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF0000013F:EE_|CH2PR12MB4039:EE_ X-MS-Office365-Filtering-Correlation-Id: bb52b2a7-0398-4cc3-2123-08ddfa604366 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|376014|36860700013|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?rnotQud+MyqmAXK2yUwMiMQEGS0LPqQhoLedM4vI+MFms9mwdSxqqmmbt5be?= =?us-ascii?Q?/SqxcnEzf47Hr0w07N2xkZRyE6YURSu6Z93HglAZe29rCSjnGBrbKcm8uhPc?= =?us-ascii?Q?BiJddaaLDObHOkzudtT8x7Oj3Pp4H+oABzk7UQnEhBpyquawtVxIEAsgvDyx?= =?us-ascii?Q?VmgGvAEj978vBOGuaPjGJ1/B9omDJjVsZzctcoMKKjsI2JyFf1byM6vnA4dX?= =?us-ascii?Q?4il7+h9A/kWh9SdWZbOqovIfhZEzaJBFTIMpN/Cc/oxRi94nWWCgtfP9Wrz8?= =?us-ascii?Q?JSNN5GpL1i7kKojjjU82LdgQJqp+lvVHBg5Kpm6jdIzSP7wgXm9HSIqRGkqM?= =?us-ascii?Q?z4xqu1E9hNhMi5tNSEX8PO2Xs9hLlyS1yAQ35mP612k55+diB2nqT5ANhuZt?= =?us-ascii?Q?rXkC6ctl1E6rbgjXFOyVhizL3Ko9WCOm1NhxtegWuaZfa//QhbK2axp0kgHX?= =?us-ascii?Q?NWnkJs4TRlX+BykGvC/YDZnUZLD6ZsVgCFHl23ci9Pf/lGLB82UDC7v1BW5s?= =?us-ascii?Q?WZtwaxOWDYSJ3GZJQRi48Ph2wpMsgwivk5hpAlV0dYXl3PQtG/dujOPXwSRM?= =?us-ascii?Q?88eG4T8/fMer8mSdX2XYcQ2AplwZnas+dU4n3Fy826Do994Owx8EORPkwDrn?= =?us-ascii?Q?gi2bIp5yAwd7DKbEgLx+P1UXSMCTLWDYz+L+tJvYYsWN5TtHqEkaEaILqyP4?= =?us-ascii?Q?FtuzrWeD0yoxKA6mq+9KLZktEcdeo30+JCsBaPEVZ0OtQckkC6RW4RepzRCo?= =?us-ascii?Q?FhsAjdaPvs8Q3eABWKk/PaBx13tvT7Huz1dDARqtsZGFzo/fFd9e5vDBIAGb?= =?us-ascii?Q?zSgE4JkPjZ23uJ6tjUKhVSfTPw0HfoPfIwMNlCCjLEVNta4UuIdmh2DOl8Pb?= =?us-ascii?Q?yzBAaUl9CwlbqpfaBscGwt4CEu6wkhwfrF/JTRx6SlYNQuAN1QxAM2tGi2po?= =?us-ascii?Q?w8aFXpA3zo1fVlvOzaPlgdnDSquKHm7Qu2Fm4tNWzKP2tnOEK15aRyCjWxDB?= =?us-ascii?Q?JIUdQ+Kq2zyVsxHLGzuwSyd7C2JQds/giYM6mcbxzbKQF6y+wXIbbIN5+9Mz?= =?us-ascii?Q?s1EsnL+0yTDAxZcnlkyOQZklYuF0iGNDrEsmIl1hWz8HtvbMZet4DR7NLgkf?= =?us-ascii?Q?HgtAuzouhbMgzES9LdN761KCd7IPBmPo3ZpvveIiX65dB4ahtHeCuioo/8Zt?= =?us-ascii?Q?I7vXhgMlsTfo22ngcNTO3tdNp1muVOPv1aVOy4CDiMAsoEko87INNd6c5BdR?= =?us-ascii?Q?YMbQd/nrfTB2enCitjoQALrJmmiyE3H2/q4swAe9B04UoWZmMKys2DWGIW2L?= =?us-ascii?Q?O4kKReW/R1UkK4aofOIHwPatpMRB1UOLm7oN10te1diozLvJZ+ttXQ7rlii2?= =?us-ascii?Q?zbBkDn9Xtrgttcn32U0T85G4HQ//dslL8s+n5vb+pHWSWigeBLfjpcFHPHuU?= =?us-ascii?Q?kXRV9z7tKcVhe4830AME5cLJyDAt4FrW+3i7mMB6648fWxiCO3vNS+Awircs?= =?us-ascii?Q?DKlcd1cynw25T4dZhWIaNJ7adwfVv4pqRCjb?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(376014)(36860700013)(1800799024);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:15:51.0507 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: bb52b2a7-0398-4cc3-2123-08ddfa604366 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF0000013F.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH2PR12MB4039 Content-Type: text/plain; charset="utf-8" Compilers can generate movabs instructions for MMIO accesses, when accessing fixed addresses like the local APIC base. The movabs instruction is unique in that it moves data between the accumulator (RAX) and a memory location specified by an absolute 64-bit address encoded directly in the instruction stream. The existing MMIO #VC handler in the SEV-ES selftest was unable to process these instructions because its decoding logic relied on ModR/M and SIB bytes, which movabs does not use. This would cause MMIO emulation to fail for such instructions. Extend insn_decode_mmio() to recognize the movabs opcodes (0xa1, 0xa3). This allows the SEV-ES #VC handler to correctly emulate movabs instructions, improving the robustness of MMIO testing for features like the xAPIC. Signed-off-by: Neeraj Upadhyay --- .../selftests/kvm/include/x86/insn-eval.h | 2 ++ .../testing/selftests/kvm/lib/x86/insn-eval.c | 8 +++++ tools/testing/selftests/kvm/lib/x86/sev.c | 35 ++++++++++++++----- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/tools/testing/selftests/kvm/include/x86/insn-eval.h b/tools/te= sting/selftests/kvm/include/x86/insn-eval.h index 0547b622295a..911b7f4e5473 100644 --- a/tools/testing/selftests/kvm/include/x86/insn-eval.h +++ b/tools/testing/selftests/kvm/include/x86/insn-eval.h @@ -35,10 +35,12 @@ enum insn_mmio_type { INSN_MMIO_DECODE_FAILED, INSN_MMIO_WRITE, INSN_MMIO_WRITE_IMM, + INSN_MMIO_WRITE_MOV_ABS, INSN_MMIO_READ, INSN_MMIO_READ_ZERO_EXTEND, INSN_MMIO_READ_SIGN_EXTEND, INSN_MMIO_MOVS, + INSN_MMIO_READ_MOV_ABS, }; =20 enum insn_mmio_type insn_decode_mmio(struct insn *insn, int *bytes); diff --git a/tools/testing/selftests/kvm/lib/x86/insn-eval.c b/tools/testin= g/selftests/kvm/lib/x86/insn-eval.c index 369530badba9..9d370b1cef84 100644 --- a/tools/testing/selftests/kvm/lib/x86/insn-eval.c +++ b/tools/testing/selftests/kvm/lib/x86/insn-eval.c @@ -1224,6 +1224,14 @@ enum insn_mmio_type insn_decode_mmio(struct insn *in= sn, int *bytes) break; } break; + case 0xa1: + type =3D INSN_MMIO_READ_MOV_ABS; + *bytes =3D insn->opnd_bytes; + break; + case 0xa3: + type =3D INSN_MMIO_WRITE_MOV_ABS; + *bytes =3D insn->opnd_bytes; + break; } =20 return type; diff --git a/tools/testing/selftests/kvm/lib/x86/sev.c b/tools/testing/self= tests/kvm/lib/x86/sev.c index 610342b8e479..1e0719dfd6b0 100644 --- a/tools/testing/selftests/kvm/lib/x86/sev.c +++ b/tools/testing/selftests/kvm/lib/x86/sev.c @@ -469,9 +469,11 @@ void sev_es_pv_mmio_rw(uint32_t *reg_gpa, uint32_t *da= ta, bool write) } =20 static void do_mmio(struct ghcb_entry *entry, struct ex_regs *regs, - struct insn *insn, unsigned int bytes, bool read) + struct insn *insn, unsigned int bytes, bool read, + void *ref) { - void *ref =3D insn_get_addr_ref(insn, regs); + if (!ref) + ref =3D insn_get_addr_ref(insn, regs); =20 register_ghcb_page(entry->gpa); __sev_es_hv_mmio_rw(entry, ref, bytes, !read); @@ -600,11 +602,12 @@ static void sev_es_vc_mmio_handler(struct ex_regs *re= gs) char buffer[MAX_INSN_SIZE]; struct ghcb_entry *entry; enum insn_mmio_type mmio; - unsigned long *reg_data; + unsigned long *reg_data =3D NULL; unsigned int bytes; struct ghcb *ghcb; uint8_t sign_byte; struct insn insn; + void *abs_ref; int ret; =20 memcpy(buffer, (uint8_t *)regs->rip, MAX_INSN_SIZE); @@ -616,7 +619,9 @@ static void sev_es_vc_mmio_handler(struct ex_regs *regs) mmio =3D insn_decode_mmio(&insn, (int *)&bytes); __GUEST_ASSERT(!(mmio =3D=3D INSN_MMIO_DECODE_FAILED), " MMIO decode fail= ed\n"); =20 - if (mmio !=3D INSN_MMIO_WRITE_IMM && mmio !=3D INSN_MMIO_MOVS) { + if (mmio =3D=3D INSN_MMIO_WRITE_MOV_ABS || mmio =3D=3D INSN_MMIO_READ_MOV= _ABS) { + reg_data =3D ®s->rax; + } else if (mmio !=3D INSN_MMIO_WRITE_IMM && mmio !=3D INSN_MMIO_MOVS) { reg_data =3D insn_get_modrm_reg_ptr(&insn, regs); __GUEST_ASSERT(reg_data, "insn_get_modrm_reg_ptr failed\n"); } @@ -627,25 +632,37 @@ static void sev_es_vc_mmio_handler(struct ex_regs *re= gs) switch (mmio) { case INSN_MMIO_WRITE: memcpy(ghcb->shared_buffer, reg_data, bytes); - do_mmio(entry, regs, &insn, bytes, false); + do_mmio(entry, regs, &insn, bytes, false, NULL); break; case INSN_MMIO_WRITE_IMM: memcpy(ghcb->shared_buffer, insn.immediate1.bytes, bytes); - do_mmio(entry, regs, &insn, bytes, false); + do_mmio(entry, regs, &insn, bytes, false, NULL); + break; + case INSN_MMIO_WRITE_MOV_ABS: + abs_ref =3D (void *)*(uint64_t *)((uint8_t *)regs->rip + 1); + memcpy(ghcb->shared_buffer, reg_data, bytes); + do_mmio(entry, regs, &insn, bytes, false, abs_ref); break; case INSN_MMIO_READ: - do_mmio(entry, regs, &insn, bytes, true); + do_mmio(entry, regs, &insn, bytes, true, NULL); + if (bytes =3D=3D 4) + *reg_data =3D 0; + memcpy(reg_data, ghcb->shared_buffer, bytes); + break; + case INSN_MMIO_READ_MOV_ABS: + abs_ref =3D (void *)*(uint64_t *)((char *)regs->rip + 1); + do_mmio(entry, regs, &insn, bytes, true, abs_ref); if (bytes =3D=3D 4) *reg_data =3D 0; memcpy(reg_data, ghcb->shared_buffer, bytes); break; case INSN_MMIO_READ_ZERO_EXTEND: - do_mmio(entry, regs, &insn, bytes, true); + do_mmio(entry, regs, &insn, bytes, true, NULL); memset(reg_data, 0, insn.opnd_bytes); memcpy(reg_data, ghcb->shared_buffer, bytes); break; case INSN_MMIO_READ_SIGN_EXTEND: - do_mmio(entry, regs, &insn, bytes, true); + do_mmio(entry, regs, &insn, bytes, true, NULL); if (bytes =3D=3D 1) { uint8_t *val =3D (uint8_t *)ghcb->shared_buffer; =20 --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from SN4PR2101CU001.outbound.protection.outlook.com (mail-southcentralusazon11012013.outbound.protection.outlook.com [40.93.195.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 647F02E9741; Tue, 23 Sep 2025 05:16:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.195.13 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604577; cv=fail; b=PWSuQ8XBLmQtnh+qj3a1Cf/IUT26dJYMrQzUaTzf5+VvPwXSu/viujPkCZkgAtvPDlvNfuDhwu1FURKxbCvOEyErdCy0/ikAXt9nwS7vIw9eaLe/hGzIw+fdP6niGqvmemtN9R3fA3QpkHscdDfl+9FMlg7iN2F7jbF2GaYLHVc= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604577; c=relaxed/simple; bh=NgL8ZpjqU55F1d3K0/Ys0H4gYPM3wi+kC+6CNqW3Ggs=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=cx67jd2/UhJ/J860/hSa8ek/9LCKlqQd0PvHJh8pvQ0X3YLWlj6YhNt2uca7dKG26z96iMS0sQWrHn0i8sXiab4tWHyCDamnYFbrKZxLKOLJSMat8H001tUoWZeAA0IfIj4tbzsty9gp6Dl3PMF9bPyJ2xJn8YpXevVLgh/+aJA= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=ddPNU3yc; arc=fail smtp.client-ip=40.93.195.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="ddPNU3yc" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=wZMl6NL8FtIBHsvz7FFVCvKK6UqvOy30bZ/zuUlQaQB12Bq/2BeurlIR4ER2vlRA6X5uPrgM3j41RZank0KMxytXKoJ5XCvsrKGk4kmqlOjYcj3LwlpsYx6uixhGSdzHvCo0Oevxf2fcy4b7N4xQcG1UrYCmVijtZcOBz3yS2jFA7xJNQ7xkgVvoLIDgjxSN6ulI37ZQU2g7fS8odmYFT3aOr9QaNT44lA3XaKjUgzQ8siZIidtQqJWvfW32Qz2H43zU/ONN2Bn3efO7guWAJCd0TptRN/COJgjYEGYJ7VVEF2nm78HpPC30mQM0K8BmRobebJSdAeMZSKgo/xMXiw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=EH6eC59Wn+K/0tK/CRZhm+gtcNjeYclYdoBj4dr8FNs=; b=tKQdb6J1Pe+0M+J6bRWbxcTwyVMxm9F+BSw3GMJwdw4/CagWKHpymnx8UxXSKgrKGJw6uQCPgk2Rnre4kwgFKdsADlZmuC6hoeaa3+wIlmmv1VCvj14K1D1CFO4iIC2R0Xe8DOiBYuRw1GpXRKcxMvcta+Olt26a2GzLz+QBsBn3zq3TVpAiQw7oHGZkdp7Wj1PRwhOcYcIsW0n91Lj7ufK5kJ+1p/RALpEKa07KHxwNqktbxwriHa7fCGpt6zR5iG48Szf+yDft3AdKO8USomh1M+vF80T/kiKpHWG4Szkw6ohlXdcDnp6ZwGzXtNWIxl8Sdv3a/BSYEoFoiqb8bQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=EH6eC59Wn+K/0tK/CRZhm+gtcNjeYclYdoBj4dr8FNs=; b=ddPNU3ycQANxW6i3fdft1/q8DUkrtugaRhGLJ2QvSx4Ibg9+KBVWo3gnjBYRJWIHxwLdC9GLmm8uo4e/RiAcndSNWYroDXYAw8wyv6LJ2s0FEluTO8PYjJSjs912TCpbbq6PA3c1NvyrQZBX34EUC+al6sWZ71yUq0tl51paR3w= Received: from CH2PR08CA0018.namprd08.prod.outlook.com (2603:10b6:610:5a::28) by LV8PR12MB9407.namprd12.prod.outlook.com (2603:10b6:408:1f9::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.20; Tue, 23 Sep 2025 05:16:11 +0000 Received: from CH2PEPF0000013C.namprd02.prod.outlook.com (2603:10b6:610:5a:cafe::3a) by CH2PR08CA0018.outlook.office365.com (2603:10b6:610:5a::28) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.19 via Frontend Transport; Tue, 23 Sep 2025 05:16:09 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF0000013C.mail.protection.outlook.com (10.167.244.73) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:16:10 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:16:03 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 21/35] KVM: selftests: Add SEV guest support in xapic_state_test Date: Tue, 23 Sep 2025 10:39:28 +0530 Message-ID: <20250923050942.206116-22-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF0000013C:EE_|LV8PR12MB9407:EE_ X-MS-Office365-Filtering-Correlation-Id: 362a5ab2-13ef-4fe8-cd88-08ddfa604f3c X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|1800799024|36860700013|376014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?eNKRxRLThDt84Vo57yy66kmoTxQCBMdrFavnOTA6RKU/Ts/Jg8djb9d29r8c?= =?us-ascii?Q?yPr6QCS24kKdNeVjX4A4D6SGhCQls2d5QwLBPKOZBxy7qs5+BHV5qx78bjx6?= =?us-ascii?Q?V2B/zBcg7mbzBmfKnrT6zaINCQWiMfv6ihf8t709i+kE+qFdVOf6Na9qqMrG?= =?us-ascii?Q?+OqolrYQW5fLv2Jj/YfwpeIB+tqBi5fnP0p38BAZ2MQn1zy8uBWupHcrrcRJ?= =?us-ascii?Q?VT60jf9QpEwUfualSQs+OE/7reDFhpuPSe6FaoiBJ8a6fzC6SUANKyXhKMGP?= =?us-ascii?Q?hS48lUY9ZDo6LL/K4uJfbBeGANMUe5IAj1k4Pew6QRIIfq3TabD6KjWUnLNr?= =?us-ascii?Q?zMJzHS8mFEOzqyuWFWW6QeoZJ90u/XAs/ypzFwhQeVS5Y13ssrEsQgcE5DoC?= =?us-ascii?Q?knZN39PDRV1h5qdppCbD1V1Cxsa+YIR0YVacE/k3CTZ+sMOnsOk5VqNCaZ5r?= =?us-ascii?Q?m8aOVF2irVOUmQj1Jczhlg307OKtFISiJa+vzd1V5nH0AZBdf5UHn1ZJAPw0?= =?us-ascii?Q?VP+hMnr5AOZFIGo13IS8IC8unFg9q+l40NZq4hm2X34dRQfYuKMJn88H8aBm?= =?us-ascii?Q?d0ReV8DepEyH9GBGHJYWjcwfOKCzUZVKrZSM0BrXts99cc2AsQuEFIqTKAwe?= =?us-ascii?Q?zLiyGDPBK/zQPyOR2ZFZhnYOQdpfG80FMvanRNRFPVPc67abznkr64G4MHIz?= =?us-ascii?Q?pqPgiF9BmhsY2XudQDsXOVln4UE5rE7zw4kZX3h8n1iK6YhxqYFjC4lx+AxQ?= =?us-ascii?Q?Wxwjwqt92GXqtHEbC8GnwyBl9AmljkP9qGjroZxwvWva94A9PHln4dFpuefN?= =?us-ascii?Q?UgsWRD57TWJ0zkffnbRspXhF19+ptozMMgRWeFtmUyeKELNU4sEtkXycwZym?= =?us-ascii?Q?V8Uzg7ht82XkugnvLi40nyzRXZ8M8FHzFQUvtf70wlSzenvzGQKHP7ENoxZM?= =?us-ascii?Q?CBSHuEnPPFvwIv2gVbFyW6xftGC2prtVSNQiSBgf5zz68NqiI7I3MyodKvxc?= =?us-ascii?Q?cMbg7Nf6Qrah5AHSBJGhTf43uDnjjOpy1zsRprc/CdTTce2yP8q0ctyj5YiG?= =?us-ascii?Q?o3vqbGQkpISikNcNeiu7DKuSfkpMKFAZYgkp4IW5UApGyU9GgSKywOZBVgrc?= =?us-ascii?Q?Ajm7ytUuKKegQ8XgBmg+7RxCuqzxHzQdfyOkuoDdo2SiYAQ0XQsnNoczo9SN?= =?us-ascii?Q?R0MNV9k6oEA7zYXmroDujN5e5+G0tflA/givz7iQBDC5heA49b3WKNZZp9ID?= =?us-ascii?Q?wGXss0iqv+BRQSDoTTFDrEZcbDidg5G5URU1XgTDbAxUSltuSCWjVapTZBZt?= =?us-ascii?Q?v/J3olV+FrSnLQva/0V3ZKZZWkwpbW03cRKSGnswjr0ZdIuULfu5bGPde+6w?= =?us-ascii?Q?CgrQGXGlpvdivVNgJDvd9tfppcauFr5FW+nvKmwoDS2J0dcL3/ZGYZFo9Y8R?= =?us-ascii?Q?WNmH/L1UupmJWm3YaWdUZoBwO63hqD7Th+y9kDN9wlNIsTbjY8/u91/bOrWB?= =?us-ascii?Q?0To/+mU20WZz80IB4FR0in2ynpQxU4eaZI3+?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(1800799024)(36860700013)(376014);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:16:10.9143 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 362a5ab2-13ef-4fe8-cd88-08ddfa604f3c X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF0000013C.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: LV8PR12MB9407 Content-Type: text/plain; charset="utf-8" The xapic_state_test validates the behavior of the local APIC across different states and modes (xAPIC vs. x2APIC). Previously, this test only ran on standard, unencrypted VMs. With the recent addition of a #VC handler to emulate MMIO accesses for SEV-ES guests, the necessary infrastructure is in place to test APIC functionality within encrypted environments. Extend xapic_state_test to support SEV, SEV-ES, and SNP guests. This provides crucial regression testing for APIC functionality in these confidential computing environments. The test functions are refactored to handle the new VM setup flow, enabling existing APIC tests to run transparently on encrypted guests. Signed-off-by: Neeraj Upadhyay --- .../selftests/kvm/x86/xapic_state_test.c | 117 ++++++++++++++++-- 1 file changed, 109 insertions(+), 8 deletions(-) diff --git a/tools/testing/selftests/kvm/x86/xapic_state_test.c b/tools/tes= ting/selftests/kvm/x86/xapic_state_test.c index fdebff1165c7..91f593ef22dc 100644 --- a/tools/testing/selftests/kvm/x86/xapic_state_test.c +++ b/tools/testing/selftests/kvm/x86/xapic_state_test.c @@ -9,6 +9,7 @@ #include "kvm_util.h" #include "processor.h" #include "test_util.h" +#include "sev.h" =20 struct xapic_vcpu { struct kvm_vcpu *vcpu; @@ -160,6 +161,27 @@ static void __test_apic_id(struct kvm_vcpu *vcpu, uint= 64_t apic_base) expected, apic_id); } =20 +static inline bool is_sev_vm_type(int type) +{ + return type =3D=3D KVM_X86_SEV_VM || + type =3D=3D KVM_X86_SEV_ES_VM || + type =3D=3D KVM_X86_SNP_VM; +} + +static inline uint64_t get_sev_policy(int vm_type) +{ + switch (vm_type) { + case KVM_X86_SEV_VM: + return SEV_POLICY_NO_DBG; + case KVM_X86_SEV_ES_VM: + return SEV_POLICY_ES; + case KVM_X86_SNP_VM: + return snp_default_policy(); + default: + return 0; + } +} + /* * Verify that KVM switches the APIC_ID between xAPIC and x2APIC when user= space * stuffs MSR_IA32_APICBASE. Setting the APIC_ID when x2APIC is enabled a= nd @@ -168,16 +190,22 @@ static void __test_apic_id(struct kvm_vcpu *vcpu, uin= t64_t apic_base) * attempted to transition from x2APIC to xAPIC without disabling the APIC= is * architecturally disallowed. */ -static void test_apic_id(void) +static void test_apic_id(int vm_type) { const uint32_t NR_VCPUS =3D 3; struct kvm_vcpu *vcpus[NR_VCPUS]; uint64_t apic_base; struct kvm_vm *vm; int i; + struct vm_shape shape =3D { + .mode =3D VM_MODE_DEFAULT, + .type =3D vm_type, + }; =20 - vm =3D vm_create_with_vcpus(NR_VCPUS, NULL, vcpus); + vm =3D __vm_create_with_vcpus(shape, NR_VCPUS, 0, NULL, vcpus); vm_enable_cap(vm, KVM_CAP_X2APIC_API, KVM_X2APIC_API_USE_32BIT_IDS); + if (is_sev_vm(vm)) + vm_sev_launch(vm, get_sev_policy(vm_type), NULL); =20 for (i =3D 0; i < NR_VCPUS; i++) { apic_base =3D vcpu_get_msr(vcpus[i], MSR_IA32_APICBASE); @@ -195,15 +223,21 @@ static void test_apic_id(void) kvm_vm_free(vm); } =20 -static void test_x2apic_id(void) +static void test_x2apic_id(int vm_type) { struct kvm_lapic_state lapic =3D {}; struct kvm_vcpu *vcpu; struct kvm_vm *vm; int i; + bool is_sev =3D is_sev_vm_type(vm_type); =20 - vm =3D vm_create_with_one_vcpu(&vcpu, NULL); + if (is_sev) + vm =3D vm_sev_create_with_one_vcpu(vm_type, NULL, &vcpu); + else + vm =3D vm_create_with_one_vcpu(&vcpu, NULL); vcpu_set_msr(vcpu, MSR_IA32_APICBASE, MSR_IA32_APICBASE_ENABLE | X2APIC_E= NABLE); + if (is_sev) + vm_sev_launch(vm, get_sev_policy(vm_type), NULL); =20 /* * Try stuffing a modified x2APIC ID, KVM should ignore the value and @@ -222,6 +256,46 @@ static void test_x2apic_id(void) kvm_vm_free(vm); } =20 +void get_cmdline_args(int argc, char *argv[], int *vm_type) +{ + for (;;) { + int opt =3D getopt(argc, argv, "t:"); + + if (opt =3D=3D -1) + break; + switch (opt) { + case 't': + *vm_type =3D parse_size(optarg); + switch (*vm_type) { + case KVM_X86_DEFAULT_VM: + break; + case KVM_X86_SEV_VM: + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV)); + break; + case KVM_X86_SEV_ES_VM: + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV_ES)); + break; + case KVM_X86_SNP_VM: + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV_SNP)); + break; + default: + TEST_ASSERT(false, "Unsupported VM type :%d", + *vm_type); + } + break; + default: + TEST_ASSERT(false, + "Usage: -t . Default is %d.\n" + "Supported values:\n" + "0 - default\n" + "2 - SEV\n" + "3 - SEV-ES\n" + "4 - SNP", + KVM_X86_DEFAULT_VM); + } + } +} + int main(int argc, char *argv[]) { struct xapic_vcpu x =3D { @@ -229,8 +303,24 @@ int main(int argc, char *argv[]) .is_x2apic =3D true, }; struct kvm_vm *vm; + int vm_type =3D KVM_X86_DEFAULT_VM; + bool is_sev; + + get_cmdline_args(argc, argv, &vm_type); + is_sev =3D is_sev_vm_type(vm_type); + + if (is_sev) + vm =3D vm_sev_create_with_one_vcpu(vm_type, x2apic_guest_code, + &x.vcpu); + else + vm =3D vm_create_with_one_vcpu(&x.vcpu, x2apic_guest_code); + + if (is_sev_es_vm(vm)) + vm_install_exception_handler(vm, 29, sev_es_vc_handler); + + if (is_sev) + vm_sev_launch(vm, get_sev_policy(vm_type), NULL); =20 - vm =3D vm_create_with_one_vcpu(&x.vcpu, x2apic_guest_code); test_icr(&x); kvm_vm_free(vm); =20 @@ -239,7 +329,15 @@ int main(int argc, char *argv[]) * the guest in order to test AVIC. KVM disallows changing CPUID after * KVM_RUN and AVIC is disabled if _any_ vCPU is allowed to use x2APIC. */ - vm =3D vm_create_with_one_vcpu(&x.vcpu, xapic_guest_code); + if (is_sev) + vm =3D vm_sev_create_with_one_vcpu(vm_type, xapic_guest_code, + &x.vcpu); + else + vm =3D vm_create_with_one_vcpu(&x.vcpu, xapic_guest_code); + + if (is_sev_es_vm(vm)) + vm_install_exception_handler(vm, 29, sev_es_vc_handler); + x.is_x2apic =3D false; =20 /* @@ -254,9 +352,12 @@ int main(int argc, char *argv[]) vcpu_clear_cpuid_feature(x.vcpu, X86_FEATURE_X2APIC); =20 virt_pg_map(vm, APIC_DEFAULT_GPA, APIC_DEFAULT_GPA); + if (is_sev) + vm_sev_launch(vm, get_sev_policy(vm_type), NULL); + test_icr(&x); kvm_vm_free(vm); =20 - test_apic_id(); - test_x2apic_id(); + test_apic_id(vm_type); + test_x2apic_id(vm_type); } --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from BL0PR03CU003.outbound.protection.outlook.com (mail-eastusazon11012015.outbound.protection.outlook.com [52.101.53.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D964D1D8E01; Tue, 23 Sep 2025 05:16:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.53.15 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604594; cv=fail; b=iRMLplGpxUtD40q8EHpj4W75UVSvsGDO0Ve7lddXAN4ZYugP/RI0FWmYDf5GCRaMsPNR2yj4v2awUz/FruUP82SdYcxpvoNbReZg6X67UNqG1nWajGb6xLyzj4nB4gTuiOc2QAwclEiZS3j+B4a6WUEUlOgDGuWGYbJMSp2/dR0= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604594; c=relaxed/simple; bh=SPOV2738h+huzkxdbPfj6U9cGd1pJacWr7fy37l26GM=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=OOHRiJ7Cy/5M6CtYv8RdfOqVRybxHU728e3LOJthtKCgl/GN3bFHFhpAOpn7PvoixU+ou9+WREfeF9T7u+9dh7vJO/36ECJRgB4ScnFhr/n4U09C48JhoiaYfN3lJ148V3CfElEB1kOTg4hMjwDPN/gxEX+VrjALyJO4I0pFjs0= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=nUo2DnrE; arc=fail smtp.client-ip=52.101.53.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="nUo2DnrE" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=SJP8OO9JxhUHhH+knBAgcZTPNo9tKtkGUm2kUnyeBLwkN+YiGryKctN/gOuvsXwBf+98aQ9Ix3L7XlLxGBMYK893U2uoB3ByiJb/1s1/2RKYsq/YOkt2sKRcsTYfBM1Ploj1pBgNE4Bts9GOVnYQzlynizb/8PPo1ES2eSEWtj6yc0XPwNCpZA7dongOm2jUJkeME5UoAgXDqWO4840e7/MksMAgPd+Qg1wyze8Hk6shlNEIk9EjigBH89bx46f/x19omF7eyx/Ec07zdCxaG7SQDO2zA2rOdYdrzj0+A3wk4cOOHiJeAVrcBo2uIQHoMBm4SlAcPEI5MrLePIVZOQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=YPvZPMBj5ao4HEPY/P+r4JPDDKL8uWF0MPsBYf4YOBM=; b=QbvB2VWC0Ns521epUO1XwB0IR4HJMrcwEZjiKMV2JMGtMkNhUETWxFvVJ7etDabEoEz1/02fIaimrRTu92DZygHHGSkd1azTyzEsOI38g9pyCgdP5JsYr8kPpnuouUdSy2fbKWclTniBEt+a0NfZ1KPQhZ+HuJtlvA8BLkd47kM6wXJX2vElfU4eXBcGD3y3NBd3xr7AsqXykVQRoyiSmQte7oAIrfHc4Npf3+XCTpsilKLsyBtEogwSKQr9AtS4gkmF3b3Fema4KEQuKaH76tRczKkZZBeBdjPp8y4QM5jWnctOMlf6XFQ8W7LnpX3PBZ6TG7bW5CZGsGkwaCotzg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=YPvZPMBj5ao4HEPY/P+r4JPDDKL8uWF0MPsBYf4YOBM=; b=nUo2DnrEHSBVhnpBdrFy8sYsGL+H2JE4DK14h5FlIdbifNzwEdwgGIdLcFW8zv0hESszT7B6U22bnoY6YiQGZtZHks3goJ920W3P2J3YhIEUrRlZbWuXyA5G8E9qwDbq64K3lo5APLu7i5dQ9Yzh6fFKpWZW9ST3l7s6qHjKd1g= Received: from CH2PR16CA0003.namprd16.prod.outlook.com (2603:10b6:610:50::13) by SJ2PR12MB8882.namprd12.prod.outlook.com (2603:10b6:a03:537::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.20; Tue, 23 Sep 2025 05:16:26 +0000 Received: from CH2PEPF0000013B.namprd02.prod.outlook.com (2603:10b6:610:50:cafe::c5) by CH2PR16CA0003.outlook.office365.com (2603:10b6:610:50::13) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:16:26 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF0000013B.mail.protection.outlook.com (10.167.244.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:16:26 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:16:21 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 22/35] KVM: selftests: Add x2apic mode testing in xapic_ipi_test Date: Tue, 23 Sep 2025 10:39:29 +0530 Message-ID: <20250923050942.206116-23-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF0000013B:EE_|SJ2PR12MB8882:EE_ X-MS-Office365-Filtering-Correlation-Id: 108caf4c-5597-4580-100b-08ddfa60586e X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|36860700013|376014|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?DMFzzepVUk1820vZNvRHx52HQdzdrTDhibvsS2BfTCiczYmRP+AxU8Iwc5G7?= =?us-ascii?Q?/Ci/2hZ++3x/cFmM44XzetktLU//ghJ3jb1R6Zp6eS3JW6iidNzEzkmZXyB3?= =?us-ascii?Q?btPJhrPlYZpS/OEJpPG2J2DTNqfGqDZyvvQvy1FZx0Q9gm9kY4g5+JJYr+ZT?= =?us-ascii?Q?6pbEPthvvj86WUbAYqhIw6K+L9lq6bYAXmuUEwab3vLHs9qT7tS/ruhWjv43?= =?us-ascii?Q?iNmAwmJgWZXcoMMjD7DCHafda7rFDuQYz800ZBvk0ExqaHSXoLjsteY2eoIT?= =?us-ascii?Q?F+zZ1SNEvv5KEkODAolOhoJH5DUcW1w4HKu6FPVz2DErKaixx2wCsyyGFRuj?= =?us-ascii?Q?KHTUtTcaoJXer58gKxqTuj7jN2eV0BvKsErdc1re+l0YOn3M+C2Em6ATFKQL?= =?us-ascii?Q?cCsc/x3GjeD37aewGPOpYibGK7xJifid9YJE91phvYFTfQZN46Tpp+tyKwH1?= =?us-ascii?Q?+GnOGoJSuHt/7BAcXiAfGfZP/XNPFxRov9sZPZHOi1G8EebyI12HQXvOlElQ?= =?us-ascii?Q?hpoHSuUTO/MYdCZ/Qf3Qn8qnrjCZXJhQcd7kkh7jOa3qLZlsEGVCBbTDOm0y?= =?us-ascii?Q?ShLsQwKmvSB5zobJZaJtHEb2V7AWbGt/O/XDcwWtJu8jWAoXQOTjDzPDqseH?= =?us-ascii?Q?XKKk2rOZMPIaKdAfXqIMeHr7i0xORGwLdmpc3rjOSKanEN6AzhhQUp1va+Gg?= =?us-ascii?Q?ELWiZkT6if6Ku7lybvsBqmQ6phKYfMinjFB3il00xCXXjekkacEp8uUMsjum?= =?us-ascii?Q?QQSyaxO/sDs/IqweRa5S45f80ZzY2pm+jBNi5EvndhR554Q/AC8FI43jal58?= =?us-ascii?Q?zbkLavBcPf6tWs9gyfWDSCKO5u1L6brcvSbYbm+mDmmJ8wG1BOXkarBa7wCZ?= =?us-ascii?Q?y2NHe7UOeA/k4z5mQI6LnhYBggqIW61A12StokCpVNzuhHS/nRO9O7VEyZmO?= =?us-ascii?Q?rlyMW4AjRFpHp3jfwTVp2LaZC2+Z57nOWq5Fl3xVxodP7IEQBTHyXUipenav?= =?us-ascii?Q?cDzj0OaKIcGDYwdqKLtU1PGIzlav/8GZJxoYYOgx38ZvW25CTpqsXR9i58Hd?= =?us-ascii?Q?L0k8VFeGSFJxl9JWbE4qNw1Xeyawiw/uJMCYULqc+HBpjRqhbMXbTxqSpqyK?= =?us-ascii?Q?bSIuDEuLBvPGGPWFAxnrf68fNi5RosXmxRkgGvAyI2MU+Zvs22lTJ2XyYH95?= =?us-ascii?Q?XL+30VhLI/6VYtLruXXmDzEeF9NhuFklu7T7IAalrhDEU7GIwllvdejhBQlz?= =?us-ascii?Q?1mULERiGdE+AI5G/P7JoGHKyreAyFtQr82B6Z1ga1Tu37NifR58/cY7xaaJF?= =?us-ascii?Q?xuMVjH2l59IBCipzBmAY+HfqtaWCoQ2qiph0vIfSIr3jG689+gaPVQB7D7za?= =?us-ascii?Q?AXlCZR1DrtSDCauhQ7VoQWxHw63YC79fp2KZv2Qw325go0z5So1Pzz6CFTXg?= =?us-ascii?Q?yRNTOCRBTbkqC/vWrnnPc8ZV3GhVP/+Dkwx+2b888v1GcsNftAbRWo4GBiC5?= =?us-ascii?Q?hj1IgMGWQ0tTiEM69L5MoCslRDNLnOUu+Jxd?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(36860700013)(376014)(1800799024);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:16:26.3347 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 108caf4c-5597-4580-100b-08ddfa60586e X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF0000013B.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ2PR12MB8882 Content-Type: text/plain; charset="utf-8" Refactor the test to support both xAPIC and x2APIC modes. The xapic_ipi_test selftest was hardcoded to use xAPIC mode, relying exclusively on MMIO to access the local APIC registers. This limits its ability to test IPI functionality in environments where x2APIC mode is required or preferred, such as for guests with Secure AVIC enabled. This change makes the IPI test more versatile and prepares it for future extensions to test features that depend on x2APIC. Signed-off-by: Neeraj Upadhyay --- .../selftests/kvm/x86/xapic_ipi_test.c | 65 +++++++++++++++---- 1 file changed, 51 insertions(+), 14 deletions(-) diff --git a/tools/testing/selftests/kvm/x86/xapic_ipi_test.c b/tools/testi= ng/selftests/kvm/x86/xapic_ipi_test.c index 35cb9de54a82..e7dcf4bc0350 100644 --- a/tools/testing/selftests/kvm/x86/xapic_ipi_test.c +++ b/tools/testing/selftests/kvm/x86/xapic_ipi_test.c @@ -50,6 +50,29 @@ */ static volatile uint64_t ipis_rcvd; =20 +static bool x2apic; + +static void apic_enable(void) +{ + if (x2apic) + x2apic_enable(); + else + xapic_enable(); +} + +static uint32_t apic_read_reg(unsigned int reg) +{ + return x2apic ? x2apic_read_reg(reg) : xapic_read_reg(reg); +} + +static void apic_write_reg(unsigned int reg, uint64_t val) +{ + if (x2apic) + x2apic_write_reg(reg, val); + else + xapic_write_reg(reg, (uint32_t)val); +} + /* Data struct shared between host main thread and vCPUs */ struct test_data_page { uint32_t halter_apic_id; @@ -89,10 +112,10 @@ void verify_apic_base_addr(void) static void halter_guest_code(struct test_data_page *data) { verify_apic_base_addr(); - xapic_enable(); + apic_enable(); =20 - data->halter_apic_id =3D GET_APIC_ID_FIELD(xapic_read_reg(APIC_ID)); - data->halter_lvr =3D xapic_read_reg(APIC_LVR); + data->halter_apic_id =3D GET_APIC_ID_FIELD(apic_read_reg(APIC_ID)); + data->halter_lvr =3D apic_read_reg(APIC_LVR); =20 /* * Loop forever HLTing and recording halts & wakes. Disable interrupts @@ -103,8 +126,8 @@ static void halter_guest_code(struct test_data_page *da= ta) * TPR and PPR for diagnostic purposes in case the test fails. */ for (;;) { - data->halter_tpr =3D xapic_read_reg(APIC_TASKPRI); - data->halter_ppr =3D xapic_read_reg(APIC_PROCPRI); + data->halter_tpr =3D apic_read_reg(APIC_TASKPRI); + data->halter_ppr =3D apic_read_reg(APIC_PROCPRI); data->hlt_count++; safe_halt(); cli(); @@ -120,7 +143,7 @@ static void halter_guest_code(struct test_data_page *da= ta) static void guest_ipi_handler(struct ex_regs *regs) { ipis_rcvd++; - xapic_write_reg(APIC_EOI, 77); + apic_write_reg(APIC_EOI, 77); } =20 static void sender_guest_code(struct test_data_page *data) @@ -133,7 +156,7 @@ static void sender_guest_code(struct test_data_page *da= ta) uint64_t tsc_start; =20 verify_apic_base_addr(); - xapic_enable(); + apic_enable(); =20 /* * Init interrupt command register for sending IPIs @@ -160,8 +183,12 @@ static void sender_guest_code(struct test_data_page *d= ata) * First IPI can be sent unconditionally because halter vCPU * starts earlier. */ - xapic_write_reg(APIC_ICR2, icr2_val); - xapic_write_reg(APIC_ICR, icr_val); + if (!x2apic) { + apic_write_reg(APIC_ICR2, icr2_val); + apic_write_reg(APIC_ICR, icr_val); + } else { + apic_write_reg(APIC_ICR, (uint64_t)icr2_val << 32 | icr_val); + } data->ipis_sent++; =20 /* @@ -357,10 +384,10 @@ void do_migrations(struct test_data_page *data, int r= un_secs, int delay_usecs, } =20 void get_cmdline_args(int argc, char *argv[], int *run_secs, - bool *migrate, int *delay_usecs) + bool *migrate, int *delay_usecs, bool *x2apic) { for (;;) { - int opt =3D getopt(argc, argv, "s:d:m"); + int opt =3D getopt(argc, argv, "s:d:v:me:"); =20 if (opt =3D=3D -1) break; @@ -374,13 +401,18 @@ void get_cmdline_args(int argc, char *argv[], int *ru= n_secs, case 'd': *delay_usecs =3D parse_size(optarg); break; + case 'e': + *x2apic =3D parse_size(optarg) =3D=3D 1; + break; default: TEST_ASSERT(false, "Usage: -s . Default is %d seconds.\n" "-m adds calls to migrate_pages while vCPUs are running." " Default is no migrations.\n" "-d - delay between migrate_pages() calls." - " Default is %d microseconds.", + " Default is %d microseconds.\n" + "-e - APIC mode 0 - xapic , 1 - x2apic" + " Default is xAPIC.\n", DEFAULT_RUN_SECS, DEFAULT_DELAY_USECS); } } @@ -401,7 +433,10 @@ int main(int argc, char *argv[]) struct kvm_vm *vm; uint64_t *pipis_rcvd; =20 - get_cmdline_args(argc, argv, &run_secs, &migrate, &delay_usecs); + get_cmdline_args(argc, argv, &run_secs, &migrate, &delay_usecs, &x2apic); + if (x2apic) + migrate =3D 0; + if (run_secs <=3D 0) run_secs =3D DEFAULT_RUN_SECS; if (delay_usecs <=3D 0) @@ -411,7 +446,9 @@ int main(int argc, char *argv[]) =20 vm_install_exception_handler(vm, IPI_VECTOR, guest_ipi_handler); =20 - virt_pg_map(vm, APIC_DEFAULT_GPA, APIC_DEFAULT_GPA); + sync_global_to_guest(vm, x2apic); + if (!x2apic) + virt_pg_map(vm, APIC_DEFAULT_GPA, APIC_DEFAULT_GPA); =20 params[1].vcpu =3D vm_vcpu_add(vm, 1, sender_guest_code); =20 --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from SN4PR0501CU005.outbound.protection.outlook.com (mail-southcentralusazon11011030.outbound.protection.outlook.com [40.93.194.30]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B20B730E820; Tue, 23 Sep 2025 05:16:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.194.30 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604611; cv=fail; b=W0667KoGhKmhrXwz+qoSIBx9NVLbMxgkSm7eEZXV/EWAIoHz3DDSJie8U5nkWOUo++GemRTzSLwiAkDzgX2PMTbOYWaJYPJdpbHlWH7Y54hl9NteE4xHNPiLF3vHbXkxfBvNBbWJNnZMKVoJm5WBPLU2BLaR8hZZq11VU0ERCZY= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604611; c=relaxed/simple; bh=0GNKsBw2jMJ+Il7KcQtZLcj6BMf4UVRyjykQi9cp888=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Gi1BlrGIApGTpZOeegJ3M7fYXcSAHxs+rEbqkz9Hiu9/5pZirKMib70rkEaTw2M2DmZNc353GjoJ69ek8Rtt7ZrRSnwQPzuOeH73UmP5d3Fpk84IICkloxZkwmP5Yc86B4N01JCaSGR01lv1CeYHRaRcamXsbGR0ph0BFgKpgQE= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=yUBNWNel; arc=fail smtp.client-ip=40.93.194.30 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="yUBNWNel" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=ikWjD0Cmqu5rFN6kZLIfkaNnVZQXMIpZUEuMVxtMhtr6nQ0iM3yHlqIfJCeKWTYGuEhKxPn9Y8+ofLCrmyNO++6fUwjOEiXt7ScdunsQrEiIO+pGNfXz1gtwunqrmPdQVaLSR1iwTAeQkP8R+4BRg+Kq+OY7n4GOnPtkqu5y1VNLJHmX9rM9QyHWtGba/zDa9lP2hZc6uAdsvSMl1sTqOYQUQ6IVtZLThM3fwxNwgYegiIbug335pXOC++bvCgYNHfzDbL4dPYVZU8MgRmWpZYabGOhBVCJcTAmRi8wKRddwQ5NEiSXvtRCjzgu96abT0Vo7PiIqfqyEdFPYyDsP7A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=25fTTBu+HG56NMeQ8yEb2vfjcwFsA/5AIv+xU4n1xYE=; b=vKlCAE/FkSKrNYQYd3QF3OMAqd8fOsTEBQUfy7sA3HAyEf0B3I528YSGnNlEUCZ7/12CxMiInRVjEJK8ggQ9xAnSCW9vYrSpoKQA4II/sKoWaDo/8MtxUzORJ9JTylXr7YjMtz8IXmKqY2K17kZjKvVNNv1PXd8ZWqwN+C0TuFOwY40VCivpNpUB3g3jm288UtFK1K95oUqapDEkIsMxoV/yDjdtBl3DJoLm6tXnSwev9faE4dCBiJ9bkF5JpFcwa8Moy9htCln3NQ1D0hWrC4MT1nequ0tFH0LIsjt5feQGFqkAtjvbZpwkpAZ2n5mGPjguHIhvdkvqgV7jqlr72Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=25fTTBu+HG56NMeQ8yEb2vfjcwFsA/5AIv+xU4n1xYE=; b=yUBNWNelzexXDNsoL0mabLSPG4ZPPokUmEP0JQxrrOHTVjVe8pOyqK3KsBBbJuIb3zTt9PitiVO4LVFyO/K1oKI3Nz4DnQJMPLNvpT982vWf6/bH2RdCwaLJCs2GFEJhETuaJzyoivbW8jj9eWLfvpBwh+5Rn6nOJO7uhjyz+lw= Received: from CH2PR08CA0021.namprd08.prod.outlook.com (2603:10b6:610:5a::31) by BN7PPF9C6E5285F.namprd12.prod.outlook.com (2603:10b6:40f:fc02::6db) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.19; Tue, 23 Sep 2025 05:16:44 +0000 Received: from CH2PEPF0000013C.namprd02.prod.outlook.com (2603:10b6:610:5a:cafe::58) by CH2PR08CA0021.outlook.office365.com (2603:10b6:610:5a::31) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.19 via Frontend Transport; Tue, 23 Sep 2025 05:16:44 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF0000013C.mail.protection.outlook.com (10.167.244.73) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:16:43 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:16:38 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 23/35] KVM: selftests: Add SEV VM support in xapic_ipi_test Date: Tue, 23 Sep 2025 10:39:30 +0530 Message-ID: <20250923050942.206116-24-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF0000013C:EE_|BN7PPF9C6E5285F:EE_ X-MS-Office365-Filtering-Correlation-Id: 7e17d328-98f9-4626-da24-08ddfa6062f2 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|36860700013|376014|82310400026; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?V1roi9ISw010DgcACoyxDPDMuP2KW9QEMydWKHZ5aHCeiSEUkkAEiRZrFt8p?= =?us-ascii?Q?BiqmCI5L6jvRTOUjDhEdoA+q3nTgEx4SF5DFWIOQ8jYmotA7EsFFoJjygO3l?= =?us-ascii?Q?dEjo8AalzfMqSfyjZm9Zc2ziP6In/y1hhIdiR2gUCJC4qjKPgaM2kgjL/xUR?= =?us-ascii?Q?wy6sXWImyaGf9eflEAs9SrMGBiM2mIMpNAT/r8IN9x8Lrwu0/l3UTkvaRDPS?= =?us-ascii?Q?A/sXXPxBQck3MyYjrUopeArJx3aITL1o93yEO5JNy6xA/P5fVoypfrhW1yRx?= =?us-ascii?Q?XASP1UGp/+e62Nhv3mQMDrDG1CFydTpU3lvxgRPil1dM6zyar77TpUwRNMTw?= =?us-ascii?Q?sw35N92DF84IyoaFuEBY4PKDk7sj9Hk/MNpEM1USBjS9c0uDqFm8q+Tnwsqn?= =?us-ascii?Q?VF3SBU39Iq4xlZ1rNNB/NL+LDEQy51YUoZ2UAS0ZeIjnwizQTekT8ujLfwUu?= =?us-ascii?Q?N1qbedlTK6y4J/eZ5wK09CnG7nkXqawHn8wMqZc11mlrl/wWDhZ9pyoWww7B?= =?us-ascii?Q?eA7+45lT72DPPHpx2pLQnwsxieoWkpur6AlH+Q0FDrqBM70eCDs98IYFn7nW?= =?us-ascii?Q?yxQRHpd7ZJJpRkc7cnwmjjS5kzZRhsHXfgN+0ZH71WLLFKFnaeCK52HxzFtq?= =?us-ascii?Q?WzKmFQntyI8OM6/VheGLRr6bpAOCwMqpPeWaPY/6NewQxp3hYCgMpiLHGKU/?= =?us-ascii?Q?DRFkCk7T6v51OPrJ/1OPVXBD5GflQEruk1qh5QrYMrQ9A+5Sev/xu+U0AyjV?= =?us-ascii?Q?h4zZg+DghVW++1B+b2OoiHJMmPUdgehKWubxiGtv7TKZstzB/V6Yjhi2Wds9?= =?us-ascii?Q?Gb29hk/devlMHMq6gpLIseh2XJauDRJRf20dfZjn5EyOVto2eLPPdrZzSop3?= =?us-ascii?Q?tfjVOY028vNVzVU4ApJmJegGv2VhOBy5OC6s2KgPwxooU8pSzmno8i39Ah8t?= =?us-ascii?Q?dMmPqv8tkPwV3cXfDNP1QwMFRYKdzyi4j5XhFX/otBU3QGEwsnjREiDPT7Hz?= =?us-ascii?Q?jR2txDBbQfqOk7HF1prLHSxBEOW2PaUEYDUrz121/h6MYFPUQBLVCFHC6Lzs?= =?us-ascii?Q?7npP1UnZQRQboQX2H19wo8TW3Ag0v4gmVcoRyQd+pnQXKDUyubVlJSpZWnww?= =?us-ascii?Q?gT8VsdrIhLEAlv24qs8fvI8abguWT8g4z1J+WiFPQOo3ELIbEbvKmXjSnONB?= =?us-ascii?Q?X5COXj82DXs3slfdr46W7ipRW0kXR4lcHSDd9oVmKFHUNhM6lZmUM5DFqLMQ?= =?us-ascii?Q?7XV8kYD4a5v6GWd4+vq5VOnFDkkSXvdCCES7TLnHtfjwAofQfMVwF4MAly7F?= =?us-ascii?Q?4UpN4pNVlMP5IP5D5zgvpMthtNFE669Kary5t2bXlSXldloIrkX9KMINZrz4?= =?us-ascii?Q?sMpyzgolLmzi9KYdsqvjFP/7Jh2vxEfhiz7VByNVvvxn3uVsZtQ8W7rnp9fc?= =?us-ascii?Q?vPeqWEeCdxsDZFl6mVKoCvDx2sR9le4+RDQKD5uupInrD9jhbjU7tlaRQs2V?= =?us-ascii?Q?jYwy6mxAT7JjSDah5jvo1CdU8a8wdZIuwwQc?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(36860700013)(376014)(82310400026);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:16:43.9817 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 7e17d328-98f9-4626-da24-08ddfa6062f2 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF0000013C.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN7PPF9C6E5285F Content-Type: text/plain; charset="utf-8" Extend the xapic_ipi_test to support SEV, SEV-ES, and SNP guests. This is important for validating IPI functionality within confidential computing environments. The test now works in both xAPIC and x2APIC modes for these encrypted guest types. The test now uses SEV-specific VM creation and launch helpers when an encrypted guest is selected. For SEV-ES guests, install the generic for xAPIC mode to function. In an encrypted guest, memory is private by default and inaccessible to the host. To allow the host to monitor guest activity, convert the page used for statistics (test_data_page) to a shared (unencrypted) memory region. Add a convenience wrapper, vm_vaddr_alloc_page_shared(), to simplify the allocation of a single shared page. With these changes, the IPI selftest can now provide comprehensive coverage across both standard and confidential VM types. Signed-off-by: Neeraj Upadhyay --- .../testing/selftests/kvm/include/kvm_util.h | 1 + tools/testing/selftests/kvm/lib/kvm_util.c | 19 ++++ .../selftests/kvm/x86/xapic_ipi_test.c | 94 ++++++++++++++++--- 3 files changed, 100 insertions(+), 14 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing= /selftests/kvm/include/kvm_util.h index 2e27682c5077..4a4f9621082d 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -700,6 +700,7 @@ vm_vaddr_t vm_vaddr_alloc_pages_shared(struct kvm_vm *v= m, int nr_pages); vm_vaddr_t __vm_vaddr_alloc_page(struct kvm_vm *vm, enum kvm_mem_region_type type); vm_vaddr_t vm_vaddr_alloc_page(struct kvm_vm *vm); +vm_vaddr_t vm_vaddr_alloc_page_shared(struct kvm_vm *vm); =20 void virt_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, unsigned int npages); diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index 00317ce5dbb9..360f262f5f3f 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -1592,6 +1592,25 @@ vm_vaddr_t vm_vaddr_alloc_page(struct kvm_vm *vm) return vm_vaddr_alloc_pages(vm, 1); } =20 +/* + * VM Virtual Address Allocate shared Page + * + * Input Args: + * vm - Virtual Machine + * + * Output Args: None + * + * Return: + * Starting guest virtual address + * + * Allocates at least one system page (in shared state) worth of bytes wit= hin the + * virtual address space of the vm. + */ +vm_vaddr_t vm_vaddr_alloc_page_shared(struct kvm_vm *vm) +{ + return vm_vaddr_alloc_pages_shared(vm, 1); +} + /* * Map a range of VM virtual address to the VM's physical address * diff --git a/tools/testing/selftests/kvm/x86/xapic_ipi_test.c b/tools/testi= ng/selftests/kvm/x86/xapic_ipi_test.c index e7dcf4bc0350..3d49f7798dcc 100644 --- a/tools/testing/selftests/kvm/x86/xapic_ipi_test.c +++ b/tools/testing/selftests/kvm/x86/xapic_ipi_test.c @@ -30,6 +30,7 @@ #include "processor.h" #include "test_util.h" #include "vmx.h" +#include "sev.h" =20 /* Default running time for the test */ #define DEFAULT_RUN_SECS 3 @@ -48,7 +49,7 @@ * Incremented in the IPI handler. Provides evidence to the sender that th= e IPI * arrived at the destination */ -static volatile uint64_t ipis_rcvd; +static volatile uint64_t *ipis_rcvd; =20 static bool x2apic; =20 @@ -93,6 +94,7 @@ struct test_data_page { * to determine whether APIC access exits are working. */ uint32_t halter_lvr; + uint64_t ipis_rcvd; }; =20 struct thread_params { @@ -142,7 +144,7 @@ static void halter_guest_code(struct test_data_page *da= ta) */ static void guest_ipi_handler(struct ex_regs *regs) { - ipis_rcvd++; + (*ipis_rcvd)++; apic_write_reg(APIC_EOI, 77); } =20 @@ -176,7 +178,7 @@ static void sender_guest_code(struct test_data_page *da= ta) =20 last_wake_count =3D data->wake_count; last_hlt_count =3D data->hlt_count; - last_ipis_rcvd_count =3D ipis_rcvd; + last_ipis_rcvd_count =3D *ipis_rcvd; for (;;) { /* * Send IPI to halter vCPU. @@ -201,19 +203,19 @@ static void sender_guest_code(struct test_data_page *= data) */ tsc_start =3D rdtsc(); while (rdtsc() - tsc_start < 2000000000) { - if ((ipis_rcvd !=3D last_ipis_rcvd_count) && + if ((*ipis_rcvd !=3D last_ipis_rcvd_count) && (data->wake_count !=3D last_wake_count) && (data->hlt_count !=3D last_hlt_count)) break; } =20 - GUEST_ASSERT((ipis_rcvd !=3D last_ipis_rcvd_count) && + GUEST_ASSERT((*ipis_rcvd !=3D last_ipis_rcvd_count) && (data->wake_count !=3D last_wake_count) && (data->hlt_count !=3D last_hlt_count)); =20 last_wake_count =3D data->wake_count; last_hlt_count =3D data->hlt_count; - last_ipis_rcvd_count =3D ipis_rcvd; + last_ipis_rcvd_count =3D *ipis_rcvd; } } =20 @@ -384,10 +386,10 @@ void do_migrations(struct test_data_page *data, int r= un_secs, int delay_usecs, } =20 void get_cmdline_args(int argc, char *argv[], int *run_secs, - bool *migrate, int *delay_usecs, bool *x2apic) + bool *migrate, int *delay_usecs, bool *x2apic, int *vm_type) { for (;;) { - int opt =3D getopt(argc, argv, "s:d:v:me:"); + int opt =3D getopt(argc, argv, "s:d:v:me:t:"); =20 if (opt =3D=3D -1) break; @@ -404,6 +406,25 @@ void get_cmdline_args(int argc, char *argv[], int *run= _secs, case 'e': *x2apic =3D parse_size(optarg) =3D=3D 1; break; + case 't': + *vm_type =3D parse_size(optarg); + switch (*vm_type) { + case KVM_X86_DEFAULT_VM: + break; + case KVM_X86_SEV_VM: + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV)); + break; + case KVM_X86_SEV_ES_VM: + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV_ES)); + break; + case KVM_X86_SNP_VM: + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SNP)); + break; + default: + TEST_ASSERT(false, "Unsupported VM type :%d", + *vm_type); + } + break; default: TEST_ASSERT(false, "Usage: -s . Default is %d seconds.\n" @@ -412,12 +433,39 @@ void get_cmdline_args(int argc, char *argv[], int *ru= n_secs, "-d - delay between migrate_pages() calls." " Default is %d microseconds.\n" "-e - APIC mode 0 - xapic , 1 - x2apic" - " Default is xAPIC.\n", - DEFAULT_RUN_SECS, DEFAULT_DELAY_USECS); + " Default is xAPIC.\n" + "-t . Default is %d.\n" + "Supported values:\n" + "0 - default\n" + "2 - SEV\n" + "3 - SEV-ES\n" + "4 - SNP", + DEFAULT_RUN_SECS, DEFAULT_DELAY_USECS, KVM_X86_DEFAULT_VM); } } } =20 +static inline bool is_sev_vm_type(int type) +{ + return type =3D=3D KVM_X86_SEV_VM || + type =3D=3D KVM_X86_SEV_ES_VM || + type =3D=3D KVM_X86_SNP_VM; +} + +static inline uint64_t get_sev_policy(int vm_type) +{ + switch (vm_type) { + case KVM_X86_SEV_VM: + return SEV_POLICY_NO_DBG; + case KVM_X86_SEV_ES_VM: + return SEV_POLICY_ES; + case KVM_X86_SNP_VM: + return snp_default_policy(); + default: + return 0; + } +} + int main(int argc, char *argv[]) { int r; @@ -432,8 +480,13 @@ int main(int argc, char *argv[]) struct thread_params params[2]; struct kvm_vm *vm; uint64_t *pipis_rcvd; + int vm_type =3D KVM_X86_DEFAULT_VM; + bool is_sev; + + get_cmdline_args(argc, argv, &run_secs, &migrate, &delay_usecs, + &x2apic, &vm_type); + is_sev =3D is_sev_vm_type(vm_type); =20 - get_cmdline_args(argc, argv, &run_secs, &migrate, &delay_usecs, &x2apic); if (x2apic) migrate =3D 0; =20 @@ -442,9 +495,15 @@ int main(int argc, char *argv[]) if (delay_usecs <=3D 0) delay_usecs =3D DEFAULT_DELAY_USECS; =20 - vm =3D vm_create_with_one_vcpu(¶ms[0].vcpu, halter_guest_code); + if (is_sev) + vm =3D vm_sev_create_with_one_vcpu(vm_type, halter_guest_code, + ¶ms[0].vcpu); + else + vm =3D vm_create_with_one_vcpu(¶ms[0].vcpu, halter_guest_code); =20 vm_install_exception_handler(vm, IPI_VECTOR, guest_ipi_handler); + if (is_sev_es_vm(vm)) + vm_install_exception_handler(vm, 29, sev_es_vc_handler); =20 sync_global_to_guest(vm, x2apic); if (!x2apic) @@ -452,8 +511,10 @@ int main(int argc, char *argv[]) =20 params[1].vcpu =3D vm_vcpu_add(vm, 1, sender_guest_code); =20 - test_data_page_vaddr =3D vm_vaddr_alloc_page(vm); + test_data_page_vaddr =3D vm_vaddr_alloc_page_shared(vm); data =3D addr_gva2hva(vm, test_data_page_vaddr); + if (is_sev_snp_vm(vm)) + vm_mem_set_shared(vm, addr_hva2gpa(vm, data), getpagesize()); memset(data, 0, sizeof(*data)); params[0].data =3D data; params[1].data =3D data; @@ -461,10 +522,15 @@ int main(int argc, char *argv[]) vcpu_args_set(params[0].vcpu, 1, test_data_page_vaddr); vcpu_args_set(params[1].vcpu, 1, test_data_page_vaddr); =20 - pipis_rcvd =3D (uint64_t *)addr_gva2hva(vm, (uint64_t)&ipis_rcvd); + ipis_rcvd =3D &((struct test_data_page *)test_data_page_vaddr)->ipis_rcvd; + sync_global_to_guest(vm, ipis_rcvd); + pipis_rcvd =3D (uint64_t *)addr_gva2hva(vm, (uint64_t)ipis_rcvd); params[0].pipis_rcvd =3D pipis_rcvd; params[1].pipis_rcvd =3D pipis_rcvd; =20 + if (is_sev) + vm_sev_launch(vm, get_sev_policy(vm_type), NULL); + /* Start halter vCPU thread and wait for it to execute first HLT. */ r =3D pthread_create(&threads[0], NULL, vcpu_thread, ¶ms[0]); TEST_ASSERT(r =3D=3D 0, --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from CH4PR04CU002.outbound.protection.outlook.com (mail-northcentralusazon11013060.outbound.protection.outlook.com [40.107.201.60]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5620630FF25; Tue, 23 Sep 2025 05:17:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.201.60 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604630; cv=fail; b=dIKibL7Q+lzpa7G1SV95LBZQI26veZ3gv+8OtivNRtrfzB6Gll5GjcuxhvnU/3LZiCvUvAjs3/SUIIqmGjDg2/8CV64WpIcXjhIQxtceaV+mtUqK+WHWUGbs3vRs8pnDqWHklbnUaA2MWYV5O00nk1JAJhqia5BJbm9z3MZ8HV8= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604630; c=relaxed/simple; bh=ZsQyO58cr8x5vJqgp640jL5MzyqYxXiFHAb4JgD5CL8=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=b2SOOtfZGG6U1wmKHDFhKEC6W/5yngqhsFQEYzfGs57BQDP4eFEdsrANorpf8HnzNHDimh7toB2qwps2P3fZjdoJ7uyyT6UkmJQys6XxcfYj5A8t9YknrcL8NTbCb+baB8GObXSdLcAs1XfmnIY7SEcqK5nqIb9JvxqKI796710= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=wI1Xda/N; arc=fail smtp.client-ip=40.107.201.60 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="wI1Xda/N" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=yo99bRxGlIDHwDJJlUctYUKwUeBGjrSumPxupOfZbdiQjg7+v/eOnRr2F/k4VepuNyWUczK144dVazC+XkE0BEz7jyyzhq4OxQ9s8dg4zWAk+mV97rgNPGrL6xZzxLy7oUHTh8mFVuwMfVZx+hECIfdFl562ynlB8PqIeoKERhZ0RZCJ9GE5NK6AQ7EMznvOCOlZb8kDKc8ANAjQFUeyJ4BB8RV3ufthvJfaadkq6yj8OkUcAAEvqatWRoEv94l90q4jBZ1EBuOxsXVs0a0b61rpqrP0k7gjoV1P6fk0McPmH/4n1lJPp1jT5qKvI8A3ZVeLRzhEphXq2z1OnAFVWA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=TemSTNfe7Rc/LQx223hKXeWmU2u9uTIFRInWqTTJJto=; b=AcU7VOtDXSJTexxsUbQyJqg8s2aQ1XY3ban+FmDFss6y5F8M1XEEoz3c4MAw6JL/ZGTcvD6/V81Drn9f/VAkdhhlYk3rkyWNIBdHPaeDrzcwh/iiDKpd55YM7Ev3AbfCITXs5JxY3ftP5Bm9vEr8dYPql5FIHRec7B95zOPdRdkATfslYLi0m4s2w9EfG91NJ+1ble14Kp4WxiGtPMgnICExk3g6/Nwc5ScVbQyLmxtHTMhk0q5kmr8q4gPFohbEnY2wPtus0Lzolm11+wyhK0qpk3DmxqgDZ1uZ8n7C9z+nEyIDGyEovczgnunEc78qi8QOFbGkPMNWTXMnw2z7DA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=TemSTNfe7Rc/LQx223hKXeWmU2u9uTIFRInWqTTJJto=; b=wI1Xda/NOJmMRQfcTdnLKLzEqkTHwdP1S1pFA1536Hudmg6v8agkk+hmHRQ6mPE26rvCcaXncfujtMmVQ4DZosI0Bouu5vLoSY8UUsUGShYaIJ22RU4EbjiLaMyUajHzms1PQS4Z+piFVogQl9B2JWoA35LeFQuELaBMNkHp7jo= Received: from CH2PR15CA0027.namprd15.prod.outlook.com (2603:10b6:610:51::37) by CY8PR12MB7634.namprd12.prod.outlook.com (2603:10b6:930:9d::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.14; Tue, 23 Sep 2025 05:17:02 +0000 Received: from CH2PEPF0000013B.namprd02.prod.outlook.com (2603:10b6:610:51:cafe::76) by CH2PR15CA0027.outlook.office365.com (2603:10b6:610:51::37) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:17:01 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF0000013B.mail.protection.outlook.com (10.167.244.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:17:01 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:16:56 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 24/35] KVM: selftests: Add Secure AVIC library Date: Tue, 23 Sep 2025 10:39:31 +0530 Message-ID: <20250923050942.206116-25-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF0000013B:EE_|CY8PR12MB7634:EE_ X-MS-Office365-Filtering-Correlation-Id: 76947992-e2cf-4d6f-0372-08ddfa606d96 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|376014|36860700013|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?bfMXATGx7H6VtnPpqZrmBnzdjVGfKfmFuFDGb9+DFhN4EShlVKWtAjLl1HwD?= =?us-ascii?Q?xVUZjCJzjw4BvspQCndseTT3nBfyMXJau0RRsBevoXrxY6seeKegE1GqQ2n2?= =?us-ascii?Q?XPpZRMxtW2CFRq/UPvl71NgwfUhHzfQOtVm2wmdvaAO5oEmRZIGZJOnKcDg0?= =?us-ascii?Q?lLCHeG9QygrnGcRFfBx1wLI32RFYTGIw5hBO2gmpXG8okdkXG26m0UcZnuNh?= =?us-ascii?Q?7fFfqQEXFPQu/vjfVLbc4sZEP0eysPHMBqc8vJAc9kie89u8I+ngGyRIIzel?= =?us-ascii?Q?Ucro4G3x7MWUBFH7L6N+TbLVG3MWD8uRRQfGBcwhTXr9TxVTUpZdFe4BNTrA?= =?us-ascii?Q?2PzJsMrqchD501crYB4KK1XAFoxPH3j0POacMBuNPClNJyxivvbOft/mfMgh?= =?us-ascii?Q?SlN1FtPYHMDlWZadALRPkQ6DNJhPAU0kJOXmwbnyFVHGTFo5tCxeBXLpCpjZ?= =?us-ascii?Q?noduxbHZ0kvXVU5xFlnmgbVihiLfpobUnb/zOmRPGoUN7tft3D/r4P2Ufr1R?= =?us-ascii?Q?j/Gvj/3tfXptoHArVuFY5YsModD0Brt59liy0nURFQByiBjX0dYkrTKnjOir?= =?us-ascii?Q?xvDVNO8k3MHhp/CRn2TFgoPlI+kIw7KwC6yb5WrGAgB0541IsNL1clIBIisW?= =?us-ascii?Q?0iHCaQdA2J/WeJ3X2Cod/EbqjtOPpCRmwoZrFMWa6F9ZYIzYodbbed7azgtJ?= =?us-ascii?Q?ePsjB4mDzRx921a4/m+i7zURB5ySxu+2n+RvFFNr/8Yi3dHVEsk7srEPP4I/?= =?us-ascii?Q?ZrpJtD+7A7HmZ+8Cju5lukEB9Ra8fYb1jkWzZxtx4IuuXbfN9lbFPby3wbna?= =?us-ascii?Q?CFH9Tp0jSblreCL3kSxxOVK7N8q8eVp92H9F/7jlhFfE7TKLipzaIxJqrL0g?= =?us-ascii?Q?yOf2DkivCCuC3mRHCk2cmwuhXrJygTaKeX1mo4g+6Bb2mjjygiLHdNOlkL82?= =?us-ascii?Q?bHZ7ib9mUvATtxDp8LmE+UVf0rZ9kITCbquXuR3cWDbGg2s0DWq9uYDwdYNZ?= =?us-ascii?Q?BYrfL5H78PePcyjZVgL7/FKX3D4lFHckxIE3sCdsorc4uQkslxYcP5H39jGZ?= =?us-ascii?Q?jcpCGl7LwPPTh53/3Z24Zdbufmwu+Nc6W5vSNoKQjyVMIbkzlJ9b9LmtJLiW?= =?us-ascii?Q?tAkFc+LjK6VQTMOZ8L/DuXiQDy4SqoogKCM8c/OeDBI5IDlvKSRWklcWMjmv?= =?us-ascii?Q?dhOl8RDjK+KdJi4A0Jvl7wil0qtA4L3x1XvCNCeYsD2+beu7V+VPnvcSaqv8?= =?us-ascii?Q?z7Vpl9vDWJBJTBKz6my/VJmA1+DhbKNkdDrg0BNroMQa1CeP3jfjv8DSqB+F?= =?us-ascii?Q?otFpyQf/C2xyi8QjXXYoS4NPSgNIPHYlZ1MZVwyCiMna71zX3hUtj51BF8sa?= =?us-ascii?Q?bdcgTEkzKWJK28Cha3Yy8Y7klqwTPkS/gLgB8xf6nanJK1BSZDCSFtg1V/Y7?= =?us-ascii?Q?Fweo/05WPTbdmrVyMmOjGmD8SYLPrmfdQPqeMHureGWkePadQkJrSuOVjfiE?= =?us-ascii?Q?iHOvD86FlODfzsfAmUkKTJWW5sKDcFzrGlnb?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(376014)(36860700013)(1800799024);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:17:01.8274 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 76947992-e2cf-4d6f-0372-08ddfa606d96 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF0000013B.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY8PR12MB7634 Content-Type: text/plain; charset="utf-8" Add a new library to the KVM selftest framework to manage and enable Secure AVIC, providing the foundation for testing this feature. Secure AVIC (SAVIC) is an AMD SEV-SNP feature that provides each vCPU with a guest-owned APIC backing page in memory. This allow SEV-SNP guests to prevent the hypervisor from generating unexpected interrupts to a vCPU or otherwise violate architectural assumptions around APIC behavior. The core of the new library (lib/x86/savic.c) revolves around the management of these APIC backing pages: - Allocate pool of APIC backing pages during the SNP VM launch sequence if the VMSA features report SAVIC support. - Update kvm_arch_vm_additional_pages_required() helper to ensure sufficient memory is pre-allocated for these pages during VM creation. The library exposes a set of helpers for guest code: - savic_enable(): The primary function for a vCPU to switch into Secure AVIC mode. - savic_read/write_reg(): Allow the guest to interact with its local APIC state via the backing page once SAVIC is active. - savic_hv_read/write_reg(): Helpers that wrap the PV MSR interface for communicating with KVM's view of the APIC state. This infrastructure is a prerequisite for writing selftests that verify the correctness of Secure AVIC. Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/Makefile.kvm | 1 + .../testing/selftests/kvm/include/x86/apic.h | 6 + .../testing/selftests/kvm/include/x86/savic.h | 19 ++ tools/testing/selftests/kvm/include/x86/svm.h | 3 + .../testing/selftests/kvm/lib/x86/processor.c | 7 +- tools/testing/selftests/kvm/lib/x86/savic.c | 205 ++++++++++++++++++ tools/testing/selftests/kvm/lib/x86/sev.c | 15 ++ 7 files changed, 254 insertions(+), 2 deletions(-) create mode 100644 tools/testing/selftests/kvm/include/x86/savic.h create mode 100644 tools/testing/selftests/kvm/lib/x86/savic.c diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selft= ests/kvm/Makefile.kvm index 41aa99e5e0c4..b94ac1caa514 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -26,6 +26,7 @@ LIBKVM_x86 +=3D lib/x86/insn-eval.c LIBKVM_x86 +=3D lib/x86/memstress.c LIBKVM_x86 +=3D lib/x86/pmu.c LIBKVM_x86 +=3D lib/x86/processor.c +LIBKVM_x86 +=3D lib/x86/savic.c LIBKVM_x86 +=3D lib/x86/sev.c LIBKVM_x86 +=3D lib/x86/svm.c LIBKVM_x86 +=3D lib/x86/ucall.c diff --git a/tools/testing/selftests/kvm/include/x86/apic.h b/tools/testing= /selftests/kvm/include/x86/apic.h index 80fe9f69b38d..6ba5d0545bf8 100644 --- a/tools/testing/selftests/kvm/include/x86/apic.h +++ b/tools/testing/selftests/kvm/include/x86/apic.h @@ -29,6 +29,7 @@ #define APIC_TASKPRI 0x80 #define APIC_PROCPRI 0xA0 #define APIC_EOI 0xB0 +#define APIC_LDR 0xD0 #define APIC_SPIV 0xF0 #define APIC_SPIV_FOCUS_DISABLED (1 << 9) #define APIC_SPIV_APIC_ENABLED (1 << 8) @@ -60,10 +61,15 @@ #define APIC_ICR2 0x310 #define SET_APIC_DEST_FIELD(x) ((x) << 24) #define APIC_LVTT 0x320 +#define APIC_LVTTHMR 0x330 +#define APIC_LVTPC 0x340 +#define APIC_LVT0 0x350 #define APIC_LVT_TIMER_ONESHOT (0 << 17) #define APIC_LVT_TIMER_PERIODIC (1 << 17) #define APIC_LVT_TIMER_TSCDEADLINE (2 << 17) #define APIC_LVT_MASKED (1 << 16) +#define APIC_LVT1 0x360 +#define APIC_LVTERR 0x370 #define APIC_TMICT 0x380 #define APIC_TMCCT 0x390 #define APIC_TDCR 0x3E0 diff --git a/tools/testing/selftests/kvm/include/x86/savic.h b/tools/testin= g/selftests/kvm/include/x86/savic.h new file mode 100644 index 000000000000..1ab92dad00c1 --- /dev/null +++ b/tools/testing/selftests/kvm/include/x86/savic.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Helpers used for Secure AVIC guests + * + */ +#ifndef SELFTEST_KVM_SAVIC_H +#define SELFTEST_KVM_SAVIC_H + +struct guest_apic_page; + +void guest_apic_pages_init(struct kvm_vm *vm); +void set_savic_control_msr(struct guest_apic_page *apic_page, bool enable,= bool enable_nmi); +void savic_write_reg(struct guest_apic_page *apic_page, uint32_t reg, uint= 64_t val); +uint64_t savic_read_reg(struct guest_apic_page *apic_page, uint32_t reg); +void savic_hv_write_reg(uint32_t reg, uint64_t val); +uint64_t savic_hv_read_reg(uint32_t reg); +void savic_enable(void); +int savic_nr_pages_required(uint64_t page_size); +#endif diff --git a/tools/testing/selftests/kvm/include/x86/svm.h b/tools/testing/= selftests/kvm/include/x86/svm.h index 66dd4eaf23b9..689fefb72d06 100644 --- a/tools/testing/selftests/kvm/include/x86/svm.h +++ b/tools/testing/selftests/kvm/include/x86/svm.h @@ -179,6 +179,9 @@ struct __attribute__ ((__packed__)) vmcb_control_area { #define SVM_NESTED_CTL_NP_ENABLE BIT(0) #define SVM_NESTED_CTL_SEV_ENABLE BIT(1) =20 +#define SVM_FEAT_SECURE_AVIC 16 +#define SVM_FEAT_ALLOWED_SEV_FEATURES_VALID 63 + struct __attribute__ ((__packed__)) vmcb_seg { u16 selector; u16 attrib; diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testin= g/selftests/kvm/lib/x86/processor.c index 181f1943c4be..a33a09a161d3 100644 --- a/tools/testing/selftests/kvm/lib/x86/processor.c +++ b/tools/testing/selftests/kvm/lib/x86/processor.c @@ -659,10 +659,13 @@ void kvm_arch_vm_post_create(struct kvm_vm *vm) =20 int kvm_arch_vm_additional_pages_required(struct vm_shape shape, uint64_t = page_size) { - if (shape.type =3D=3D KVM_X86_SEV_ES_VM || - shape.type =3D=3D KVM_X86_SNP_VM) + if (shape.type =3D=3D KVM_X86_SEV_ES_VM) return ghcb_nr_pages_required(page_size); =20 + if (shape.type =3D=3D KVM_X86_SNP_VM) + return ghcb_nr_pages_required(page_size) + + savic_nr_pages_required(page_size); + return 0; } =20 diff --git a/tools/testing/selftests/kvm/lib/x86/savic.c b/tools/testing/se= lftests/kvm/lib/x86/savic.c new file mode 100644 index 000000000000..72ad43d4797e --- /dev/null +++ b/tools/testing/selftests/kvm/lib/x86/savic.c @@ -0,0 +1,205 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * Copyright (C) 2024 Advanced Micro Devices, Inc. + * + */ + +#include "apic.h" +#include "kvm_util.h" +#include "sev.h" + +struct apic_page { + u8 apic_regs[PAGE_SIZE]; +} __packed; + +struct guest_apic_page { + struct apic_page apic_page; + uint64_t gpa; + uint64_t hva; +} __aligned(PAGE_SIZE); + +struct guest_apic_pages { + struct guest_apic_page guest_apic_page[KVM_MAX_VCPUS]; +}; + +static struct guest_apic_pages *apic_page_pool; + +enum lapic_lvt_entry { + LVT_TIMER, + LVT_THERMAL_MONITOR, + LVT_PERFORMANCE_COUNTER, + LVT_LINT0, + LVT_LINT1, + LVT_ERROR, + APIC_MAX_NR_LVT_ENTRIES, +}; + +#define MSR_AMD64_SECURE_AVIC_CONTROL 0xc0010138 + +#define APIC_LVTx(x) (APIC_LVTT + 0x10 * (x)) +#define MSR_AMD64_SECURE_AVIC_EN_BIT 0 +#define MSR_AMD64_SECURE_AVIC_ALLOWED_NMI_BIT 1 + +/* + * Initial pool of guest apic backing page. + */ +void guest_apic_pages_init(struct kvm_vm *vm) +{ + struct guest_apic_pages *g_pages; + struct guest_apic_page *entry; + vm_vaddr_t vaddr; + int i; + size_t sz =3D align_up(sizeof(struct guest_apic_pages), + vm_guest_mode_params[vm->mode].page_size); + + vaddr =3D vm_vaddr_alloc(vm, sz, KVM_UTIL_MIN_VADDR); + + g_pages =3D (struct guest_apic_pages *)addr_gva2hva(vm, vaddr); + memset(g_pages, 0, sz); + + for (i =3D 0; i < KVM_MAX_VCPUS; ++i) { + entry =3D &g_pages->guest_apic_page[i]; + entry->hva =3D (uint64_t)entry; + entry->gpa =3D (uint64_t)addr_hva2gpa(vm, &entry->apic_page); + } + + apic_page_pool =3D (struct guest_apic_pages *)vaddr; + sync_global_to_guest(vm, apic_page_pool); +} + +int savic_nr_pages_required(uint64_t page_size) +{ + return align_up(sizeof(struct guest_apic_pages), page_size) / page_size; +} + +/* + * Enable/disable Secure AVIC in control msr. + * + * @apic_page : Guest APIC backing page for the CPU on which + * this function is called. + * @enable : Enable/Disable Secure AVIC. + * @enable_nmi : Allow host to send NMI to the guest. + */ +void set_savic_control_msr(struct guest_apic_page *apic_page, bool enable,= bool enable_nmi) +{ + uint64_t val =3D apic_page->gpa | BIT_ULL(MSR_AMD64_SECURE_AVIC_EN_BIT); + + if (!enable) { + wrmsr(MSR_AMD64_SECURE_AVIC_CONTROL, 0); + return; + } + + if (enable_nmi) + val |=3D BIT_ULL(MSR_AMD64_SECURE_AVIC_ALLOWED_NMI_BIT); + + wrmsr(MSR_AMD64_SECURE_AVIC_CONTROL, val); +} + +/* + * Write APIC reg offset in the guest APIC backing page. + * + * @apage : Backing page address. + * @reg : APIC reg offset corresponding to the xapic MMIO + * offset. + * @val : New value to be set for the APIC reg. + */ +void savic_write_reg(struct guest_apic_page *apic_page, uint32_t reg, uint= 64_t val) +{ + *(volatile uint64_t *)((uint64_t)apic_page + reg) =3D val; +} + +/* + * Read APIC reg offset from the guest APIC backing page. + * + * @apage : Backing page address. + * @reg : APIC reg offset corresponding to the xapic MMIO + * offset. + * + * @ret : APIC register value in the guest APIC backing page. + */ +uint64_t savic_read_reg(struct guest_apic_page *apic_page, uint32_t reg) +{ + return *(volatile uint64_t *)((uint64_t)apic_page + reg); +} + +/* + * Write APIC reg value to hypervisor. + * + * @reg : APIC reg offset corresponding to the xapic MMIO + * offset. + * @val : Value to be set for the APIC reg. + */ +void savic_hv_write_reg(uint32_t reg, uint64_t val) +{ + sev_es_pv_msr_rw(APIC_BASE_MSR + (reg >> 4), &val, true); +} + +/* + * Read APIC reg offset from hypervisor. + * + * @reg : APIC reg offset corresponding to the xapic MMIO + * offset. + * + * @ret : APIC register value in the hypervisor's APIC state. + */ +uint64_t savic_hv_read_reg(uint32_t reg) +{ + uint64_t val; + + sev_es_pv_msr_rw(APIC_BASE_MSR + (reg >> 4), &val, false); + + return val; +} + +static void savic_init_backing_page(struct guest_apic_page *apic_page, uin= t32_t apic_id) +{ + uint64_t regval; + enum lapic_lvt_entry i; + + /* Update APIC ID in the backing page */ + savic_write_reg(apic_page, APIC_ID, apic_id); + + /* Set LVR, LDR, LVT* in backing page from host values */ + regval =3D savic_hv_read_reg(APIC_LVR); + savic_write_reg(apic_page, APIC_LVR, regval); + + regval =3D savic_hv_read_reg(APIC_LDR); + savic_write_reg(apic_page, APIC_LDR, regval); + + for (i =3D LVT_THERMAL_MONITOR; i < APIC_MAX_NR_LVT_ENTRIES; i++) { + regval =3D savic_hv_read_reg(APIC_LVTx(i)); + savic_write_reg(apic_page, APIC_LVTx(i), regval); + } + + regval =3D savic_hv_read_reg(APIC_LVT0); + savic_write_reg(apic_page, APIC_LVT0, regval); + + regval =3D savic_hv_read_reg(APIC_LVT1); + savic_write_reg(apic_page, APIC_LVT1, regval); +} + +/* + * Initialize and enable Secure AVIC on a CPU. + * + * @context: Called from x2apic enabled context and Secure AVIC disabled. + */ +void savic_enable(void) +{ + uint64_t savic_ctrl_msr_val, exp_msr_val; + struct guest_apic_page *apic_page; + uint32_t apic_id; + + __GUEST_ASSERT(apic_page_pool, "Guest APIC pages pool is not initialized"= ); + apic_id =3D x2apic_read_reg(APIC_ID); + apic_page =3D &apic_page_pool->guest_apic_page[apic_id]; + + savic_init_backing_page(apic_page, apic_id); + set_savic_control_msr(apic_page, true, true); + savic_ctrl_msr_val =3D rdmsr(MSR_AMD64_SECURE_AVIC_CONTROL); + exp_msr_val =3D apic_page->gpa | BIT_ULL(MSR_AMD64_SECURE_AVIC_EN_BIT) | + BIT_ULL(MSR_AMD64_SECURE_AVIC_ALLOWED_NMI_BIT); + __GUEST_ASSERT(savic_ctrl_msr_val =3D=3D exp_msr_val, + "SAVIC Control msr unexpected val : 0x%lx, expected : 0x%lx", + savic_ctrl_msr_val, exp_msr_val); +} diff --git a/tools/testing/selftests/kvm/lib/x86/sev.c b/tools/testing/self= tests/kvm/lib/x86/sev.c index 1e0719dfd6b0..113f33ca40b2 100644 --- a/tools/testing/selftests/kvm/lib/x86/sev.c +++ b/tools/testing/selftests/kvm/lib/x86/sev.c @@ -276,6 +276,18 @@ struct kvm_vm *vm_sev_create_with_one_vcpu(uint32_t ty= pe, void *guest_code, return vm; } =20 +static bool is_savic_enabled(void) +{ + u64 supported_vmsa_features; + int kvm_fd =3D open_kvm_dev_path_or_exit(); + + kvm_device_attr_get(kvm_fd, KVM_X86_GRP_SEV, + KVM_X86_SEV_VMSA_FEATURES, + &supported_vmsa_features); + + return supported_vmsa_features & BIT_ULL(SVM_FEAT_SECURE_AVIC); +} + void vm_sev_launch(struct kvm_vm *vm, uint64_t policy, uint8_t *measuremen= t) { if (is_sev_es_vm(vm)) @@ -284,6 +296,9 @@ void vm_sev_launch(struct kvm_vm *vm, uint64_t policy, = uint8_t *measurement) if (is_sev_snp_vm(vm)) { vm_enable_cap(vm, KVM_CAP_EXIT_HYPERCALL, BIT(KVM_HC_MAP_GPA_RANGE)); =20 + if (is_savic_enabled()) + guest_apic_pages_init(vm); + snp_vm_launch_start(vm, policy); =20 snp_vm_launch_update(vm); --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from BN1PR04CU002.outbound.protection.outlook.com (mail-eastus2azon11010010.outbound.protection.outlook.com [52.101.56.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2EADF30DD29; Tue, 23 Sep 2025 05:17:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.56.10 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604661; cv=fail; b=enOvme9zY0D40WKHb90OrLvNeD8TcymILLPWWd8+NXXNqeTnjlgmaK/4gWxnzZyf0ijvWsvbrfxBNAblOpZsHXZHfZuycfgsyT9LXqXbwCDXqWUmKAoE22O4UwZabNRGBn1+QWWbGpqQRzyqneepKLkEKpB1T7RodVXHQl88lGk= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604661; c=relaxed/simple; bh=zrXyPWBUFrjrbghIthUK6XLiXBfcujFIdzK1rOIW73Q=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=bLZs8f0EBJRTGZAPzPOeeTEXVBg7OIxCHSs6LxSQm0CBSdc1uE70+yCze0zDrNcxJs58S+8mJ8CzbQ3o3ibIngo6mCcUEqEoS3+myxedu4NzTJBvsn5SCNTA9Jh9tP+xVUozW0rtapX4tqUnu4DRapsa+06sJbtg7/HjCGqWTKU= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=hvufsxrs; arc=fail smtp.client-ip=52.101.56.10 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="hvufsxrs" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=vsZA0i5REaQgYsbZtlXe+svvIvpwH98RwQOr4PRLEso0w3nGjaDFccX5FBNf/GRcD++ROKCIKKskkn/q+8vDgyfm21kd+ArWuEjtwW61ZLpMl4gqRT9klKBS+tO6f/3lste0FXeZNASunh0aUcmHdrnHwZmAelh01CZMI+qUH4hnBvG5qTz/pyuWktunmmXBMmVBGHb/bVmYn1ySU79O1KkzZQ99f9DSGCgLZNGBq0xdWE0PDcdpkgUdeCwtLU7JdkU/Ohl2UmMzog8v1st7UroO1ZYCOu5mrNd5fbTJGVr/ZdSzh/v3Sn5rhwPxFSORh5LGPKHDMAhU3i0L/9Zjww== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=uWKiSKcGqO9bHqfapJCMvbRpFALtusXfkepJeqAelCA=; b=amHJ1kOBKqk7bC3RWDvfE5ahVn4b/RwllWP5MYiRSg1vQV/CzQOWNWxMedosYeLFD8hkFZ/vX/N99CA8Gx7nw04SSPI7n4BQbbvmNmTUEnLi6fCi9khqZ4NgY3O46Fi/ghnXDzu3sGmqPinsAUSREIs0h8bCwr/mqC8b0aRORoDzy/ACTGeKHAW+yPKoH5/eeNFFKgwn7aZqC/P0h+BOb3v6EiN7VYXQcc2YXDrtwFIzBT3o12BZ/P395IgSstGi8lFN3wQ3EXbv0L/mEysIe/EsDbksNm8pRv4Nyu/iV4NtJvuHft78upXw8fC6RjW7KiPHN3ckbkxL4ib0o1CRUw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=uWKiSKcGqO9bHqfapJCMvbRpFALtusXfkepJeqAelCA=; b=hvufsxrsW83T1qeKeN8jLivoVXF+8BbU9NL2biL9BtWJmfIW+nfpZPwqFsVTL8QY5XRDVGUfuDPZJkKOQe066AioyHO0qXUSs6R8Sz3mgyPjzdgymcayO3LZ4frcmR6/7rjrvP5lEktpgz3mqMDgEJ1/BKt8cea66D6A1Kjz068= Received: from CH2PR15CA0010.namprd15.prod.outlook.com (2603:10b6:610:51::20) by PH0PR12MB7471.namprd12.prod.outlook.com (2603:10b6:510:1e9::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.19; Tue, 23 Sep 2025 05:17:34 +0000 Received: from CH2PEPF0000013B.namprd02.prod.outlook.com (2603:10b6:610:51:cafe::c3) by CH2PR15CA0010.outlook.office365.com (2603:10b6:610:51::20) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.19 via Frontend Transport; Tue, 23 Sep 2025 05:17:33 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF0000013B.mail.protection.outlook.com (10.167.244.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:17:33 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:17:14 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 25/35] KVM: selftests: Add #VC handler for unaccelerated Secure AVIC MSRs Date: Tue, 23 Sep 2025 10:39:32 +0530 Message-ID: <20250923050942.206116-26-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF0000013B:EE_|PH0PR12MB7471:EE_ X-MS-Office365-Filtering-Correlation-Id: 93956914-316d-4821-28a8-08ddfa60807c X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|36860700013|82310400026|376014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?nBBq2gB2boBS6kRDvpQ3WtUZx/HrkSPBkahiAYd7KYMFTgTQRLUb8N31YQ99?= =?us-ascii?Q?PtEbSE56UhoV0sGEO9SSRw+GaoOThtiaHLX7MROeSlaSc3zhidvd/9OTEaSq?= =?us-ascii?Q?xPVfZgac+Ut9M6wksqpSdtacyYgE95IA/vQsuQyotN94Gq3YUEyfiILbaVV+?= =?us-ascii?Q?6k3b5NQrxaMVsKjTjSBb4kfniJGULoEUabcexefb2yXjF99s/O6oSg/M9K3v?= =?us-ascii?Q?L/2hb5HE12qrL0OIXOp8yL1DOXXMINuwOWpRWNdXT5p4qAgiofp8iqv31CGT?= =?us-ascii?Q?bKYVAR4TYRdLEFNpRVxxvb9qP432W//KpKQ7NBWb12B4JZWkSc1JDB5mRKzz?= =?us-ascii?Q?aYpS6rvfKSO/6scs2ifNIJZ9q5wHMvrVw09p9Q1XhttYsyKQLEuZaeWxxQ1Z?= =?us-ascii?Q?xAoK/P1tP71Vch2wjsOc8a6pJZ1Wa+1osiPyD/TPBrAW5XGl6NNofhz3zqd/?= =?us-ascii?Q?soh8P5IGO8n1cx9bAkUA8SA70e71HVTrv/a4zVXtQtAuFbAzOKxwAUnwQ6hh?= =?us-ascii?Q?iuwyXq1lM65i7EYgmuXrdTxP+4F+qKhwLxiPHrXM6yqooUAzKNb8iCYrDmGU?= =?us-ascii?Q?Th50e3I8yH9o5z+CFH4uevHe2nWtJbeNLX236AZUaUWNKZfmTjU++1bN4coX?= =?us-ascii?Q?+5/D19ziknCErce35MAWWGZBJRUZVlb5cKbPkWfvTyqf4IZvL4alZmLop9Qt?= =?us-ascii?Q?MxBoU/m3eH9AJ3Ne9XfrleP/PiX7WF0Lk9YGl1oGEoCh63I6A8f/E8c3iVy2?= =?us-ascii?Q?SP6+TpNFYi/t1zALz08u3pgatN/vslTIphmMspvx4d/4icZ6nYrGAS9deFyA?= =?us-ascii?Q?i+wyed9aGxz8+MlS2gxMoV0/XcAd73tURskUZavgWOT3D4Wny5Vf6OMNX/jv?= =?us-ascii?Q?g9x05uX9buMspPPHVJRma5TK/21V2cfl4BrdFQorrcnFy9vHD8klOgPk0bvw?= =?us-ascii?Q?M9PfiQ8nKCYfwBgVHpL6JzY/T3bk8Y0FRjxDHyZw8UMpB1HQI9iW06aKgjjd?= =?us-ascii?Q?f5r1WPTTlqSgTQpa5jheMFjfzf1vKO/Cz4M8e2FXZD7keY5daJsrEAuzwfq8?= =?us-ascii?Q?Y7ojLGhBIlJT5RxzZ5VpsTOMbTML/obkBHweg+BycIHeK58APUDNh4fFI+iL?= =?us-ascii?Q?3mRS9P1Ax65/8c3gx8ZUo9g7CeR0TBN4YE1PEU5LSEGvO8bnX7SU9kMAdY5r?= =?us-ascii?Q?yMfKBnC5Vla5A+HNE+zLP3YysCzY3gHTrsNPQ92Dnn1saJy3+iTiB3mADb0n?= =?us-ascii?Q?hP4ucwqizjV9Jp0CIFuJm9RbL79/M8MIk0MRnL/WxPx3uMxHw/W6cZLoYKCq?= =?us-ascii?Q?cUVT8oHOaBpaQR8WUMTIzjUG0uR0/mD0Lu79xi7QmTvBJuaviuddQPQgCCMy?= =?us-ascii?Q?pFJ+dYwvwy/kmbdycfYZYLviJ4I8R484zDvF8KAVyJ6h66/OYEgNit47/uM/?= =?us-ascii?Q?2svVhBF871+sSiA0neG2Vfhchw16/VZ5TtT9H6dIEYeD/tWSS9z9f2rZMr52?= =?us-ascii?Q?BolzOeqGEZe+VF/tlXJwmIPJfmXvU5kTtSog?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(36860700013)(82310400026)(376014);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:17:33.5311 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 93956914-316d-4821-28a8-08ddfa60807c X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF0000013B.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR12MB7471 Content-Type: text/plain; charset="utf-8" When Secure AVIC (SAVIC) is enabled for an SEV-SNP guest, most APIC register accesses are accelerated via a guest-visible backing page. However, not all APIC registers are handled this way. Accesses to certain "unaccelerated" registers via RDMSR or WRMSR are designed to trigger a #VC (Virtualization Exception) with the new exit code SVM_EXIT_AVIC_UNACCELERATED_ACCESS. Without a handler for this exit code, any guest attempt to access these MSRs would result in an unhandled fault, crashing the guest. Implement the necessary #VC handler to emulate these accesses. The new handler (handle_savic_unaccel_access) emulates the MSR operation. For MSR reads/writes, it applies different strategies based on the register: - Read/Write APIC timer, APIC Spurious Interrupt Vector and LVT registers' from the hypervisor using the existing paravirtual MSR interface as LVT and APIC timers are emulated by the hypervisor. - Propagate EOI write to the hypervisor. This is required for acknowledging emulated IOAPIC interrupts. - Keep APIC_ID in-sync between the guest and the hypervisor. - For rest of the valid APIC register writes, write the value only in the APIC backing page of the guest vCPU. This emulation provides the necessary glue to allow guest code to run seamlessly when SAVIC is active, enabling comprehensive testing of APIC functionality in this mode. Signed-off-by: Neeraj Upadhyay --- .../testing/selftests/kvm/include/x86/apic.h | 1 + .../testing/selftests/kvm/include/x86/savic.h | 1 + tools/testing/selftests/kvm/lib/x86/savic.c | 145 ++++++++++++++++++ 3 files changed, 147 insertions(+) diff --git a/tools/testing/selftests/kvm/include/x86/apic.h b/tools/testing= /selftests/kvm/include/x86/apic.h index 6ba5d0545bf8..aa3a5d54c404 100644 --- a/tools/testing/selftests/kvm/include/x86/apic.h +++ b/tools/testing/selftests/kvm/include/x86/apic.h @@ -33,6 +33,7 @@ #define APIC_SPIV 0xF0 #define APIC_SPIV_FOCUS_DISABLED (1 << 9) #define APIC_SPIV_APIC_ENABLED (1 << 8) +#define APIC_TMR 0x180 #define APIC_IRR 0x200 #define APIC_ICR 0x300 #define APIC_LVTCMCI 0x2f0 diff --git a/tools/testing/selftests/kvm/include/x86/savic.h b/tools/testin= g/selftests/kvm/include/x86/savic.h index 1ab92dad00c1..238d7450ab6e 100644 --- a/tools/testing/selftests/kvm/include/x86/savic.h +++ b/tools/testing/selftests/kvm/include/x86/savic.h @@ -16,4 +16,5 @@ void savic_hv_write_reg(uint32_t reg, uint64_t val); uint64_t savic_hv_read_reg(uint32_t reg); void savic_enable(void); int savic_nr_pages_required(uint64_t page_size); +void savic_vc_handler(struct ex_regs *regs); #endif diff --git a/tools/testing/selftests/kvm/lib/x86/savic.c b/tools/testing/se= lftests/kvm/lib/x86/savic.c index 72ad43d4797e..9b1ea5d15338 100644 --- a/tools/testing/selftests/kvm/lib/x86/savic.c +++ b/tools/testing/selftests/kvm/lib/x86/savic.c @@ -41,6 +41,8 @@ enum lapic_lvt_entry { #define MSR_AMD64_SECURE_AVIC_EN_BIT 0 #define MSR_AMD64_SECURE_AVIC_ALLOWED_NMI_BIT 1 =20 +#define SVM_EXIT_AVIC_UNACCELERATED_ACCESS 0x402 + /* * Initial pool of guest apic backing page. */ @@ -203,3 +205,146 @@ void savic_enable(void) "SAVIC Control msr unexpected val : 0x%lx, expected : 0x%lx", savic_ctrl_msr_val, exp_msr_val); } + +static bool savic_reg_access_is_trapped(uint32_t reg) +{ + switch (reg) { + case APIC_ID: + case APIC_TASKPRI: + case APIC_EOI: + case APIC_LDR: + case APIC_SPIV: + case APIC_ICR: + case APIC_ICR2: + case APIC_LVTT: + case APIC_LVTTHMR: + case APIC_LVTPC: + case APIC_LVT0: + case APIC_LVT1: + case APIC_LVTERR: + case APIC_TMICT: + case APIC_TDCR: + return true; + case APIC_LVR: + case APIC_PROCPRI: + case APIC_TMR: + case APIC_IRR ... APIC_IRR + 0x70: + case APIC_TMCCT: + return false; + default: + return false; + } +} + +static void savic_unaccel_apic_msrs_read(struct guest_apic_page *apic_page, + uint32_t reg, uint64_t *val) +{ + switch (reg) { + case APIC_TMICT: + case APIC_TMCCT: + case APIC_TDCR: + case APIC_LVTT: + case APIC_LVTTHMR: + case APIC_LVTPC: + case APIC_LVT0: + case APIC_LVT1: + case APIC_LVTERR: + *val =3D savic_hv_read_reg(reg); + break; + default: + __GUEST_ASSERT(0, "Unexpected unaccelerated read trap for reg: %x\n", re= g); + } +} + +static void savic_unaccel_apic_msrs_write(struct guest_apic_page *apic_pag= e, + uint32_t reg, uint64_t val) +{ + switch (reg) { + /* + * APIC_ID value is in sync between guest apic backing page and + * hv. + * LVT* registers and APIC timer register updates are propagated to hv. + */ + case APIC_ID: + case APIC_LVTT: + case APIC_LVTTHMR: + case APIC_LVTPC: + case APIC_LVT0: + case APIC_LVT1: + case APIC_LVTERR: + case APIC_SPIV: + case APIC_TMICT: + case APIC_TMCCT: + case APIC_TDCR: + savic_write_reg(apic_page, reg, val); + savic_hv_write_reg(reg, val); + break; + /* + * LDR is derived in hv from APIC_ID. + * TPR, IRR information is not propagated to hv. + */ + case APIC_LDR: + case APIC_TASKPRI: + case APIC_IRR: + savic_write_reg(apic_page, reg, val); + break; + /* + * EOI write need to be propagated to hv for level-triggered + * interrupts. + */ + case APIC_EOI: + savic_hv_write_reg(reg, val); + break; + default: + __GUEST_ASSERT(0, "Write not permitted for reg: %x\n", reg); + } +} + +static void handle_savic_unaccel_access(struct ex_regs *regs) +{ + bool write;; + uint64_t msr =3D regs->rcx; + uint32_t reg =3D (msr - APIC_BASE_MSR) << 4; + struct guest_apic_page *apic_page; + uint64_t low =3D regs->rax; + uint64_t high =3D regs->rdx; + uint64_t val =3D 0; + + apic_page =3D &apic_page_pool->guest_apic_page[x2apic_read_reg(APIC_ID)]; + + switch (msr) { + case APIC_BASE_MSR ... APIC_BASE_MSR + 0xff: + if (savic_reg_access_is_trapped(reg)) + write =3D *((uint8_t *)regs->rip - 1) =3D=3D 0x30; + else + write =3D *((uint8_t *)regs->rip + 1) =3D=3D 0x30; + if (write) { + savic_unaccel_apic_msrs_write(apic_page, reg, + high << 32 | low); + } else { + savic_unaccel_apic_msrs_read(apic_page, reg, &val); + regs->rax =3D val & ((1ULL << 32) - 1); + regs->rdx =3D val >> 32; + } + if (!savic_reg_access_is_trapped(reg)) + regs->rip +=3D 2; + break; + default: + __GUEST_ASSERT(0, "Unknown unaccelerated msr: %lx\n", msr); + break; + } +} + +void savic_vc_handler(struct ex_regs *regs) +{ + uint64_t exit_code =3D regs->error_code; + + switch (exit_code) { + case SVM_EXIT_AVIC_UNACCELERATED_ACCESS: + handle_savic_unaccel_access(regs); + break; + default: + sev_es_vc_handler(regs); + break; + } +} --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from SJ2PR03CU001.outbound.protection.outlook.com (mail-westusazon11012007.outbound.protection.outlook.com [52.101.43.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B8E9726CE15; Tue, 23 Sep 2025 05:17:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.43.7 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604676; cv=fail; b=LO8hBdACXkI4w9kQJ5vq3Nck9T/abOHXKLFYs4Z+H/GYGIxNQWLFj2iMdfNQcxsau6EGgtNqLVLi2HI/+tpmtfB/FmZ62Xdnxwt26EpZ5zMno2izH3LvKZoFmOeq4UqTMrdVfUAWw0+Ul5PIoI6tZ0hQFsFj2E92INfiAnP0fc8= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604676; c=relaxed/simple; bh=HKNm0TiNb1X7rsoPzdVc1YxSCnKQ3CHO0HO+wigMUh0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=pR2qmHXeu3joDpeDbjQU2mr2bwbR0Qu0EpYOcGiJuF2ZTVIkx7qDpK4bgvhjjTH6DSeAXzIGxapuHTKmefRJlLiO8vyFQAYeEdoNd2bO8m++0hJyRUUi/L8emw2kLGfXLUoH5ax24jsaW1LoQV4cTUOKMbmzZhE8Xl30S+0mqW0= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=l1wKSR9Z; arc=fail smtp.client-ip=52.101.43.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="l1wKSR9Z" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=y8NQCuANWkoSUyalbjLjeBKVzKVyobue79VeX1nwllk74rEbpyJswKkmM3f55I6iD8v8hqsxgUCxqCJeSCq54aIxG0QPmZJp6FuYVmy1OOYgOLvtI6coGsuw+u0u7R/f5vIzKC7Lu9Z0vr10L+Jeull1ezy7WA7VMVnrX0+FArFD+Dm5XZHOTvhg8evheJ8Dt8qCkzviYvIEMZWKEyU4R4rSl/QwiZky6OAVO+IlKcm6q+oCdpfHNMpb9GyUxvRODGdhTZaUXWKz4X/YlPrZrlWcy67yLhqy2E1xBg3w6mUMGYw+mpvbmyWs1ZjgVe16hp+zO6HrCAfM9zhn0AUHng== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=zL1CJFgDZtAXdEDSYTRIiluubSH8WJxzxWUCw7ofpSk=; b=v30FpDYFP2zSqIzFP0R2XDG3UAVEan/wOONvYOe/KRr8j7mPs7Wp9aB9BrbFC8rnjVMKbr+8Xq02rKOgyflNva+j32xTJVt6a/KDuzMszQ4hi9CXAi7c0AHdBkmRoppVKw4YFkBZw9oNqU5x5x+Q1ni2WwyFH3WdEUvq0KrAqesy7laDdSC4jNWCgipoqVjxTTo6fIVkVONIqEzGgALeIhRsB7dHJpNoxKnPSXUvIZfr7GBdOKBJb63Jke216vV44xGcl2OwWc6bDxuHQHe3If4ijdnf6gzRiCaVwmSZX6+9YUwe/6o4CCEqFUZM1SqzJvzZCjqVWmQcENCsK0dHIw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=zL1CJFgDZtAXdEDSYTRIiluubSH8WJxzxWUCw7ofpSk=; b=l1wKSR9ZCr+UkYpMKfp6ZIIub/vsooG4qojQepCXR7lI3PKowxLxJnXTPrTQs/2OvZ6zXTWTuaOc7s6Dzc6zY+hnmXM5Ar1YzuZ4OAtGJ53W0tfjt2CIlK9ZDPO+gMkqRvmY465glbevD9apWked+mWWTTovGS0uytmPcxyY7ww= Received: from CH2PR15CA0028.namprd15.prod.outlook.com (2603:10b6:610:51::38) by MN2PR12MB4287.namprd12.prod.outlook.com (2603:10b6:208:1dd::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.19; Tue, 23 Sep 2025 05:17:38 +0000 Received: from CH2PEPF0000013B.namprd02.prod.outlook.com (2603:10b6:610:51:cafe::64) by CH2PR15CA0028.outlook.office365.com (2603:10b6:610:51::38) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:17:38 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by CH2PEPF0000013B.mail.protection.outlook.com (10.167.244.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:17:38 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:17:32 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 26/35] KVM: selftests: Add IPI handling support for Secure AVIC Date: Tue, 23 Sep 2025 10:39:33 +0530 Message-ID: <20250923050942.206116-27-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PEPF0000013B:EE_|MN2PR12MB4287:EE_ X-MS-Office365-Filtering-Correlation-Id: cf6441bf-2366-47c8-4c60-08ddfa608389 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|36860700013|376014|82310400026; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?5gnWAPkkkmj96XxX3KyfL1qYK4Sb8GfwsGL/tt26wlWeNERWAoVj7hPwCyTc?= =?us-ascii?Q?4btNhrj4eedSzWAiswv1xtcg+Y/NqXppfTosyvvGmeQXlLoK9nHazCkt82ck?= =?us-ascii?Q?NdRcQsWOYGQyFhoRImQuMMmLc7mab7P2V6IM5PswJh3KMpztbryReHgcwQQ5?= =?us-ascii?Q?pYKpUtr92B1qA4D49x9k19T8AQUS83uHLcN1uE6lQ/Ch732BuVkH+YHqgUcX?= =?us-ascii?Q?C9fJeZ3dU5aPy+bcIx73GVc2aeBqXU2xa3i4tvjud7kIcnqUBvvxscZ/lyI7?= =?us-ascii?Q?R6HuDbBl0HOZN9lgXYPkqgz4/efQVXbwNZK5j/InHrXdYTBXEExgv+KGCztr?= =?us-ascii?Q?4RkZFi70SNH8V44QSnBr73etqvW0emdlRcbwGUBjCwk6zQf3npd0yT9mbsEO?= =?us-ascii?Q?3M65jZJxmRryjd8hpgomaOEcZnSw9q/qChxozEDoywltGQY8dvtadk+OGu6J?= =?us-ascii?Q?V1nQDlOhnWINUnZ5aSQARdeH9AI50dTv54uskLS4esedVjWYqyx4DG9dZFfH?= =?us-ascii?Q?YJkyqZpY83vDbhXDeZ5rs9Ds55h4a5MQ3vUL/ZFolt7Md2d88A7FdHd6pXWS?= =?us-ascii?Q?ZsScrPoYEeyLwnCLonLlx7rfiwk4x8h+5i2l/KOqiRU0ucUGF0PZo4Ilo/1R?= =?us-ascii?Q?OGYQP3yBiIMp9S+O1Ya+JM1zLyMzh85jnmZ+yJTWekZoRv45xiwwDUk5Loh3?= =?us-ascii?Q?UfLGAHVeOJmMNCg7VAt4d43h26Hv1SGNV5vFHk/CiOeJHl3Qy6iE+HFtuMDM?= =?us-ascii?Q?0b9y8Bt53k5TdnTFfiyHjAzzofmun4YObn4PkgB2OkrffMDJxzQnXqUK5XC9?= =?us-ascii?Q?Efeu4+SKtZKSdqwwTwUhOdy0HKuPO3HA7TR+D5LGgJlzQb3D5SW0I78GGkTg?= =?us-ascii?Q?M+O+1b1kp68jpCCqzBacWXKuLhYz1D6JrfTFgSNDFIoFCr94bxIWnNxXJS//?= =?us-ascii?Q?MrjfqUlN6DysTf9MhVhJhtXUXMRKFC4t2uZ2uJ0R8xAJmXv+3txD7nTyB1U0?= =?us-ascii?Q?vEneS4bSI/rTB6+aB/ll/WhzaGyxr1qRN9xYwwVpdd4cfifBQAAIXmddq+VF?= =?us-ascii?Q?JINFay6jeRmJWqZO+koVODJ1QPLOjdbyLdGQnuKjRr1fyLBssflIzBBTHzaA?= =?us-ascii?Q?AofOxH9siPkwFfLz2kVxDDhzRBHinEtY22R+DxaNyzEj4Hi5ZmOi48446+jM?= =?us-ascii?Q?gibZYDXbjP8jjWv+5C1DNc4Jh9Deq5D5PyzEdgjif9tcwzkP/k2F3pKovmaQ?= =?us-ascii?Q?xNnG5gLEEMezXz0zVDNQKrMwVpf0NTjYmB2lafqZR/xQaGi4pQS8RTLjtOP6?= =?us-ascii?Q?iyC8K2i8PaygrC51ZnEgfedQelR2mafy4Unfg2Sn2Emiyx8n1Etbr0qFqi6d?= =?us-ascii?Q?Hct+FNB9eweYpql+gBATzbXC/uPDVq1uTQJrjioolnfdi4iI0X/leswsLiUv?= =?us-ascii?Q?aOtBB9jb+rs+ICfpnzOngu/NFFj2JfeJTcS2DsZ5R24YHVcPfIPlFVmKJO3e?= =?us-ascii?Q?9JMiX3PaSd8MQv+2PzDZzVsnL98WLvaK7Zrt?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(36860700013)(376014)(82310400026);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:17:38.6532 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: cf6441bf-2366-47c8-4c60-08ddfa608389 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH2PEPF0000013B.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4287 Content-Type: text/plain; charset="utf-8" When a guest vCPU has Secure AVIC (SAVIC) enabled, an attempt to send an Inter-Processor Interrupt (IPI) by writing to the Interrupt Command Register (APIC_ICR) does not complete in hardware. Instead, it triggers a #VC exception with the exit code SVM_EXIT_AVIC_INCOMPLETE_IPI. This design delegates the responsibility of IPI delivery to the guest's #VC handler. Implement the necessary #VC handler to process these IPI requests, enabling multi-vCPU IPI communication for SAVIC guests. Add support for all IPI modes: physical and logical destination modes, as well as "broadcast" and "broadcast-but-self" destination shorthands. Inject the IPI into each target vCPU by directly setting the appropriate bit in the Interrupt Request Register (IRR) of its backing page. In addition, propagate the ICR write to the hypervisor via a VMGEXIT. This is crucial for KVM to perform actions like waking up a halted vCPU. APIC_ICR based NMI delivery is also supported via a the NMIReq field in the backing page. This functionality is a prerequisite for testing IPIs in SAVIC guests. It allows selftests like xapic_ipi_test to correctly validate IPI delivery for SAVIC enabled guests. Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/lib/x86/savic.c | 111 ++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/tools/testing/selftests/kvm/lib/x86/savic.c b/tools/testing/se= lftests/kvm/lib/x86/savic.c index 9b1ea5d15338..016e5e9e43f6 100644 --- a/tools/testing/selftests/kvm/lib/x86/savic.c +++ b/tools/testing/selftests/kvm/lib/x86/savic.c @@ -42,6 +42,12 @@ enum lapic_lvt_entry { #define MSR_AMD64_SECURE_AVIC_ALLOWED_NMI_BIT 1 =20 #define SVM_EXIT_AVIC_UNACCELERATED_ACCESS 0x402 +#define SVM_EXIT_AVIC_INCOMPLETE_IPI 0x401 + +#define REG_OFF(VEC) (VEC / 32 * 16) +#define VEC_POS(VEC) (VEC % 32) + +#define SAVIC_NMI_REQ_OFFSET 0x278 =20 /* * Initial pool of guest apic backing page. @@ -335,6 +341,104 @@ static void handle_savic_unaccel_access(struct ex_reg= s *regs) } } =20 +static void send_ipi(int cpu, int vector, bool nmi) +{ + struct guest_apic_page *apic_page; + + apic_page =3D &apic_page_pool->guest_apic_page[cpu]; + + if (nmi) + savic_write_reg(apic_page, SAVIC_NMI_REQ_OFFSET, 1); + else + savic_write_reg(apic_page, APIC_IRR + REG_OFF(vector), BIT(VEC_POS(vecto= r))); +} + +static bool is_cpu_present(int cpu) +{ + struct guest_apic_page *apic_page; + + if (cpu >=3D KVM_MAX_VCPUS) + return false; + + apic_page =3D &apic_page_pool->guest_apic_page[cpu]; + + return savic_read_reg(apic_page, APIC_ID) !=3D 0; +} + +static void savic_send_ipi_all_but(int vector, bool nmi) +{ + int cpu; + int mycpu =3D x2apic_read_reg(APIC_ID); + + for (cpu =3D 0; cpu < KVM_MAX_VCPUS; cpu++) { + if (cpu =3D=3D mycpu) + continue; + if (!(cpu =3D=3D 0 || is_cpu_present(cpu))) + break; + send_ipi(cpu, vector, nmi); + } +} + +static bool ipi_match_dest(uint32_t dest, bool logical, int dest_cpu) +{ + struct guest_apic_page *apic_page; + + apic_page =3D &apic_page_pool->guest_apic_page[dest_cpu]; + uint32_t ldr; + + if (logical) { + ldr =3D savic_read_reg(apic_page, APIC_LDR); + return ((ldr >> 16) =3D=3D (dest >> 16)) && + (ldr & dest & 0xffff) !=3D 0; + } else { + return dest =3D=3D savic_read_reg(apic_page, APIC_ID); + } +} + +static void savic_send_ipi_target(uint32_t dest, int vector, bool logical, + bool nmi) +{ + int cpu; + int mycpu =3D x2apic_read_reg(APIC_ID); + + for (cpu =3D 0; cpu < KVM_MAX_VCPUS; cpu++) { + if (cpu =3D=3D mycpu) + continue; + if (!(cpu =3D=3D 0 || is_cpu_present(cpu))) + break; + if (ipi_match_dest(dest, logical, cpu)) + send_ipi(cpu, vector, nmi); + } +} + +static void savic_handle_icr_write(uint64_t icr_data) +{ + int dsh =3D icr_data & APIC_DEST_ALLBUT; + int vector =3D icr_data & APIC_VECTOR_MASK; + bool logical =3D icr_data & APIC_DEST_LOGICAL; + bool nmi =3D (icr_data & APIC_DM_FIXED_MASK) =3D=3D APIC_DM= _NMI; + uint64_t self_icr_data =3D APIC_DEST_SELF | APIC_INT_ASSERT | vector; + + if (nmi) + self_icr_data |=3D APIC_DM_NMI; + + switch (dsh) { + case APIC_DEST_ALLINC: + savic_send_ipi_all_but(vector, nmi); + savic_hv_write_reg(APIC_ICR, icr_data); + x2apic_write_reg(APIC_ICR, self_icr_data); + break; + case APIC_DEST_ALLBUT: + savic_send_ipi_all_but(vector, nmi); + savic_hv_write_reg(APIC_ICR, icr_data); + break; + default: + savic_send_ipi_target(icr_data >> 32, vector, logical, nmi); + savic_hv_write_reg(APIC_ICR, icr_data); + break; + } +} + void savic_vc_handler(struct ex_regs *regs) { uint64_t exit_code =3D regs->error_code; @@ -343,6 +447,13 @@ void savic_vc_handler(struct ex_regs *regs) case SVM_EXIT_AVIC_UNACCELERATED_ACCESS: handle_savic_unaccel_access(regs); break; + case SVM_EXIT_AVIC_INCOMPLETE_IPI: + uint64_t icr_data =3D regs->rax | (regs->rdx << 32); + uint32_t reg =3D (regs->rcx - APIC_BASE_MSR) << 4; + + GUEST_ASSERT(reg =3D=3D APIC_ICR); + savic_handle_icr_write(icr_data); + break; default: sev_es_vc_handler(regs); break; --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from SN4PR0501CU005.outbound.protection.outlook.com (mail-southcentralusazon11011058.outbound.protection.outlook.com [40.93.194.58]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A86991A3142; Tue, 23 Sep 2025 05:18:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.194.58 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604693; cv=fail; b=liyXaai6g1NuJCiHhHD0fHWS9eNQVfl23/Fx1i9hmvyJSkl4u2bkLc211ZLxfqxFkBTOSJRoLg5trkwMjJ1uRguZFOnKGcmhzUwObkiiotF59iUSeqP6RiM+s94rU3g0eM7UufDwTmusFLSc4aEWicJ6esXInrNy22e2ZfZnhW0= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604693; c=relaxed/simple; bh=KX+QENdWtr3ZV6Mkoh/DNY6C+y9GE0Q9ijz0elMvtjs=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=hgoWuL1P3uqemoTOioMILmJcWjPINoTYphFh3g1+L4l/P2OF3fJ9e5V68VGePSF0s8UkVCEj8NBuB17UYGbQtTnaw8YqVZq2SiV17y3EgmaQHEfWaPNyJBq9O6ZoIBJN5T4kA/+3Bcum+qLKXscxQQ3Vf/Dk01YEBL8aa/aj/lc= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=OCO6sNRS; arc=fail smtp.client-ip=40.93.194.58 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="OCO6sNRS" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=sRLyXXtlAIxYcdehVb64N4jk1w0r8uLc7m4xHoI6PiLXKsljCfgrJpqNHKTumyrdPZuWNIna/MRX0RQEDzaMB5pIGYCp4wwJkw85ZyGi8DW35CWe20l5dvaw/eyL2NVfPfCTZX2PecY8BH8zlkTb/TFKpbWyVi0u9oAzJRtnmguEjYlENMLnf1DrRbGuApMv0S2EW7NPh/I4/QfRGm6EMT/8olZ6Tdrfv5FsrQGJVO8KgOoJ1aePGSBdIhCE1yKSXWXftGu1N3HtreTTdTJ0Qu/ln4rm9i9b+hcWwcNU8zkY2gsPDTIzsyjRL3LLvs+5FC4uO1BwFAb1Qrn0pToJDw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=fBZG+hxak/+fUz0yvuwL273kO42JHHc7TBl1uKbEjVg=; b=PcGhjZRiQBY+qMxpF3jXX/vezbxWE1+691d1487G2z8+YCI+wZvTY5C/SAL0qRiiW8S/hR8YJhy0iYANkY+vfUQio/iivaK3l//DV4aEl7zKlIMs9yngwsYkPXvPx3gtClZzn06i4w28n57RwPoveNm/czqO4fLPZTm1eHMkabaOkqqw0U4FidoV303BshydMtW9fE52wvH8RdNXjKbSG7c9VfMA1kSWLaS03ictFSFX6JGqpAesw1+JZVc+ocDcrJR65KWygQn7+dmw9H1N9+CervINss/ZLh7Jqt4YZwMQRU3KvESPx1Z3nK5n5hT//5ygPAqQlgsaqMH+8LqAnQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=fBZG+hxak/+fUz0yvuwL273kO42JHHc7TBl1uKbEjVg=; b=OCO6sNRS2YrrL/ipebvNxUMgmIuMclbMFihBf8n3eWyxL7JLgp7QD2ZNzgrFfstzZuzGfwQttbvQMuneGFD728CfQ51yZnOBmhSknfcDvR+HdJoYYyN7k6VRzBfBerRbudG8D5uvmVCIRWb0Xj25DOYMeF+/Dz2ky37daJrUW7s= Received: from SJ0PR03CA0354.namprd03.prod.outlook.com (2603:10b6:a03:39c::29) by DM6PR12MB4339.namprd12.prod.outlook.com (2603:10b6:5:2af::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.14; Tue, 23 Sep 2025 05:18:04 +0000 Received: from SJ5PEPF000001D1.namprd05.prod.outlook.com (2603:10b6:a03:39c:cafe::16) by SJ0PR03CA0354.outlook.office365.com (2603:10b6:a03:39c::29) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:18:04 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by SJ5PEPF000001D1.mail.protection.outlook.com (10.167.242.53) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:18:04 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:17:49 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 27/35] KVM: selftests: Add args parameter to kvm_arch_vm_post_create() Date: Tue, 23 Sep 2025 10:39:34 +0530 Message-ID: <20250923050942.206116-28-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001D1:EE_|DM6PR12MB4339:EE_ X-MS-Office365-Filtering-Correlation-Id: 870b6b0d-444b-4425-ce66-08ddfa6092fd X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|376014|36860700013|82310400026; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?Zs0lPR0bsp//EnadEoRfOY7O8+8X0XdU3l7vlzwQg22WCxbHhkYbIdYUe8nu?= =?us-ascii?Q?UUQD6vejk8O3LUrPk03zc5Yvj5uoVJZ38gfFsD6PG5TTse7GehnC6OFQDmdD?= =?us-ascii?Q?kbXIhEmXBztZL4xjMnbMknYdoG3lkF7F+NsvoiOWaiq3hjvhpvaVsTjZyaU4?= =?us-ascii?Q?5zVxuLblfIBDWDmM/tkN3GTNqlRyqpxHaC5+Bh+Pl7YOyjdN2SByDVJvpdmw?= =?us-ascii?Q?ok+QBr4kmG5yrdMXMxNtadJxHi4VXobbr57uOyz1xthSJ9hBO1NPu2mHN6P1?= =?us-ascii?Q?cAqd+EM62DofVpThaOSFz4jVS4jg50Ix2uKHr0NO+Z8JNZ5p527K4mF0lAXY?= =?us-ascii?Q?M3sGZTnurBN8zAEsIXakHGom7AGwRo8hw4sQABZ6Qv/7mhunBwcBxC+9USNo?= =?us-ascii?Q?2PDLko/YfJu55DbHH1gkfuNKdfwMDChsdQ2NT4OjEEdhxC5SmnkJQX5wCJZx?= =?us-ascii?Q?PHp6AaD5ynxUUl1QlmHzc6v/SjQQi9awja0u0/Zy7fgun/dCfaQE5/OiXSOq?= =?us-ascii?Q?Q8fpJ6QOMJmaz4OwQzogqttT3OF4WJIrYD0CWzknjkiIwnr7YDsibm8WHNwU?= =?us-ascii?Q?wfiJ4o+gwpU/t4Jl8J0YSemE9z79EZ53laYeY7GUPM9jt+qGM7O6B9qleNml?= =?us-ascii?Q?x+kUxZ0zR5Os0/HGRSWRH1YSNFLOacQrMcMP99PpUeSJQTuzoRCwjQo41Jit?= =?us-ascii?Q?JnCS31ncPgiIrmLBC/5NKx8DjPCv0baFf0bFa654em9e9EjApBUupDvR4E3L?= =?us-ascii?Q?Y18Di2KzBz1GUtJrzGrl6fAIo+mTo+MTVRvX+3hYVUBQReoaFXZEd1sgA8B/?= =?us-ascii?Q?dZJfWTxqlfJWXlU78Jvzy0+O7rETG9dEKPtAVLnQUxk6qixy/VIuDc+eaXu2?= =?us-ascii?Q?poTwqeoUA6XkCddOBkw111YPJwNNQrkH/oe4kyJOxiMgXFe63QLLsPxrDc+p?= =?us-ascii?Q?8V3iB2ZmdVEgQc0/pmVojvFx2oyuXJADX+I+QWtIwU2DEXBAkQgcc4//cxZY?= =?us-ascii?Q?FwyjP2clA5d8d6dPt1HNFW1fnJP010yYyvwjLlOZY9C86M2EXWL0JhVtLnEQ?= =?us-ascii?Q?KZL33nPelhiM1Vr6iG3igEKuy7To2obs/FAQawYKoezW8hlnDrzYicKClUaT?= =?us-ascii?Q?F22uQp5CVhKUtwlFT1xRPyq7iS36yDk7N8xgOr/+BlSqk/VS5BgP9dJ02fP9?= =?us-ascii?Q?KlSqh4uofDXPAy9fnHwtfKmWI4Pcj81gygD5+oUhEFvrORP4opB2wJmqn4ph?= =?us-ascii?Q?TGHiXkMdQgeGIB2nm8xRWA3IGE+Qap469b1zeCGxsk3TMEDFZLEpEnLokcKe?= =?us-ascii?Q?jJgiTAPeDNg8eZHCezjX2VEJAV6bhv0lUIK6lVNa7PouJSsFurPRK7NKEACc?= =?us-ascii?Q?614KpaKUWutwG+vkqx+5/3ZhFmVNrihOpSdj4Kz2NqGmvQ/LYE7MrMvYYBRb?= =?us-ascii?Q?aQ4kOPoRpVYbl4evVicW2lu40LzdnuyRGnYzGnuy/HP8Zyr3cDFRPvZ/GDy3?= =?us-ascii?Q?3FOEFbU9tIoWl9zA/HPHGQnMpG0+YTR3PG9f?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(376014)(36860700013)(82310400026);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:18:04.4983 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 870b6b0d-444b-4425-ce66-08ddfa6092fd X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ5PEPF000001D1.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB4339 Content-Type: text/plain; charset="utf-8" The kvm_arch_vm_post_create() hook allows for architecture-specific setup to be performed immediately after a VM is created. However, it currently lacks a mechanism to pass custom configuration data from the test down to this setup phase. This is a limitation for features that require non-default initialization. For example, to test SEV-SNP with Secure AVIC (SAVIC), the desired VMSA features must be configured via the KVM_SEV_INIT2 ioctl. This ioctl is called within the x86 implementation of kvm_arch_vm_post_create(), but it currently uses hardcoded default values. To make this configurable, extend kvm_arch_vm_post_create() with a generic "void *args" parameter. The x86 implementation of kvm_arch_vm_post_create() now uses this argument to populate the "struct kvm_sev_init" for the "KVM_SEV_INIT2" ioctl. This refactoring makes the VM creation process more flexible and is a prerequisite for adding selftests for Secure AVIC guests. Signed-off-by: Neeraj Upadhyay --- .../testing/selftests/kvm/arm64/set_id_regs.c | 2 +- .../testing/selftests/kvm/include/kvm_util.h | 9 +++- tools/testing/selftests/kvm/include/x86/sev.h | 3 ++ tools/testing/selftests/kvm/lib/kvm_util.c | 51 +++++++++++++------ .../testing/selftests/kvm/lib/x86/processor.c | 6 ++- tools/testing/selftests/kvm/lib/x86/sev.c | 13 +++-- tools/testing/selftests/kvm/s390/cmma_test.c | 2 +- 7 files changed, 63 insertions(+), 23 deletions(-) diff --git a/tools/testing/selftests/kvm/arm64/set_id_regs.c b/tools/testin= g/selftests/kvm/arm64/set_id_regs.c index d3bf9204409c..b732ee9efbed 100644 --- a/tools/testing/selftests/kvm/arm64/set_id_regs.c +++ b/tools/testing/selftests/kvm/arm64/set_id_regs.c @@ -749,7 +749,7 @@ static void test_reset_preserves_id_regs(struct kvm_vcp= u *vcpu) ksft_test_result_pass("%s\n", __func__); } =20 -void kvm_arch_vm_post_create(struct kvm_vm *vm) +void kvm_arch_vm_post_create(struct kvm_vm *vm, void *args) { if (vm_check_cap(vm, KVM_CAP_ARM_MTE)) { vm_enable_cap(vm, KVM_CAP_ARM_MTE, 0); diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing= /selftests/kvm/include/kvm_util.h index 4a4f9621082d..e5f322994f44 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -992,6 +992,9 @@ static inline vm_paddr_t vm_phy_pages_alloc(struct kvm_= vm *vm, size_t num, struct kvm_vm *____vm_create(struct vm_shape shape); struct kvm_vm *__vm_create(struct vm_shape shape, uint32_t nr_runnable_vcp= us, uint64_t nr_extra_pages); +struct kvm_vm *__vm_create_with_args(struct vm_shape shape, + uint32_t nr_runnable_vcpus, uint64_t nr_extra_pages, + void *args); =20 static inline struct kvm_vm *vm_create_barebones(void) { @@ -1016,6 +1019,10 @@ static inline struct kvm_vm *vm_create(uint32_t nr_r= unnable_vcpus) struct kvm_vm *__vm_create_with_vcpus(struct vm_shape shape, uint32_t nr_v= cpus, uint64_t extra_mem_pages, void *guest_code, struct kvm_vcpu *vcpus[]); +struct kvm_vm *___vm_create_with_vcpus(struct vm_shape shape, + uint32_t nr_vcpus, uint64_t extra_mem_pages, + void *guest_code, struct kvm_vcpu *vcpus[], + void *args); =20 static inline struct kvm_vm *vm_create_with_vcpus(uint32_t nr_vcpus, void *guest_code, @@ -1261,7 +1268,7 @@ static inline int __vm_disable_nx_huge_pages(struct k= vm_vm *vm) */ void kvm_selftest_arch_init(void); =20 -void kvm_arch_vm_post_create(struct kvm_vm *vm); +void kvm_arch_vm_post_create(struct kvm_vm *vm, void *args); =20 bool vm_is_gpa_protected(struct kvm_vm *vm, vm_paddr_t paddr); =20 diff --git a/tools/testing/selftests/kvm/include/x86/sev.h b/tools/testing/= selftests/kvm/include/x86/sev.h index d9794f5c2c16..73a23043d6c5 100644 --- a/tools/testing/selftests/kvm/include/x86/sev.h +++ b/tools/testing/selftests/kvm/include/x86/sev.h @@ -72,6 +72,9 @@ void snp_vm_launch_start(struct kvm_vm *vm, uint64_t poli= cy); void snp_vm_launch_update(struct kvm_vm *vm); void snp_vm_launch_finish(struct kvm_vm *vm); =20 +struct kvm_vm *_vm_sev_create_with_one_vcpu(uint32_t type, void *guest_cod= e, + struct kvm_vcpu **cpu, + void *init_args); struct kvm_vm *vm_sev_create_with_one_vcpu(uint32_t type, void *guest_code, struct kvm_vcpu **cpu); void vm_sev_launch(struct kvm_vm *vm, uint64_t policy, uint8_t *measuremen= t); diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index 360f262f5f3f..23272f797f5f 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -473,8 +473,8 @@ static bool is_guest_memfd_required(struct vm_shape sha= pe) #endif } =20 -struct kvm_vm *__vm_create(struct vm_shape shape, uint32_t nr_runnable_vcp= us, - uint64_t nr_extra_pages) +static struct kvm_vm *___vm_create(struct vm_shape shape, uint32_t nr_runn= able_vcpus, + uint64_t nr_extra_pages, void *args) { uint64_t nr_pages =3D vm_nr_pages_required(shape, nr_runnable_vcpus, nr_extra_pages); @@ -519,7 +519,37 @@ struct kvm_vm *__vm_create(struct vm_shape shape, uint= 32_t nr_runnable_vcpus, guest_rng =3D new_guest_random_state(guest_random_seed); sync_global_to_guest(vm, guest_rng); =20 - kvm_arch_vm_post_create(vm); + kvm_arch_vm_post_create(vm, args); + + return vm; +} + +struct kvm_vm *__vm_create(struct vm_shape shape, uint32_t nr_runnable_vcp= us, + uint64_t nr_extra_pages) +{ + return ___vm_create(shape, nr_runnable_vcpus, nr_extra_pages, NULL); +} + +struct kvm_vm *__vm_create_with_args(struct vm_shape shape, uint32_t nr_ru= nnable_vcpus, + uint64_t nr_extra_pages, void *args) +{ + return ___vm_create(shape, nr_runnable_vcpus, nr_extra_pages, args); +} + +struct kvm_vm *___vm_create_with_vcpus(struct vm_shape shape, + uint32_t nr_vcpus, uint64_t extra_mem_pages, + void *guest_code, struct kvm_vcpu *vcpus[], + void *args) +{ + struct kvm_vm *vm; + int i; + + TEST_ASSERT(!nr_vcpus || vcpus, "Must provide vCPU array"); + + vm =3D ___vm_create(shape, nr_vcpus, extra_mem_pages, args); + + for (i =3D 0; i < nr_vcpus; ++i) + vcpus[i] =3D vm_vcpu_add(vm, i, guest_code); =20 return vm; } @@ -547,17 +577,8 @@ struct kvm_vm *__vm_create_with_vcpus(struct vm_shape = shape, uint32_t nr_vcpus, uint64_t extra_mem_pages, void *guest_code, struct kvm_vcpu *vcpus[]) { - struct kvm_vm *vm; - int i; - - TEST_ASSERT(!nr_vcpus || vcpus, "Must provide vCPU array"); - - vm =3D __vm_create(shape, nr_vcpus, extra_mem_pages); - - for (i =3D 0; i < nr_vcpus; ++i) - vcpus[i] =3D vm_vcpu_add(vm, i, guest_code); - - return vm; + return ___vm_create_with_vcpus(shape, nr_vcpus, extra_mem_pages, guest_co= de, + vcpus, NULL); } =20 struct kvm_vm *__vm_create_shape_with_one_vcpu(struct vm_shape shape, @@ -2357,7 +2378,7 @@ void kvm_get_stat(struct kvm_binary_stats *stats, con= st char *name, TEST_FAIL("Unable to find stat '%s'", name); } =20 -__weak void kvm_arch_vm_post_create(struct kvm_vm *vm) +__weak void kvm_arch_vm_post_create(struct kvm_vm *vm, void *args) { } =20 diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testin= g/selftests/kvm/lib/x86/processor.c index a33a09a161d3..fc57b948c041 100644 --- a/tools/testing/selftests/kvm/lib/x86/processor.c +++ b/tools/testing/selftests/kvm/lib/x86/processor.c @@ -9,6 +9,7 @@ #include "processor.h" #include "sev.h" #include "apic.h" +#include "savic.h" =20 #ifndef NUM_INTERRUPTS #define NUM_INTERRUPTS 256 @@ -631,7 +632,7 @@ void assert_on_unhandled_exception(struct kvm_vcpu *vcp= u) REPORT_GUEST_ASSERT(uc); } =20 -void kvm_arch_vm_post_create(struct kvm_vm *vm) +void kvm_arch_vm_post_create(struct kvm_vm *vm, void *sev_init_args) { int r; =20 @@ -648,7 +649,8 @@ void kvm_arch_vm_post_create(struct kvm_vm *vm) if (is_sev_vm(vm)) { struct kvm_sev_init init =3D { 0 }; =20 - vm_sev_ioctl(vm, KVM_SEV_INIT2, &init); + vm_sev_ioctl(vm, KVM_SEV_INIT2, sev_init_args ? + (struct kvm_sev_init *)sev_init_args : &init); } =20 r =3D __vm_ioctl(vm, KVM_GET_TSC_KHZ, NULL); diff --git a/tools/testing/selftests/kvm/lib/x86/sev.c b/tools/testing/self= tests/kvm/lib/x86/sev.c index 113f33ca40b2..257988fce107 100644 --- a/tools/testing/selftests/kvm/lib/x86/sev.c +++ b/tools/testing/selftests/kvm/lib/x86/sev.c @@ -260,8 +260,9 @@ void snp_vm_launch_finish(struct kvm_vm *vm) vm_sev_ioctl(vm, KVM_SEV_SNP_LAUNCH_FINISH, &launch_finish); } =20 -struct kvm_vm *vm_sev_create_with_one_vcpu(uint32_t type, void *guest_code, - struct kvm_vcpu **cpu) +struct kvm_vm *_vm_sev_create_with_one_vcpu(uint32_t type, void *guest_cod= e, + struct kvm_vcpu **cpu, + void *init_args) { struct vm_shape shape =3D { .mode =3D VM_MODE_DEFAULT, @@ -270,7 +271,7 @@ struct kvm_vm *vm_sev_create_with_one_vcpu(uint32_t typ= e, void *guest_code, struct kvm_vm *vm; struct kvm_vcpu *cpus[1]; =20 - vm =3D __vm_create_with_vcpus(shape, 1, 0, guest_code, cpus); + vm =3D ___vm_create_with_vcpus(shape, 1, 0, guest_code, cpus, init_args); *cpu =3D cpus[0]; =20 return vm; @@ -288,6 +289,12 @@ static bool is_savic_enabled(void) return supported_vmsa_features & BIT_ULL(SVM_FEAT_SECURE_AVIC); } =20 +struct kvm_vm *vm_sev_create_with_one_vcpu(uint32_t type, void *guest_code, + struct kvm_vcpu **cpu) +{ + return _vm_sev_create_with_one_vcpu(type, guest_code, cpu, NULL); +} + void vm_sev_launch(struct kvm_vm *vm, uint64_t policy, uint8_t *measuremen= t) { if (is_sev_es_vm(vm)) diff --git a/tools/testing/selftests/kvm/s390/cmma_test.c b/tools/testing/s= elftests/kvm/s390/cmma_test.c index 85cc8c18d6e7..0476dace3473 100644 --- a/tools/testing/selftests/kvm/s390/cmma_test.c +++ b/tools/testing/selftests/kvm/s390/cmma_test.c @@ -145,7 +145,7 @@ static void finish_vm_setup(struct kvm_vm *vm) slot0 =3D memslot2region(vm, 0); ucall_init(vm, slot0->region.guest_phys_addr + slot0->region.memory_size); =20 - kvm_arch_vm_post_create(vm); + kvm_arch_vm_post_create(vm, NULL); } =20 static struct kvm_vm *create_vm_two_memslots(void) --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from CH1PR05CU001.outbound.protection.outlook.com (mail-northcentralusazon11010069.outbound.protection.outlook.com [52.101.193.69]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A6A0330DD00; Tue, 23 Sep 2025 05:18:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.193.69 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604715; cv=fail; b=VYLue8yiOU8zpcejg3gwWEMJNhIyBlmwTgDbib8+fv9bxQxzMqAlX7SXQ5dCMMJlwTh/S2k+6ZXJwKAu0Xynh08YHCX3sVl++h6+hWnb7s2ZZUfhmd4FEnNIukE8w3ArBEQ7aTrRSKVjFfl2ohPXF1aaZDiqtueVUiTQd9YjvwU= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604715; c=relaxed/simple; bh=SoBW1GXPliZAFoXuaD6SY23K6VIk1FXlAO3E5rhbtvk=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ED3KQZJHoC0sxPoK4C9Ie2E666gVdDr8fnoHKH5aDYcm4aiEj126RUR1Bie3DHPaSlThB1SV6NdsgYmJwVa2tyJe1w2I6W//4qO9nX6u+PgcNAZ+PFjTwLS6wAPpIcDifngd9+3nitHw9Km2+vHbttDxo8+aDjTJRUprAJK359k= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=g+hddDqc; arc=fail smtp.client-ip=52.101.193.69 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="g+hddDqc" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=CneZ9GJMEkJyUUKxwLW3lzDxizOdcNd7JO62jkAfWC53+dF2VRCVpR5pgHmRqZG1j9uK6ZDNm6BOsmmdIgj7h0t2S/DLvr2ZMSF1wavJ0dcrU7RB8zxFiXqvwxNaJEMqr7090IxBry3wuCmoYMLyMhHv9XxjdTp2qIRkYZ0j2Kjn3T8kV0CSNziPCzpwDex36OPdEm+ZmDylhoQjyQE9rIIZdsSFPzt5lYemhlC6LO2rwgw/c7hCvjwhbhs8QSyxzXa1ow07PYyO5c4YO5ckenSagZamKn5nZr4UFa8GGn5YCBf/yzJFYXGUkMIQH65KZK2sgbP0K/8Y1pta9mwTQQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=s2TA0sQ7cMworMtQI4Jwe5ToMOstwAkJ41LIjnxFxLw=; b=ES2Wqzjz0y/Q+ESuPPJPmSt5rdQXyConGb2g5baJc7zC/xtA0BtLrRwuc52qpTJyAjsH1OIJJDsectY0Pw+JSHvKAKzFgHqTH9wdY1bxxjjT/lsUjKWkU740+E9YiA9s4aTniqxxDeGBGmb0VJELIZXUBu4tjuhoYpHlJGIhFcMfyXa0yq4nnPdD2SUbH4jSrmbzKLvyOO3MaUgrIww3c3I2UGa5YKtaGMzJWD0/5VNcJSe6weC01qiez2ntxeo61TFbOVbrrRbUAdPFXRNbbNXCp1rQ7ZOgKgKJaS0+CdLyppxalrvpdHa0KvuFFwQlGZctfVccgTasxl/xg0oMqw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=s2TA0sQ7cMworMtQI4Jwe5ToMOstwAkJ41LIjnxFxLw=; b=g+hddDqciS2z+92VHIyuMAtqAcOTVfRCKrBxLvinLkunXGrpHe/5uOaoFvrw9NoPJfdUHiXMfbUtb4x5RB3Pm8Uq5W2Z2KyF/w1ZN8o47D/OCHIWook8rOHQ5iHVNUvgEs22eqi154YriljKdDF/tC/OGumQpAnJyr5rHr6UlPw= Received: from SJ0PR03CA0008.namprd03.prod.outlook.com (2603:10b6:a03:33a::13) by CY1PR12MB9697.namprd12.prod.outlook.com (2603:10b6:930:107::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.20; Tue, 23 Sep 2025 05:18:29 +0000 Received: from SJ5PEPF000001D5.namprd05.prod.outlook.com (2603:10b6:a03:33a:cafe::fd) by SJ0PR03CA0008.outlook.office365.com (2603:10b6:a03:33a::13) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:18:29 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by SJ5PEPF000001D5.mail.protection.outlook.com (10.167.242.57) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:18:29 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:18:07 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 28/35] KVM: selftests: Add GHCB call for SAVIC backing page notification Date: Tue, 23 Sep 2025 10:39:35 +0530 Message-ID: <20250923050942.206116-29-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001D5:EE_|CY1PR12MB9697:EE_ X-MS-Office365-Filtering-Correlation-Id: a95aac2a-9ced-4a4d-c515-08ddfa60a1dc X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|376014|36860700013|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?ev+1ZW4t+abkKnzKNSgztNaKNY6BuL2f7lnWjWD71jo+s1RDdXIoIH9h8fR5?= =?us-ascii?Q?uzuex2AXIpgxTbkRFWJYntH+a4CO0amC++sdb1/K4resy9n9Qeq6H0iC6MjG?= =?us-ascii?Q?S43QSRsxIeDC1KQdArKfvlW1q1S+L7pqCuSf7uxkSIazoBozvhVaBj7j7Qja?= =?us-ascii?Q?5+puleeRxLoFosY9wxKgvYTefCCq3NBonvmst7YBb7W/bqzPpnKk6dKjTxdk?= =?us-ascii?Q?2OFYkx9dq1pINHsSd1OhTqDcfCNr2ucjEi65eirxLh7ZE6CXK12AXlN7G0/a?= =?us-ascii?Q?Oh8huc1JLDIXGYT99KuDJIQeD/GSTtQdPiTHoBdP3tJjgi+k7QF2cYwNsIT3?= =?us-ascii?Q?grr1puzNNwd0QYBXBUBpEC+C2nwD16k4Z5AGHiMOn4+KWTlbhbYWPCiMOO9h?= =?us-ascii?Q?75Jymz9dZ9NJjUguHeqxuAaTtWcswxcDH4SgRNQPBSDHhZyBH9yNdrkTSnkZ?= =?us-ascii?Q?eNNfBiTM3+nkRt6JWt7LXWtEa31YR2ic8SJvt5BfU3ZbFa0SVmeGd63gxRtC?= =?us-ascii?Q?Cvr0RD1TxSDQvn1PNWShB26WngGJdaqkHXmCOKH4je5lE53KE4EoVafRqIEt?= =?us-ascii?Q?oTiOmGTg53X8+dPhTZYZHhH+X9HLKtJg2F0x4SZ9mDsaCVzLaToFGKunSuRF?= =?us-ascii?Q?JdJm13AswbdunZGjSTRiCyr983J4+hc2/waYCzDwJ3GkXRxWswG+H282KYhY?= =?us-ascii?Q?dpRR9Tixz6Nm5cDxC6r4uRY8P//rGPVtXstvmCEj63350oKuCP4nJPmpqO4n?= =?us-ascii?Q?0RBHmeSzvCY+oSsMOAAv6oYQ+R0htXXjArmPpPriKcudG9HqVAO670Jwtjq7?= =?us-ascii?Q?9/l05OhswnJ1wZ80uiLxJcrmdFnUAVsvAmrB2Adjzmd8ve75Rdg6Ma2+UOGO?= =?us-ascii?Q?kNxovVcNnRAa7mXMW1Rm+Z4Q8AIoxEV0M0+TMsKeV7NKvJHj3m+Nulp9rMJx?= =?us-ascii?Q?XGvUs0Gnu/KtC9fhlJ7r83T5tD5XZw8wfQv5kZE98SguDLAhoiA7YytcucSs?= =?us-ascii?Q?AvbJRktCZ+R0Wm9CB0hSS8UyoeTMye8Kn1tMTiloSqPMheZidT5jkoNvV2ZB?= =?us-ascii?Q?gZDfcvlE29i10egGCZP9zm0v/lZaIQ8omfhpOzZ4LJdjxt0ASyka/JBRxK1H?= =?us-ascii?Q?l72WsElDWv5W7UA33Z1WC4pzggRBmkWPD9e4s5MXYz1xlNi1WZt94jxm7U6Y?= =?us-ascii?Q?tHFnU8sR9ql0EzoHtuEMnU6DNWTF0rsq7BoZeRY9LMy+gi4/vIQkqxcuW6lI?= =?us-ascii?Q?3roS1y/vkRmHjxaPsOsLD1Xbsq8kI778Y+IFnXib7J16/EThKgybh3Tlj/le?= =?us-ascii?Q?twcj/0J13T0wI12D2BrX/XsPsfGDgvzmRN2lJjeaB3CxEh2QeHs436cOYMBE?= =?us-ascii?Q?qezwdm8ryXDoGkcRbaNlq3hKU5xYkygdfFXvalLRhvcfDsatuW6X9M6zCiHt?= =?us-ascii?Q?F+yeAe1naap0FVDscBuC/iI/EjxqqSh5tEI+2QQoPFq2GaeK3dZtvfGi9FsD?= =?us-ascii?Q?lYb5cZGsbcF6PRhB7UfnM/fcwGz/78aMRXkY?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(376014)(36860700013)(1800799024);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:18:29.4539 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: a95aac2a-9ced-4a4d-c515-08ddfa60a1dc X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ5PEPF000001D5.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY1PR12MB9697 Content-Type: text/plain; charset="utf-8" When a vCPU enables Secure AVIC (SAVIC), the hardware needs to directly access the guest's APIC backing page. For this to work correctly, the hypervisor must be aware of the guest physical address (GPA) of this page so it can ensure the page is mapped and pinned in the nested page tables (NPT) while the vCPU is running. Introduce a paravirtual GHCB call that the guest uses to notify the hypervisor of the backing page's GPA before activating SAVIC. Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/include/x86/sev.h | 1 + tools/testing/selftests/kvm/lib/x86/savic.c | 1 + tools/testing/selftests/kvm/lib/x86/sev.c | 25 ++++++++++++++++++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/kvm/include/x86/sev.h b/tools/testing/= selftests/kvm/include/x86/sev.h index 73a23043d6c5..3a95b13fb6c0 100644 --- a/tools/testing/selftests/kvm/include/x86/sev.h +++ b/tools/testing/selftests/kvm/include/x86/sev.h @@ -171,4 +171,5 @@ void sev_es_ucall_port_write(uint32_t port, uint64_t da= ta); void sev_es_vc_handler(struct ex_regs *regs); void sev_es_pv_msr_rw(uint64_t msr, uint64_t *data, bool write); void sev_es_pv_mmio_rw(uint32_t *reg_gpa, uint32_t *data, bool write); +void sev_es_savic_notify_gpa(uint64_t gpa); #endif /* SELFTEST_KVM_SEV_H */ diff --git a/tools/testing/selftests/kvm/lib/x86/savic.c b/tools/testing/se= lftests/kvm/lib/x86/savic.c index 016e5e9e43f6..24ee15cc5603 100644 --- a/tools/testing/selftests/kvm/lib/x86/savic.c +++ b/tools/testing/selftests/kvm/lib/x86/savic.c @@ -203,6 +203,7 @@ void savic_enable(void) apic_page =3D &apic_page_pool->guest_apic_page[apic_id]; =20 savic_init_backing_page(apic_page, apic_id); + sev_es_savic_notify_gpa(apic_page->gpa); set_savic_control_msr(apic_page, true, true); savic_ctrl_msr_val =3D rdmsr(MSR_AMD64_SECURE_AVIC_CONTROL); exp_msr_val =3D apic_page->gpa | BIT_ULL(MSR_AMD64_SECURE_AVIC_EN_BIT) | diff --git a/tools/testing/selftests/kvm/lib/x86/sev.c b/tools/testing/self= tests/kvm/lib/x86/sev.c index 257988fce107..840504f0243c 100644 --- a/tools/testing/selftests/kvm/lib/x86/sev.c +++ b/tools/testing/selftests/kvm/lib/x86/sev.c @@ -8,6 +8,7 @@ #include "linux/bitmap.h" #include "svm.h" #include "svm_util.h" +#include "savic.h" =20 #define IOIO_TYPE_STR (1 << 2) #define IOIO_SEG_DS (1 << 11 | 1 << 10) @@ -17,7 +18,8 @@ #define SW_EXIT_CODE_IOIO 0x7b #define SW_EXIT_CODE_MSR 0x7c #define SVM_VMGEXIT_MMIO_READ 0x80000001 -#define SVM_VMGEXIT_MMIO_WRITE 0x80000002 +#define SVM_VMGEXIT_MMIO_WRITE 0x80000002 +#define SVM_VMGEXIT_SECURE_AVIC 0x8000001a =20 struct ghcb_entry { struct ghcb ghcb; @@ -727,3 +729,24 @@ void sev_es_vc_handler(struct ex_regs *regs) __GUEST_ASSERT(0, "No VC handler\n"); } } + +void sev_es_savic_notify_gpa(uint64_t gpa) +{ + struct ghcb_entry *entry; + struct ghcb *ghcb; + int ret; + + entry =3D ghcb_alloc(); + ghcb =3D &entry->ghcb; + + register_ghcb_page(entry->gpa); + ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_SECURE_AVIC); + ghcb_set_rax(ghcb, -1ULL); + ghcb_set_rbx(ghcb, gpa); + ghcb_set_sw_exit_info_1(ghcb, 0); + ghcb_set_sw_exit_info_2(ghcb, 0); + do_vmg_exit(entry->gpa); + ret =3D ghcb->save.sw_exit_info_1 & 0xffffffff; + __GUEST_ASSERT(!ret, "Secure AVIC GPA notification failed, ret: %d", ret); + ghcb_free(entry); +} --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from CY7PR03CU001.outbound.protection.outlook.com (mail-westcentralusazon11010002.outbound.protection.outlook.com [40.93.198.2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7C0CF30FC13; Tue, 23 Sep 2025 05:18:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.198.2 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604724; cv=fail; b=Li5XXhs/gVhjV18E5h8dhKte+k6p6cN8v4B513itbWM8H0xDGv+YU2wF96eN35Pd5atgfJpniOp3GaPA2bZ8vW6OdWPzpAyIf1r+duDKDVqhivbiDQakpoxi2PCIPOjqr+P990VYpNKKFjMBwFOs0DfzkkX14URVJDKljG+xC/Q= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604724; c=relaxed/simple; bh=8aeSaXjA7w2hJ8CewSYwVfgXYxrdeKNO3qTwFnxc7hg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=WPpbeSjaGK6j/lHxHlpxlXL3122pun5UB4fHJIvoH8WTcPWzw8MytPw94OF28KgqSY0E9NZ9eStvNC2KUJ/Wmq0kLsCO17terIZfp+X5mTT5SP6oD62GwZCDkoGFUIE20P+7NPuoI/3DdeDRWzLPQr1TGkP6Esh1Z9lBOdtROak= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=KGa+tBLx; arc=fail smtp.client-ip=40.93.198.2 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="KGa+tBLx" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=V4St8gWEgecFKOlEQrgsClsceD18AnQbA/tVC9qpU14CTxh43gPkeW37dd8MPzidzBN25YxUL/7shqxdSndZXb0NQ36uzKBSPryEa+owzkT5hFowyhOwLMr3TCcm7F5FNzomOfHOcD0fBuFjDvwero0VGlL8rIKTz6PrxlYoxNm5m14VtRPyDdnBlpFuMHNdE099y122H+PCOKHUB9zx5JCHotV+z8FlWev61TY3oY/dwcFDjDZb5nNgt/G5uJjkmT2q4hG8nCI+RTD8NyGNxqkpQ+h7iockY/odQvVU0Wa8EoknvKjAvBbebQtUjtNYScedQr1E/4Xv1iniCBbIew== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=cZbSeaR51/RW7ouBNdCjbWSjtP35StoQOAF915Wr8lM=; b=Xy7V+m65gDpnw87eTBEbuJqFPdKpjta3Fyj+uHNgikCbwnPZ74jdELcqcsuvg7+/2NmdhkyaUNSgmoZ7D6sDbxiyiful9FosaG28Y2BQMeZZi5sKCcbFra5KMZOzbaAZoC7LGb7CTXxVB0RuaMDrwkpVcKvsTRSFu9StFpTx6QfyhFOu+ukmXGhHyotMF5ci0Ni15OZVZEZRwk270NkTc0HbdwSVMUBAZWL9rwd33rj587y+QqZ82O5mL94/aIaXxYQlE6dq4Nt42KLToYnf0OOpfZ5vL7o+aAzpi3DmO4+jSanZIqlcJkNIssiI42ffnL75mZUDpDHh1CD/qpOzuQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=cZbSeaR51/RW7ouBNdCjbWSjtP35StoQOAF915Wr8lM=; b=KGa+tBLxWWgQWyhOBTM9ZULkM7u1GcBoo0DSfv+nwa/5M+3D258I+rZ4KmsKetwUCG0fHRYZKJ4dyFdVgx/qqdGF4hPSHS8pcq8eG8HX9bUqTv2EFWvbPN1dbQIUFJb3THZmQ6Dc07rgeDwZVIZ9o8MV7Vvu6sEFxjKHLV5kpDo= Received: from SJ0PR05CA0130.namprd05.prod.outlook.com (2603:10b6:a03:33d::15) by CY3PR12MB9556.namprd12.prod.outlook.com (2603:10b6:930:10a::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.19; Tue, 23 Sep 2025 05:18:40 +0000 Received: from SJ5PEPF000001D4.namprd05.prod.outlook.com (2603:10b6:a03:33d:cafe::dd) by SJ0PR05CA0130.outlook.office365.com (2603:10b6:a03:33d::15) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:18:40 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by SJ5PEPF000001D4.mail.protection.outlook.com (10.167.242.56) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:18:39 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:18:24 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 29/35] KVM: selftests: Add Secure AVIC mode to xapic_ipi_test Date: Tue, 23 Sep 2025 10:39:36 +0530 Message-ID: <20250923050942.206116-30-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001D4:EE_|CY3PR12MB9556:EE_ X-MS-Office365-Filtering-Correlation-Id: 550fed45-9566-48e7-95a6-08ddfa60a820 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|36860700013|1800799024|376014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?G3iGp+s8+qoIdAYjuXGm8drd1sM9J0dBUqvSkNP6GL2is0aKT2RkHEozx4wF?= =?us-ascii?Q?6yPvAmIJv1I7UWYc2S9yRFsXgUdkkkD5y/i2ARugxFxUfxAFwk5pyhN/3zKE?= =?us-ascii?Q?3CCfw1gXHws7/gbALskt0U23fuAKHq4D/5ia4Kd4rgTs8ZrB5jlBmBG2lFKk?= =?us-ascii?Q?mWWKj5i0v/buofUMu1shZpSaRyTVNU8hwrXhY2/PJiI97xu7dTRFcpJOlWO7?= =?us-ascii?Q?iQMw9olbdf8ZT/vwYjAbeLq7zulXmVnas4chtVzv1vY8IuAfLQD9EmBz/FAf?= =?us-ascii?Q?6mUiiIpMgN4pXrqPnjYPtcfFc1+FR0q8JHa6ZUP7k78/4LiNyAQhpEOgLP/i?= =?us-ascii?Q?NRMQjmPp4Uylho8mjyDfCUxaiewFnHyZmXKo+gXpwjKVR7yCF6Sy5U7xTk4j?= =?us-ascii?Q?typK0pwA7/VyclZQfWpxHO5uYOHnYzEuTr6kVawRuKsvjmO5ufeflx3CtzFV?= =?us-ascii?Q?1Or2qRpRrdHD8W9pcXbyDoIQ7ua1mTjX3M0SkdrGK6DS0LqKZVmmEbYhd84K?= =?us-ascii?Q?NQIAGJYbr6Yqyg9k+XNUGA8UsMJcjPrJhx3RC1knhSyqXmWH6aUJRftRV1jn?= =?us-ascii?Q?tfTDpYABuVacf8z8LWR74MJexKOwWbDoOIIAGViCM0iIsq6vI9AY9oG9tJgc?= =?us-ascii?Q?iy+dJdE7c9Fd3whNC27VjSs1YkaXY+ivNKQ01WRMV6QvFp4IVAEV2FrB7nUl?= =?us-ascii?Q?ouKF49eE3845nVao5DNwlxDt9eX83qVkB2CI0jp+zOQ0sxuSsbeJDwoftEMl?= =?us-ascii?Q?kG9ix0v97kkEURbnaoTCrTfcrVR74gQ31ympGM4lKMUf/MvgoNhB1GpHHVnZ?= =?us-ascii?Q?l0Aaqg7/9Irk+2uJSbKbXL6pQnKRTceneRk/txRb8RlW/LCUhs9FfsJxzyzh?= =?us-ascii?Q?Fl3LkQ8lZ8dTnuJ8ud0adq3gU0N2bygZQfV/cfZr74t8AhePSgYmj8HrsjnG?= =?us-ascii?Q?sRR87HjKLY1WulZr2O43pk7inKmaHyXUMTV1sJEJnsnJFjDXoV0JsO7bjeHh?= =?us-ascii?Q?F73RFyijGhHoxyYW4sjt4RgFw2Y/cotS8NOYNhCAqn3i1aq43xZ8jzVGpDlR?= =?us-ascii?Q?DeV/SSFnxrE+5L5xAiHTj46Im4AYDRYeSKHBJPlQk1kq/u/4dz0koyUsuK1U?= =?us-ascii?Q?8qxu1uwxES5D5VHLC9dfWQmwJ7NE+tx7GVkHSYVl58EUnr2DP6OOBs+t8vSy?= =?us-ascii?Q?h5284sAozMno/VVURRqlxDxk+XXBGUrd9pOrcAkFGvY6NJSBASrDYWG7Fb5E?= =?us-ascii?Q?5B7M7MGGUbdjUNQ+o1kKEgZonmmLmYj3dV7P9EmxEg/lNzC7mCKlC2Vuh8iZ?= =?us-ascii?Q?Eno20sN1t5gRhTBexlYa7oLinZm05/XRR8F1Q46vG6yxSe/gtBuFMq1rQvVG?= =?us-ascii?Q?PjVbKkUdjFEoo4ewBaUgV0HsxUt7fdQJKzDpJ8DBt7ZXMrvXbPSqWF6VGyOc?= =?us-ascii?Q?hZDwQxO9ivW+bhmVds6/Xsr6hAtKJCYJkDgg/5UHO01/36OAsFjJSMIldUim?= =?us-ascii?Q?FpTEF1NqWJbHbt+GBUZ9DEZJj1FRaR0s7BXh?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(36860700013)(1800799024)(376014);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:18:39.9653 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 550fed45-9566-48e7-95a6-08ddfa60a820 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ5PEPF000001D4.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY3PR12MB9556 Content-Type: text/plain; charset="utf-8" Extend the xapic_ipi_test to validate Inter-Processor Interrupt (IPI) functionality in SEV-SNP guests with Secure AVIC (SAVIC) enabled. Secure AVIC alters how IPIs are handled. Instead of relying solely on KVM's APIC emulation/AVIC hardware, an attempt to send an IPI triggers a #VC(INCOMPLETE_IPI) exception, delegating the IPI delivery logic to the guest's #VC handler. This new execution model requires dedicated test coverage. With these changes, the existing IPI test framework can now run on SAVIC-enabled vCPUs, verifying that the guest-side emulation correctly delivers interrupts between cores and providing critical test coverage for this SEV-SNP feature. Signed-off-by: Neeraj Upadhyay --- tools/arch/x86/include/asm/msr-index.h | 4 +- .../selftests/kvm/include/x86/processor.h | 1 + .../selftests/kvm/x86/xapic_ipi_test.c | 72 +++++++++++++------ 3 files changed, 56 insertions(+), 21 deletions(-) diff --git a/tools/arch/x86/include/asm/msr-index.h b/tools/arch/x86/includ= e/asm/msr-index.h index 5cfb5d74dd5f..be08f4aca4ad 100644 --- a/tools/arch/x86/include/asm/msr-index.h +++ b/tools/arch/x86/include/asm/msr-index.h @@ -698,7 +698,9 @@ #define MSR_AMD64_SNP_VMSA_REG_PROT BIT_ULL(MSR_AMD64_SNP_VMSA_REG_PROT_BI= T) #define MSR_AMD64_SNP_SMT_PROT_BIT 17 #define MSR_AMD64_SNP_SMT_PROT BIT_ULL(MSR_AMD64_SNP_SMT_PROT_BIT) -#define MSR_AMD64_SNP_RESV_BIT 18 +#define MSR_AMD64_SNP_SECURE_AVIC_BIT 18 +#define MSR_AMD64_SNP_SECURE_AVIC BIT_ULL(MSR_AMD64_SNP_SECURE_AVIC_BIT) +#define MSR_AMD64_SNP_RESV_BIT 19 #define MSR_AMD64_SNP_RESERVED_MASK GENMASK_ULL(63, MSR_AMD64_SNP_RESV_BIT) #define MSR_AMD64_RMP_BASE 0xc0010132 #define MSR_AMD64_RMP_END 0xc0010133 diff --git a/tools/testing/selftests/kvm/include/x86/processor.h b/tools/te= sting/selftests/kvm/include/x86/processor.h index 035ced9130c2..769c6be41f1b 100644 --- a/tools/testing/selftests/kvm/include/x86/processor.h +++ b/tools/testing/selftests/kvm/include/x86/processor.h @@ -204,6 +204,7 @@ struct kvm_x86_cpu_feature { #define X86_FEATURE_SEV KVM_X86_CPU_FEATURE(0x8000001F, 0, EAX, 1) #define X86_FEATURE_SEV_ES KVM_X86_CPU_FEATURE(0x8000001F, 0, EAX, 3) #define X86_FEATURE_SEV_SNP KVM_X86_CPU_FEATURE(0x8000001F, 0, EAX, 4) +#define X86_FEATURE_SECURE_AVIC KVM_X86_CPU_FEATURE(0x8000001F, 0,= EAX, 26) #define X86_FEATURE_PERFMON_V2 KVM_X86_CPU_FEATURE(0x80000022, 0, EAX, 0) #define X86_FEATURE_LBR_PMC_FREEZE KVM_X86_CPU_FEATURE(0x80000022, 0, EAX,= 2) =20 diff --git a/tools/testing/selftests/kvm/x86/xapic_ipi_test.c b/tools/testi= ng/selftests/kvm/x86/xapic_ipi_test.c index 3d49f7798dcc..4fde0f4efb41 100644 --- a/tools/testing/selftests/kvm/x86/xapic_ipi_test.c +++ b/tools/testing/selftests/kvm/x86/xapic_ipi_test.c @@ -31,6 +31,7 @@ #include "test_util.h" #include "vmx.h" #include "sev.h" +#include "savic.h" =20 /* Default running time for the test */ #define DEFAULT_RUN_SECS 3 @@ -45,30 +46,44 @@ */ #define IPI_VECTOR 0xa5 =20 +enum apic_mode { + XAPIC, + X2APIC, + SAVIC, +}; + /* * Incremented in the IPI handler. Provides evidence to the sender that th= e IPI * arrived at the destination */ static volatile uint64_t *ipis_rcvd; =20 -static bool x2apic; +static int apic_mode; =20 static void apic_enable(void) { - if (x2apic) - x2apic_enable(); - else + switch (apic_mode) { + case XAPIC: xapic_enable(); + break; + case X2APIC: + x2apic_enable(); + break; + case SAVIC: + x2apic_enable(); + savic_enable(); + break; + } } =20 static uint32_t apic_read_reg(unsigned int reg) { - return x2apic ? x2apic_read_reg(reg) : xapic_read_reg(reg); + return apic_mode !=3D XAPIC ? x2apic_read_reg(reg) : xapic_read_reg(reg); } =20 static void apic_write_reg(unsigned int reg, uint64_t val) { - if (x2apic) + if (apic_mode !=3D XAPIC) x2apic_write_reg(reg, val); else xapic_write_reg(reg, (uint32_t)val); @@ -145,7 +160,7 @@ static void halter_guest_code(struct test_data_page *da= ta) static void guest_ipi_handler(struct ex_regs *regs) { (*ipis_rcvd)++; - apic_write_reg(APIC_EOI, 77); + apic_write_reg(APIC_EOI, 0); } =20 static void sender_guest_code(struct test_data_page *data) @@ -185,7 +200,7 @@ static void sender_guest_code(struct test_data_page *da= ta) * First IPI can be sent unconditionally because halter vCPU * starts earlier. */ - if (!x2apic) { + if (apic_mode =3D=3D XAPIC) { apic_write_reg(APIC_ICR2, icr2_val); apic_write_reg(APIC_ICR, icr_val); } else { @@ -386,10 +401,10 @@ void do_migrations(struct test_data_page *data, int r= un_secs, int delay_usecs, } =20 void get_cmdline_args(int argc, char *argv[], int *run_secs, - bool *migrate, int *delay_usecs, bool *x2apic, int *vm_type) + bool *migrate, int *delay_usecs, int *apic_mode, int *vm_type) { for (;;) { - int opt =3D getopt(argc, argv, "s:d:v:me:t:"); + int opt =3D getopt(argc, argv, "s:d:v:me:t:g"); =20 if (opt =3D=3D -1) break; @@ -404,7 +419,7 @@ void get_cmdline_args(int argc, char *argv[], int *run_= secs, *delay_usecs =3D parse_size(optarg); break; case 'e': - *x2apic =3D parse_size(optarg) =3D=3D 1; + *apic_mode =3D parse_size(optarg); break; case 't': *vm_type =3D parse_size(optarg); @@ -418,7 +433,7 @@ void get_cmdline_args(int argc, char *argv[], int *run_= secs, TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV_ES)); break; case KVM_X86_SNP_VM: - TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SNP)); + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV_SNP)); break; default: TEST_ASSERT(false, "Unsupported VM type :%d", @@ -432,7 +447,7 @@ void get_cmdline_args(int argc, char *argv[], int *run_= secs, " Default is no migrations.\n" "-d - delay between migrate_pages() calls." " Default is %d microseconds.\n" - "-e - APIC mode 0 - xapic , 1 - x2apic" + "-e - APIC mode 0 - xapic , 1 - x2apic, 3 - Secure AVI= C" " Default is xAPIC.\n" "-t . Default is %d.\n" "Supported values:\n" @@ -484,10 +499,17 @@ int main(int argc, char *argv[]) bool is_sev; =20 get_cmdline_args(argc, argv, &run_secs, &migrate, &delay_usecs, - &x2apic, &vm_type); + &apic_mode, &vm_type); + if (apic_mode =3D=3D SAVIC) { + vm_type =3D KVM_X86_SNP_VM; + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV_SNP)); + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_IDLE_HLT)); + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SECURE_AVIC)); + } + is_sev =3D is_sev_vm_type(vm_type); =20 - if (x2apic) + if (apic_mode !=3D XAPIC) migrate =3D 0; =20 if (run_secs <=3D 0) @@ -495,18 +517,28 @@ int main(int argc, char *argv[]) if (delay_usecs <=3D 0) delay_usecs =3D DEFAULT_DELAY_USECS; =20 - if (is_sev) + if (apic_mode =3D=3D SAVIC) { + struct kvm_sev_init args =3D { + .vmsa_features =3D BIT_ULL(SVM_FEAT_SECURE_AVIC) + }; + + vm =3D _vm_sev_create_with_one_vcpu(vm_type, halter_guest_code, + ¶ms[0].vcpu, &args); + } else if (is_sev) { vm =3D vm_sev_create_with_one_vcpu(vm_type, halter_guest_code, ¶ms[0].vcpu); - else + } else { vm =3D vm_create_with_one_vcpu(¶ms[0].vcpu, halter_guest_code); + } =20 vm_install_exception_handler(vm, IPI_VECTOR, guest_ipi_handler); - if (is_sev_es_vm(vm)) + if (apic_mode =3D=3D SAVIC) + vm_install_exception_handler(vm, 29, savic_vc_handler); + else if (is_sev_es_vm(vm)) vm_install_exception_handler(vm, 29, sev_es_vc_handler); =20 - sync_global_to_guest(vm, x2apic); - if (!x2apic) + sync_global_to_guest(vm, apic_mode); + if (apic_mode =3D=3D XAPIC) virt_pg_map(vm, APIC_DEFAULT_GPA, APIC_DEFAULT_GPA); =20 params[1].vcpu =3D vm_vcpu_add(vm, 1, sender_guest_code); --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from CO1PR03CU002.outbound.protection.outlook.com (mail-westus2azon11010003.outbound.protection.outlook.com [52.101.46.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4D38730DD34; Tue, 23 Sep 2025 05:18:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.46.3 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604736; cv=fail; b=jltcT9kFNo6BZjgO/6x3hydi6n4cMPiEDrXoOWwe19uWzItAknbITmkP04XWv21lXT7LYXPdOfQPHHqkxRoEbdGteAJrXoe/KhN6lapPo+gtmC2E09IL8AMNY0kxEqx9qslK3wkMEBH4ZgJeqNJu2ohxs8GXhj5THq5xxEujoJs= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604736; c=relaxed/simple; bh=kgpiGzo8PcWptKpmlY0ga6ms1RXTqMv9ljzWmNgaJOw=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=eSRsZVUjgkKW4d3/g60pAz5dlbzEQ/aGmTDVPYF+7tQwVSzqGaTFidF2s1pN1tRTltxgtY8lFqlUQAZwQWCrQZu4XKq8aRk5WuhrJL/RLn2yQffV/FcquziL23cEAda2loGYMn4y3y25num8nJXJVmIlGiARFVNiuboD1cKemCU= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=Fd8qXVdS; arc=fail smtp.client-ip=52.101.46.3 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="Fd8qXVdS" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=ZG8OijFOmvCUQcqBfrP8O4ziChnoUzYVXAd44CLv+GghkiWpYBHWlCp6hSEV76QCiXPd6cz2FBhDYXak2flMO5hUO0zt8u02FNEvrlYP3wspIs8PkUNWKbqQuqNI7hcWqrTykFYBpmcV3XXo70XqixxLdW5lJ41O2bjL8gjsTwo/3ZOVJlphMENckZXuwCdXoXzEQYRZ1eZ4c6u9Iylqu7Z4Yt9TZDVzndh9iRHDeCDAjVrNs0MljWEqG4RY36KH7TJxv6md3s4Z/s0JwkikhTJUeYt+xZmkOgsVjOTxB2q2sPn62tIbm8e44C2oo9IU30QweBWlFUzsYyX2yIt1RA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=WLyrH6WACChjeEOUOrEWp+ia8msxA52N4U1Z90AQmnM=; b=BbYPmz0OD7Bsjfgiw0iUU02HRYXYb7pSWTFewubFG5WtdJQMqtDkekkqngTMUQ5Wt1dHQZINnmgtSZl1e0yI4Q4dOIHzO7qZGNLY3WYCqrjrVvp/qj4YFwdAEra3A7TBCrFRllXWFKPyjfDwkSEfiBpURis/aujZ3yZggyAF665/bM+9QOLRL3R4SAlHKBLIZUhoZEeJcvkTcIOlu4iNCgYCeMv4ajKCa34J14ezYAACU7M0PB6fhLpI8uoBBCxdkr6oGQvY1PWBYBrGsxNNAdGq/0U4X9Qe1m6uYn9EO01NoISRCFqK2NSaevdjXo4qwGeBjQKiwRwsMrTsTOMT/A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=WLyrH6WACChjeEOUOrEWp+ia8msxA52N4U1Z90AQmnM=; b=Fd8qXVdS2Pxz4CJDvvD3yYZxdJZ/ylMcrCxh3yo9AlMOFgQOYhqj919jk9N2y4IaImCoh3UBu03g2QxK1koEg6ZZxQXGJq2Vy/kU6z1BqcP/eGfc7Ta/S6YumzMBHbB5EhWdmCB5pRqSAbfV2d/jxyCIBbDdMxg5ViyyeEwixXo= Received: from SJ0PR05CA0137.namprd05.prod.outlook.com (2603:10b6:a03:33d::22) by DM4PR12MB6398.namprd12.prod.outlook.com (2603:10b6:8:b5::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.19; Tue, 23 Sep 2025 05:18:48 +0000 Received: from SJ5PEPF000001D4.namprd05.prod.outlook.com (2603:10b6:a03:33d:cafe::ec) by SJ0PR05CA0137.outlook.office365.com (2603:10b6:a03:33d::22) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:18:47 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by SJ5PEPF000001D4.mail.protection.outlook.com (10.167.242.56) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:18:47 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:18:42 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 30/35] KVM: selftests: Add test to verify APIC MSR accesses for SAVIC guest Date: Tue, 23 Sep 2025 10:39:37 +0530 Message-ID: <20250923050942.206116-31-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001D4:EE_|DM4PR12MB6398:EE_ X-MS-Office365-Filtering-Correlation-Id: 6f61841a-40c6-426f-0b27-08ddfa60acc4 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|376014|36860700013|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?U0+fBppDfnP8pP0pNQb3TYiMmkWfKaIzznaTkPLkXY99Ko6EKSFZ69qzwvEy?= =?us-ascii?Q?Jo2AZzR6MCxGJX4x2Dzon5zUVZE4ho4bnJXLNsEn3FlEI+KRRd2+cuIkdv7/?= =?us-ascii?Q?0Kx58owKt3HeTqPbNjURxI0vvrE8yqrztwtH9L9Yh7glJz0Lf39yazuaIEEV?= =?us-ascii?Q?O8YNTT3sG3BwdiBMAHDQRz4sqGJXe4OLBrvieDxkQxQ2FwQVRV+O3RnWEPf2?= =?us-ascii?Q?2TF+EaL81TZtrZhe+ttinkUpiHfASu13Ta2E+jeDgzc3OlIlJ1g4ob9Rc6tN?= =?us-ascii?Q?B5B0/rqsHTidhvEYMETyqrWkHWwUUGH2ClB7HTFA5ovfOtQzaA5jhdX1Zq56?= =?us-ascii?Q?b+xepV3+v5BvuLT1xSAb8jU5XqG59tK8ThFV3cG67VvnNT4FoutbhzONpcVE?= =?us-ascii?Q?/iQ0nziJ4XGHogjo9Qduep9wy8ZDkZ4bZWH2TwhMWWLMBLGyD4CG2+HDxbGw?= =?us-ascii?Q?wG2gSs01Aa7Agc8RUpFCYwIa/2VzdQPqazAKSyI295qXpmGZx8lWfjdh24cF?= =?us-ascii?Q?V6u+Al/qC2bRkN1h7wFg1Sw1pS7q+SBMh3lC/h7Cge4DK+c2ae3oxQJhNAU5?= =?us-ascii?Q?nBDqsc3ALdSZhpGpVzzHgnOfyNPm4bytxO1HKC5YDH+pYNjR/tAB0DHt73Eq?= =?us-ascii?Q?NMluIqYtAVTt5MvJnKNms5WJ3CJRF0qnkJC3PdLfrh2LgB8w+yTshsHiYSg0?= =?us-ascii?Q?JhwUmnXjFzjGPDX9ix3M1Yubb/vdeNotfMkgeOLvTrouWn3aD017tH6qOXG+?= =?us-ascii?Q?B/qZXVs+sB+Bbs1gHMqjnGz2E7+aFaxNLYnhfZI7YFbDtVoAR00kFZzbWvZz?= =?us-ascii?Q?LCFGbT0hlJ9SfUO7GhlWhXFotrieN/3NNKX1Baxm1Rp0BmFJ67nMBgMIcW5y?= =?us-ascii?Q?RR0J6oOAvOcK8ii468P+GV3hJihvs979YriXAWsefma5USousFa4aezjXvvZ?= =?us-ascii?Q?SA4UxmGlZnRr8/W6mbJn2//rbCFNMtP5BPig8TwGCrP8qeQgVNI/1X7gE/wl?= =?us-ascii?Q?683EwROZliIwQH4lB7PDPMD1XZ1Rxdqx9QD53ZkNuja0iV7OWPe7HqzUzPWW?= =?us-ascii?Q?YYZPetD0Z+/Of3bBf4oZtOe2zAXqeSp/VwxKr3tXRGqPAa1IogjguejFFxpS?= =?us-ascii?Q?nvhH9izqtUr7DpuWJ8JASoc4K4/+vXLUbSZvAXySKijdaqJ11jbgUbAXTQEQ?= =?us-ascii?Q?gd+B4UQPFl//K2FnyeBMAXzqDdZ9MY5jyZhLasn3WZV5Z/ZbJc8iLNTvB+nf?= =?us-ascii?Q?lXXpA+NuEgmR210wXEXHAbbsvforRvoBTdCkcNecSsqIwbkoKiNs/96+51kx?= =?us-ascii?Q?p0YMjdl9a0f2702IBnddSYaHJIhXfPCSx2BWNjFJ8ZK5rnDgH9tBuUCv7GO6?= =?us-ascii?Q?cFVjAJFwxiLypPbjlMVdOrfxxdXdVB0GBTcmflsGowlQA5iE5SQkYUcrQbkO?= =?us-ascii?Q?xVQx3pwN8S5uD7C20P1ohz6b3NpoVsgdq3KxpO2yDuey0hLHF+3AT7lpHMvk?= =?us-ascii?Q?uXVrvk7ArWNQVCIPUlVmvQAQqGkU036A7Y6N?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(376014)(36860700013)(1800799024);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:18:47.7467 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 6f61841a-40c6-426f-0b27-08ddfa60acc4 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ5PEPF000001D4.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM4PR12MB6398 Content-Type: text/plain; charset="utf-8" When Secure AVIC (SAVIC) is enabled in an SEV-SNP guest, a hybrid model for APIC register access is used. Some registers are accelerated by the hardware, while others trigger a #VC exception for emulation by the guest's #VC handler. This complex interaction requires dedicated testing to ensure correctness. Add savic_test.c, a new selftest designed to validate APIC MSR accesses in SAVIC mode. The test creates an SEV-SNP VM with SAVIC enabled and systematically performs rdmsr/wrmsr operations on a comprehensive set of APIC registers. The test verifies several key behaviors: * Ensure that accesses to unaccelerated MSRs (e.g., APIC_TMICT, APIC_LVTT) correctly trigger a #VC exception and are properly emulated by the savic_vc_handler(). * Confirm that architecturally invalid operations, such as writing to a read-only register (APIC_LVR) or reading a write-only register (APIC_EOI), generate the expected #GP fault. * Verify that the state in the guest's APIC backing page is consistent with values read via RDMSR after a write. * Validate that register writes are correctly propagated (or intentionally not propagated) to the hypervisor's internal state, ensuring proper synchronization for registers like APIC_SPIV versus accelerated registers like APIC_TASKPRI. This test provides essential coverage for the SAVIC feature, ensuring its MSR handling mechanism is implemented correctly. Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/Makefile.kvm | 1 + .../testing/selftests/kvm/include/x86/apic.h | 1 + .../testing/selftests/kvm/include/x86/savic.h | 4 + tools/testing/selftests/kvm/lib/x86/savic.c | 20 +- tools/testing/selftests/kvm/x86/savic_test.c | 291 ++++++++++++++++++ 5 files changed, 312 insertions(+), 5 deletions(-) create mode 100644 tools/testing/selftests/kvm/x86/savic_test.c diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selft= ests/kvm/Makefile.kvm index b94ac1caa514..1b0281e6bbe1 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -96,6 +96,7 @@ TEST_GEN_PROGS_x86 +=3D x86/pmu_counters_test TEST_GEN_PROGS_x86 +=3D x86/pmu_event_filter_test TEST_GEN_PROGS_x86 +=3D x86/private_mem_conversions_test TEST_GEN_PROGS_x86 +=3D x86/private_mem_kvm_exits_test +TEST_GEN_PROGS_x86 +=3D x86/savic_test TEST_GEN_PROGS_x86 +=3D x86/set_boot_cpu_id TEST_GEN_PROGS_x86 +=3D x86/set_sregs_test TEST_GEN_PROGS_x86 +=3D x86/smaller_maxphyaddr_emulation_test diff --git a/tools/testing/selftests/kvm/include/x86/apic.h b/tools/testing= /selftests/kvm/include/x86/apic.h index aa3a5d54c404..af555638086f 100644 --- a/tools/testing/selftests/kvm/include/x86/apic.h +++ b/tools/testing/selftests/kvm/include/x86/apic.h @@ -33,6 +33,7 @@ #define APIC_SPIV 0xF0 #define APIC_SPIV_FOCUS_DISABLED (1 << 9) #define APIC_SPIV_APIC_ENABLED (1 << 8) +#define APIC_ISR 0x100 #define APIC_TMR 0x180 #define APIC_IRR 0x200 #define APIC_ICR 0x300 diff --git a/tools/testing/selftests/kvm/include/x86/savic.h b/tools/testin= g/selftests/kvm/include/x86/savic.h index 238d7450ab6e..33f19f5e39b3 100644 --- a/tools/testing/selftests/kvm/include/x86/savic.h +++ b/tools/testing/selftests/kvm/include/x86/savic.h @@ -6,6 +6,9 @@ #ifndef SELFTEST_KVM_SAVIC_H #define SELFTEST_KVM_SAVIC_H =20 +#define APIC_REG_OFF(VEC) (VEC / 32 * 16) +#define APIC_VEC_POS(VEC) (VEC % 32) + struct guest_apic_page; =20 void guest_apic_pages_init(struct kvm_vm *vm); @@ -17,4 +20,5 @@ uint64_t savic_hv_read_reg(uint32_t reg); void savic_enable(void); int savic_nr_pages_required(uint64_t page_size); void savic_vc_handler(struct ex_regs *regs); +struct guest_apic_page *get_guest_apic_page(void); #endif diff --git a/tools/testing/selftests/kvm/lib/x86/savic.c b/tools/testing/se= lftests/kvm/lib/x86/savic.c index 24ee15cc5603..da01bb5deae1 100644 --- a/tools/testing/selftests/kvm/lib/x86/savic.c +++ b/tools/testing/selftests/kvm/lib/x86/savic.c @@ -8,6 +8,7 @@ #include "apic.h" #include "kvm_util.h" #include "sev.h" +#include "savic.h" =20 struct apic_page { u8 apic_regs[PAGE_SIZE]; @@ -44,9 +45,6 @@ enum lapic_lvt_entry { #define SVM_EXIT_AVIC_UNACCELERATED_ACCESS 0x402 #define SVM_EXIT_AVIC_INCOMPLETE_IPI 0x401 =20 -#define REG_OFF(VEC) (VEC / 32 * 16) -#define VEC_POS(VEC) (VEC % 32) - #define SAVIC_NMI_REQ_OFFSET 0x278 =20 /* @@ -104,6 +102,11 @@ void set_savic_control_msr(struct guest_apic_page *api= c_page, bool enable, bool wrmsr(MSR_AMD64_SECURE_AVIC_CONTROL, val); } =20 +struct guest_apic_page *get_guest_apic_page(void) +{ + return &apic_page_pool->guest_apic_page[x2apic_read_reg(APIC_ID)]; +} + /* * Write APIC reg offset in the guest APIC backing page. * @@ -175,11 +178,17 @@ static void savic_init_backing_page(struct guest_apic= _page *apic_page, uint32_t regval =3D savic_hv_read_reg(APIC_LDR); savic_write_reg(apic_page, APIC_LDR, regval); =20 - for (i =3D LVT_THERMAL_MONITOR; i < APIC_MAX_NR_LVT_ENTRIES; i++) { + for (i =3D LVT_TIMER; i < APIC_MAX_NR_LVT_ENTRIES; i++) { regval =3D savic_hv_read_reg(APIC_LVTx(i)); savic_write_reg(apic_page, APIC_LVTx(i), regval); } =20 + regval =3D savic_hv_read_reg(APIC_TMICT); + savic_write_reg(apic_page, APIC_TMICT, regval); + + regval =3D savic_hv_read_reg(APIC_TDCR); + savic_write_reg(apic_page, APIC_TDCR, regval); + regval =3D savic_hv_read_reg(APIC_LVT0); savic_write_reg(apic_page, APIC_LVT0, regval); =20 @@ -351,7 +360,8 @@ static void send_ipi(int cpu, int vector, bool nmi) if (nmi) savic_write_reg(apic_page, SAVIC_NMI_REQ_OFFSET, 1); else - savic_write_reg(apic_page, APIC_IRR + REG_OFF(vector), BIT(VEC_POS(vecto= r))); + savic_write_reg(apic_page, APIC_IRR + APIC_REG_OFF(vector), + BIT(APIC_VEC_POS(vector))); } =20 static bool is_cpu_present(int cpu) diff --git a/tools/testing/selftests/kvm/x86/savic_test.c b/tools/testing/s= elftests/kvm/x86/savic_test.c new file mode 100644 index 000000000000..bac56f85caea --- /dev/null +++ b/tools/testing/selftests/kvm/x86/savic_test.c @@ -0,0 +1,291 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * Copyright (C) 2024 Advanced Micro Devices, Inc. + * + */ +#include + +#include "processor.h" +#include "apic.h" +#include "kvm_util.h" +#include "sev.h" +#include "test_util.h" +#include "savic.h" + +#define NR_SAVIC_VCPUS 1 + +static struct kvm_vcpu *vcpus[NR_SAVIC_VCPUS]; +static pthread_t threads[NR_SAVIC_VCPUS]; + +#define SAVIC_TEST_STATE(STATE) \ + STATE ## _START, \ + STATE ## _END + +enum savic_test_state { + SAVIC_TEST_STATE(SAVIC_APIC_MSR_ACCESSES), +}; + +#define SAVIC_GUEST_SYNC(sync, func) ({\ + GUEST_SYNC(sync ## _START); \ + func(id); \ + GUEST_SYNC(sync ## _END); \ +}) + +static int savic_wrmsr(uint32_t reg, uint64_t val) +{ + switch (reg) { + case APIC_LVR: + case APIC_LDR: + case APIC_ISR: + case APIC_TMR: + case APIC_IRR: + case APIC_TMCCT: + x2apic_write_reg_fault(reg, val); + return -1; + default: + x2apic_write_reg(reg, val); + break; + } + + return 0; +} + +static uint64_t savic_rdmsr(uint32_t reg) +{ + uint64_t val; + uint32_t msr =3D APIC_BASE_MSR + (reg >> 4); + + switch (reg) { + case APIC_EOI: + uint8_t fault =3D rdmsr_safe(msr, &val); + + __GUEST_ASSERT(fault =3D=3D GP_VECTOR, + "Wanted #GP on RDMSR(%x) =3D %x, got 0x%x\n", + msr, GP_VECTOR, fault); + return val; + default: + return x2apic_read_reg(reg); + } +} + +static void guest_verify_host_guest_reg(struct guest_apic_page *apage, uin= t32_t reg, + uint64_t val, char *regname) +{ + uint64_t hval, gval, gval2; + + if (savic_wrmsr(reg, val) =3D=3D -1) { + savic_write_reg(apage, reg, val); + /* + * Write using PV interface if wrmsr fails. Skip for + * regs which trigger GP + */ + if (reg !=3D APIC_LVR && reg !=3D APIC_TMR && reg !=3D APIC_IRR) + savic_hv_write_reg(reg, val); + } + + gval =3D savic_read_reg(apage, reg); + gval2 =3D savic_rdmsr(reg); + hval =3D savic_hv_read_reg(reg); + __GUEST_ASSERT(gval =3D=3D val, "Unexpected Guest %s 0x%lx, expected val:= 0x%lx\n", + regname, gval, val); + __GUEST_ASSERT(gval =3D=3D gval2, "Unexpected Guest %s backing page value= : 0x%lx, msr read val:0x%lx\n", + regname, gval, gval2); + + switch (reg) { + case APIC_LVR: + case APIC_LDR: + case APIC_ISR: + case APIC_TMICT: + case APIC_TDCR: + case APIC_LVTT: + case APIC_LVTTHMR: + case APIC_LVTPC: + case APIC_LVT0: + case APIC_LVT1: + case APIC_LVTERR: + case APIC_SPIV: + __GUEST_ASSERT(hval =3D=3D gval, "Guest 0x%lx host 0x%lx %s mismatch\n", + gval, hval, regname); + break; + case APIC_TASKPRI: + case APIC_ICR: + case APIC_TMR: + case APIC_IRR: + __GUEST_ASSERT(hval !=3D gval, "Guest 0x%lx host 0x%lx reg: %x %s must n= ot match\n", + gval, hval, reg, regname); + break; + default: + break; + } +} + +static inline uint32_t x2apic_ldr(uint32_t id) +{ + return ((id >> 4) << 16) | (1 << (id & 0xf)); +} + +static void guest_savic_apic_msr_accesses(int id) +{ + struct guest_apic_page *apage =3D get_guest_apic_page(); + uint64_t val, hval; + uint32_t reg; + int vec; + int i; + uint32_t lvt_regs[] =3D { + APIC_LVTT, APIC_LVTTHMR, APIC_LVTPC, + APIC_LVT0, APIC_LVT1, APIC_LVTERR + }; + + reg =3D APIC_LVR; + val =3D savic_hv_read_reg(reg); + /* APIC_LVR state is in sync between host and guest. */ + guest_verify_host_guest_reg(apage, reg, val, "APIC_LVR"); + + reg =3D APIC_TASKPRI; + val =3D 0x30; + /* Write new TASKPRI to host using PV interface. */ + savic_hv_write_reg(reg, val); + val =3D 0x40; + /* TASKPRI is accelerated and state is not up-to-date in host. */ + guest_verify_host_guest_reg(apage, reg, val, "APIC_TASKPRI"); + + reg =3D APIC_PROCPRI; + val =3D x2apic_read_reg(reg); + /* APIC_PROCPRI is updated with the APIC_TASKPRI update above. */ + GUEST_ASSERT((val & 0xf0) =3D=3D (x2apic_read_reg(APIC_TASKPRI) & 0xf0)); + GUEST_ASSERT((val & 0xf0) =3D=3D 0x40); + vec =3D 0x20; + x2apic_write_reg(APIC_ICR, APIC_DEST_SELF | APIC_INT_ASSERT | vec); + /* Interrupt remains pending in APIC_IRR. */ + val =3D savic_read_reg(apage, APIC_IRR + APIC_REG_OFF(vec)); + GUEST_ASSERT((val & BIT_ULL(APIC_VEC_POS(vec))) =3D=3D BIT_ULL(APIC_VEC_P= OS(vec))); + savic_wrmsr(APIC_TASKPRI, 0x0); + + /* Triggers GP fault */ + savic_rdmsr(APIC_EOI); + + reg =3D APIC_LDR; + val =3D x2apic_ldr(savic_rdmsr(APIC_ID)); + hval =3D savic_hv_read_reg(APIC_LDR); + __GUEST_ASSERT(val =3D=3D hval, "APIC_LDR mismatch between host %lx and g= uest %lx", + hval, val); + + /* APIC_SPIV state is not visible to host. */ + reg =3D APIC_SPIV; + val =3D savic_rdmsr(APIC_SPIV) & ~APIC_SPIV_APIC_ENABLED; + savic_hv_write_reg(reg, val); + val =3D savic_rdmsr(APIC_SPIV) | APIC_SPIV_APIC_ENABLED; + guest_verify_host_guest_reg(apage, reg, val, "APIC_SPIV"); + + reg =3D APIC_ISR; + (void) savic_rdmsr(reg); + /* Triggers GP fault */ + savic_wrmsr(reg, 0x10); + + /* APIC_TMR is not synced to host. */ + reg =3D APIC_TMR; + val =3D 0x10000; + guest_verify_host_guest_reg(apage, reg, val, "APIC_TMR"); + vec =3D 0x20; + savic_write_reg(apage, reg + APIC_REG_OFF(vec), BIT_ULL(APIC_VEC_POS(vec= ))); + GUEST_ASSERT(x2apic_read_reg(reg + APIC_REG_OFF(vec)) & BIT_ULL(APIC_VEC_= POS(vec))); + + reg =3D APIC_IRR; + val =3D 0x10000; + guest_verify_host_guest_reg(apage, reg, val, "APIC_IRR"); + savic_write_reg(apage, reg, 0x0); + + reg =3D APIC_TMICT; + val =3D 0x555; + guest_verify_host_guest_reg(apage, reg, val, "APIC_TMICT"); + + reg =3D APIC_TMCCT; + savic_rdmsr(reg); + savic_wrmsr(reg, 0xf); + + reg =3D APIC_TDCR; + val =3D 0x1; + savic_hv_write_reg(reg, val); + val =3D 0x3; + guest_verify_host_guest_reg(apage, reg, val, "APIC_TDCR"); + + for (i =3D 0; i < ARRAY_SIZE(lvt_regs); i++) { + reg =3D lvt_regs[i]; + val =3D 0x41; + savic_hv_write_reg(reg, val); + val =3D 0x42; + guest_verify_host_guest_reg(apage, reg, val, "APIC_LVTx"); + } +} + +static void guest_code(int id) +{ + GUEST_ASSERT(rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SNP_SECURE_AVIC); + + x2apic_enable(); + + savic_enable(); + + SAVIC_GUEST_SYNC(SAVIC_APIC_MSR_ACCESSES, guest_savic_apic_msr_accesses); + + GUEST_DONE(); +} + +static void *vcpu_thread(void *arg) +{ + struct kvm_vcpu *vcpu =3D (struct kvm_vcpu *)arg; + struct ucall uc; + + fprintf(stderr, "vCPU thread running vCPU %u\n", vcpu->id); + + while (true) { + vcpu_run(vcpu); + switch (get_ucall(vcpu, &uc)) { + case UCALL_SYNC: + break; + case UCALL_DONE: + return NULL; + case UCALL_ABORT: + REPORT_GUEST_ASSERT(uc); + break; + case UCALL_NONE: + continue; + default: + TEST_FAIL("Unknown ucall 0x%lx.", uc.cmd); + } + + } + + return NULL; +} + +int main(int argc, char *argv[]) +{ + struct kvm_sev_init args =3D { + .vmsa_features =3D BIT_ULL(SVM_FEAT_SECURE_AVIC) + }; + struct kvm_vm *vm; + int r; + + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV_SNP)); + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SECURE_AVIC)); + + vm =3D _vm_sev_create_with_one_vcpu(KVM_X86_SNP_VM, guest_code, &vcpus[0]= , &args); + + virt_pg_map(vm, APIC_DEFAULT_GPA, APIC_DEFAULT_GPA); + + vcpu_args_set(vcpus[0], 1, vcpus[0]->id); + + vm_install_exception_handler(vm, 29, savic_vc_handler); + vm_sev_launch(vm, snp_default_policy(), NULL); + + r =3D pthread_create(&threads[0], NULL, vcpu_thread, vcpus[0]); + TEST_ASSERT(r =3D=3D 0, "pthread_create failed errno=3D%d", errno); + + pthread_join(threads[0], NULL); + + kvm_vm_free(vm); + + return 0; +} --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from CH4PR04CU002.outbound.protection.outlook.com (mail-northcentralusazon11013054.outbound.protection.outlook.com [40.107.201.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2D74B30FF28; Tue, 23 Sep 2025 05:19:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.201.54 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604754; cv=fail; b=am822VmGi3WD5thnt9kjJH6W2szgtocrQUkegTYOw2smaEs5n+eYiq1iLZXe7wHxAc51KNN2jQkeb/VFp0A7VrogfO4Ntgz7494YMTdiVjESH6szMSMaeQD1x9TuocGW3cLE+5CEkSz93Bpy5cLLW3YYBuNv26FZ+oS4uTwMEqY= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604754; c=relaxed/simple; bh=giMJhY30EOuv/MoNVR4D5QSuFDR5HT+r/1JEh4JlJjE=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=imROzR69y9uCfHsXFaKFxldX1OTqOgOGkXDD7flalWbP8u1dCMOObVQOiPHER1sGQeotspoHPlggRInGArrqt+e1alp+ewa2YkHeDtuobbnWT26W7n5MeRwc9gRtHnIyQO1f2BBEaajudrL2A37XOs95O2XuUR6c+sYcoN47f0g= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=aACUWV09; arc=fail smtp.client-ip=40.107.201.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="aACUWV09" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=soMCHo182QPFCYq8mkyxaR5q4RxNJNMj7KcKmClP38tMJhW9MkTqIPvX1/zXb00aymxyfLno0LXHyibV6jDOWWH7J2ASq8fBy9szmlx0vfRIBuewT0nN+ZRY73kuUemHxb3/cPXH4LWdx5OOh5LVO9PwsxiX8cuthH0PxqS6tMRGZamgnlOKSlVs4apIihOI4sZ3+aZwPLhHFFnpv4cro74z6mDYw6YmeiLfIhbaAzYBX0jGgm3x825JRLIVA6OstY0LtGQzYghJEQeXF/n1s1bD96Dwnhg9lW9l8b2RKFY4ApgxmTV1p7EpyI2hEV6eg5YE+4NN5ITae2GAEy5/EA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=gRFSosfZZgWfg2iNihdj+3hZ/t5JKG00bJzXyPBqY4c=; b=b1E2QIznBcBJMABOOm44u07RwOzfzvAgdF8vo4fJtRIQMCYqDx9SYrhwXfNClO2YY6AFzH9N8wFsB688dDaK4xhicvSaOeECi4nBDbibWNK8BZsDIv43iAu8D1DWSe7LtPyqqK96bDWx7quLpgT3w9T8vJxVxero6vjZsyZ4xJna2AMQZX4Mgm3sZEh4zBzMbrw87XGoInOvJpMq5eH2QG+wxEUmLJ8EFKd6bBO/FIXE/Zrr9DjBeKFCazybbQtrL9+dODxktjB0ZklxXMLJpOwyhO4cVXsubX04/+PX+knORXM27/Rkwg6dRs4yyvaHKZ9xd2do//kcvgqFzJi8nA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=gRFSosfZZgWfg2iNihdj+3hZ/t5JKG00bJzXyPBqY4c=; b=aACUWV09pDsYmi9E21pVBzX6uyamGns+9MV+2/mb6dGn3xX27kIc1k/yjcNvD9gWUB63nqsFf8N92ktaPtw13rvt1cXZpWEWHEmydJy8rwYAQKSWGieOGuTElC6ozdjFBbzhKHItBOV5eZqIb5foeZqh/OnACOZB/OkAVmxUCuc= Received: from BY5PR04CA0010.namprd04.prod.outlook.com (2603:10b6:a03:1d0::20) by DS7PR12MB6006.namprd12.prod.outlook.com (2603:10b6:8:7d::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.19; Tue, 23 Sep 2025 05:19:06 +0000 Received: from SJ5PEPF000001D3.namprd05.prod.outlook.com (2603:10b6:a03:1d0:cafe::2b) by BY5PR04CA0010.outlook.office365.com (2603:10b6:a03:1d0::20) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:19:06 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by SJ5PEPF000001D3.mail.protection.outlook.com (10.167.242.55) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:19:05 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:19:00 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 31/35] KVM: selftests: Extend savic_test with idle halt testing Date: Tue, 23 Sep 2025 10:39:38 +0530 Message-ID: <20250923050942.206116-32-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001D3:EE_|DS7PR12MB6006:EE_ X-MS-Office365-Filtering-Correlation-Id: cc5c64cb-2232-424a-2d39-08ddfa60b783 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|376014|82310400026|36860700013; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?KU1NmQhtug0tH/S0Pl1E2fbSB/uf+pVJi6Axvw1TgtNJFrY9hZPvynrEceS/?= =?us-ascii?Q?xWm5Iz7b20QwNF33yb0oxMr8NP/0h+/jvVruCBLMChoLEDTbYeFvwSwYFZwI?= =?us-ascii?Q?6wutL406goL2hs6BHOQB8+Mr+zbAcO/JpcbaA3sI1eGaxWnRTYnccRbaJTA/?= =?us-ascii?Q?cNKZFqedJrPp8DeD53WR7ZLYiqv8D5Mgy9dXPqYoREowea+WqqaYITNtXxII?= =?us-ascii?Q?vK74hsaFODdandIw9p0ajv3JR/hL1HtmQWhP/L4qUDth6vt/fI/4WoRJOMya?= =?us-ascii?Q?Gy2LtHZf+WBDWLYGHeEZ1fYsW0LSwCLrYJJFVy6VrbZZmPGms76Cf5m0N2b9?= =?us-ascii?Q?GhRB7TVuuqC9kbN5OyNOMOc/pgiB6esLOm/WNf4axNZhOet5YecD7bvva8MX?= =?us-ascii?Q?XT0l2dKBJ0+hdE0q1J8kGegqi6WbOt9/ayGvY9cYJjNozcTLZLk97DMcJIvq?= =?us-ascii?Q?YXhQOQGc6pqWEOOEEObEMSsmFHZu5OlTNxFI0/SCHZk5iucdDSSKtqpoD8pG?= =?us-ascii?Q?S8r+Vjh/27g5IcwfYRybCqh9uevbCuw2DHpF5LMB4i4taz56bVwtQ2Uv3nzY?= =?us-ascii?Q?i2k9TJcJQKL0ijT+/geJ1ZPQwomorFdRaIfZou1NLUcGJFqAGtNpIyQTIqe6?= =?us-ascii?Q?9th8/FybLNNc5L3mR7ROe/r4gt7/ZYuh6X/gdZ1vpsOJJUJHm2epB5RNYn4+?= =?us-ascii?Q?P6IX0WZzSWIZYQKs13LtRJ/JsusHK7XkSMWJOlRjW79oDOxsPKxYWEV7Hu4Y?= =?us-ascii?Q?nThzKBWQULTcXrDiWEGSRGnoVV8nH29o1N+MPX/1ut0WlAYen6I0L50hlsZU?= =?us-ascii?Q?f2m0H20/0Kc+aGKLdRULJkve+jbLn7I9JB4ns/8skPs17TWwD+c2nOrVD1jg?= =?us-ascii?Q?7YELSzCqxZtoJbiLeQ+pWWPmL5ia+f/F1qt1uE7FAc6W+/S3YuXlrd+q7UWg?= =?us-ascii?Q?dqhEgGt3j8rMaLPuXivzY8GjzAwnS4RD1seMGh0AHdTi0xyR4cD9jccp5Z/f?= =?us-ascii?Q?Tz2pMcYm19tXXBdyw9/KNXRlSjIYEOKm05VwEJqtfzBPUlzlL9BfTahtFWcJ?= =?us-ascii?Q?j0RR0Av8vTSUV8k9EMaIibay9Jyj4Mh2X2hiuo+TJjKbcma9M7iJjUSmDijF?= =?us-ascii?Q?pyOOS7k3CSSrmN6JcxXDiq/8XOm9cTMkhKSW/Angkx6ifOW118i9IKpg+JqM?= =?us-ascii?Q?GVF13XtObhdi3LAZQTjLR6dpOaTZx9/LH3TN+W8a4i0G6HAaCUzY2V5NVvNa?= =?us-ascii?Q?tppFrJAVTDaoe5QmxB6s2zXAQmzsvUjwAspaGkfzRlf8cs3AoFgGFDs6P5av?= =?us-ascii?Q?21IHcIVFVaRwSjn6oea1K+7wONalo1mnBhGArKmdrdOB344/FREWu07ofiuQ?= =?us-ascii?Q?gIThxLtNj2nwUApn7Lykb4Tm/0DXvmdG5qBQB71wM2vPZla84UOynzlwCcUd?= =?us-ascii?Q?k+w61try4q6UpLI96R0xS+BCAcNYauy8djJWOYAo8mPluD3YshR7/SbHuvxi?= =?us-ascii?Q?NvkTLSbh4ZGh1NLGuCkD4ZnVajQIAofD3FZa?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(376014)(82310400026)(36860700013);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:19:05.7759 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: cc5c64cb-2232-424a-2d39-08ddfa60b783 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ5PEPF000001D3.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS7PR12MB6006 Content-Type: text/plain; charset="utf-8" Add a test case to savic_test.c to verify the correct handling of HLT instructions in Secure AVIC (SAVIC) enabled guests. This validation is crucial for the SAVIC feature. With SAVIC, the IRR is managed in the guest's private memory (the APIC backing page), making it invisible to the hypervisor. In the absence of idle HLT intercept, the hypervisor would be unaware of pending interrupts in the IRR and would incorrectly block the vCPU. Additionally, verify the corresponding ISR and EOI behavior for the delivered interrupt within the SAVIC model. Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/x86/savic_test.c | 57 +++++++++++++++++++- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/kvm/x86/savic_test.c b/tools/testing/s= elftests/kvm/x86/savic_test.c index bac56f85caea..9108ac0077a9 100644 --- a/tools/testing/selftests/kvm/x86/savic_test.c +++ b/tools/testing/selftests/kvm/x86/savic_test.c @@ -14,7 +14,10 @@ #include "savic.h" =20 #define NR_SAVIC_VCPUS 1 +#define IDLE_HLT_INTR_VECTOR 0x30 +#define NUM_ITERATIONS 2000 =20 +static bool irq_received; static struct kvm_vcpu *vcpus[NR_SAVIC_VCPUS]; static pthread_t threads[NR_SAVIC_VCPUS]; =20 @@ -24,6 +27,7 @@ static pthread_t threads[NR_SAVIC_VCPUS]; =20 enum savic_test_state { SAVIC_TEST_STATE(SAVIC_APIC_MSR_ACCESSES), + SAVIC_TEST_STATE(SAVIC_IDLE_HALT), }; =20 #define SAVIC_GUEST_SYNC(sync, func) ({\ @@ -89,7 +93,8 @@ static void guest_verify_host_guest_reg(struct guest_apic= _page *apage, uint32_t hval =3D savic_hv_read_reg(reg); __GUEST_ASSERT(gval =3D=3D val, "Unexpected Guest %s 0x%lx, expected val:= 0x%lx\n", regname, gval, val); - __GUEST_ASSERT(gval =3D=3D gval2, "Unexpected Guest %s backing page value= : 0x%lx, msr read val:0x%lx\n", + __GUEST_ASSERT(gval =3D=3D gval2, + "Unexpected %s Guest backing page value : 0x%lx, msr read val:0x%lx\n", regname, gval, gval2); =20 switch (reg) { @@ -161,6 +166,7 @@ static void guest_savic_apic_msr_accesses(int id) val =3D savic_read_reg(apage, APIC_IRR + APIC_REG_OFF(vec)); GUEST_ASSERT((val & BIT_ULL(APIC_VEC_POS(vec))) =3D=3D BIT_ULL(APIC_VEC_P= OS(vec))); savic_wrmsr(APIC_TASKPRI, 0x0); + savic_write_reg(apage, APIC_IRR + APIC_REG_OFF(vec), 0); =20 /* Triggers GP fault */ savic_rdmsr(APIC_EOI); @@ -219,6 +225,43 @@ static void guest_savic_apic_msr_accesses(int id) } } =20 +static void guest_idle_hlt_intr_handler(struct ex_regs *regs) +{ + struct guest_apic_page *apage =3D get_guest_apic_page(); + uint32_t isr, reg; + + WRITE_ONCE(irq_received, true); + reg =3D APIC_ISR + APIC_REG_OFF(IDLE_HLT_INTR_VECTOR); + isr =3D savic_read_reg(apage, reg); + __GUEST_ASSERT(isr & BIT(APIC_VEC_POS(IDLE_HLT_INTR_VECTOR)), + "Idle halt vector not set in APIC_ISR"); + x2apic_write_reg(APIC_EOI, 0); + isr =3D savic_read_reg(apage, reg); + __GUEST_ASSERT(!(isr & BIT(APIC_VEC_POS(IDLE_HLT_INTR_VECTOR))), + "Idle halt vector set in APIC_ISR after EOI"); +} + +static void guest_savic_idle_halt(int id) +{ + uint32_t icr_val; + uint32_t irr; + int i; + + x2apic_write_reg(APIC_TASKPRI, 0); + icr_val =3D (APIC_DEST_SELF | APIC_INT_ASSERT | IDLE_HLT_INTR_VECTOR); + + for (i =3D 0; i < NUM_ITERATIONS; i++) { + asm volatile("cli"); + x2apic_write_reg(APIC_ICR, icr_val); + irr =3D x2apic_read_reg(APIC_IRR + APIC_REG_OFF(IDLE_HLT_INTR_VECTOR)); + __GUEST_ASSERT(irr & BIT(APIC_VEC_POS(IDLE_HLT_INTR_VECTOR)), + "Idle halt vector not set in APIC_IRR"); + asm volatile("sti; hlt;" : : : "memory"); + GUEST_ASSERT(READ_ONCE(irq_received)); + WRITE_ONCE(irq_received, false); + } +} + static void guest_code(int id) { GUEST_ASSERT(rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SNP_SECURE_AVIC); @@ -229,6 +272,8 @@ static void guest_code(int id) =20 SAVIC_GUEST_SYNC(SAVIC_APIC_MSR_ACCESSES, guest_savic_apic_msr_accesses); =20 + SAVIC_GUEST_SYNC(SAVIC_IDLE_HALT, guest_savic_idle_halt); + GUEST_DONE(); } =20 @@ -260,6 +305,12 @@ static void *vcpu_thread(void *arg) return NULL; } =20 +static void install_exception_handlers(struct kvm_vm *vm) +{ + vm_install_exception_handler(vm, IDLE_HLT_INTR_VECTOR, guest_idle_hlt_int= r_handler); + vm_install_exception_handler(vm, 29, savic_vc_handler); +} + int main(int argc, char *argv[]) { struct kvm_sev_init args =3D { @@ -270,14 +321,16 @@ int main(int argc, char *argv[]) =20 TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV_SNP)); TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SECURE_AVIC)); + TEST_REQUIRE(this_cpu_has(X86_FEATURE_IDLE_HLT)); =20 vm =3D _vm_sev_create_with_one_vcpu(KVM_X86_SNP_VM, guest_code, &vcpus[0]= , &args); =20 virt_pg_map(vm, APIC_DEFAULT_GPA, APIC_DEFAULT_GPA); =20 + install_exception_handlers(vm); + vcpu_args_set(vcpus[0], 1, vcpus[0]->id); =20 - vm_install_exception_handler(vm, 29, savic_vc_handler); vm_sev_launch(vm, snp_default_policy(), NULL); =20 r =3D pthread_create(&threads[0], NULL, vcpu_thread, vcpus[0]); --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from CO1PR03CU002.outbound.protection.outlook.com (mail-westus2azon11010009.outbound.protection.outlook.com [52.101.46.9]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2575827511F; Tue, 23 Sep 2025 05:19:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.46.9 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604771; cv=fail; b=hFO8q5smlP3EyF377+lJF7WvMcRgHu5nS9yziJfyzW9HPsbF0k+0c5D78Tl3D7nyCMTdRmZJ4zNQBpx0gl6yKCW2YYjqvdLO0SQ8xyJe7vVheTG96gIdFjNZiHJWPjoksVv6F6tXgh8ikxGCp2lSjR/f+jU1TT5zAAPY5cFuAJY= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604771; c=relaxed/simple; bh=6zya8ZUZSI1/Jpx7Pa58+vLZF/h/A2FNoUkbxQC3gCs=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=KEB1j4izVSs9AD2yNz01rJdLkc9UcZwqqRNW9ouY7GRGTglY+r64jxptjs54TBQmEundfDBVbsqxTWN3DxqMMcPIo5o4IL33N7KfRyhpYMe/L8wWgv9NeE4sQ8KjDl82a/jz47bKErVCAGZAqAWHtykB0CnzRtN+JMJRvPVe89A= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=mXTFeAkm; arc=fail smtp.client-ip=52.101.46.9 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="mXTFeAkm" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=CfTqupZFyTnmTjzAfZUsw41Bw7/W65JxbB9BWabFbFwFWLOKwJPOH5XNoAkvV6ZjkWq7PxjEV7JI27oBzG6yWjgq460Y3KFyIk5DK3atrSUjpMBVwCRPLTWOlPWo2Ay4hpFs12s+09yj2q6gg++XgtZognyE0XWaIZBvH9VRt7acRupjYvOAkLzp6xBb4gIaC3O+2OoDn8YQi/zZTg+ogEZUzJOoa5UQ6qfrafI4zKXR5FCbMBCdIu3BfqXAVqcdc92o2NNN1cyMbHTQXpCWZ0g0e+ueT3LZUabp51zhkCX0AS7c3tPqmQrSph2KCje1yjO//Gt/UWFww0UEr8q/Tg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=G9g2kC7GJafYz6p6d3zmWi9XVAF4GUMDGn3HWgiuvOQ=; b=a8ZCI1ZVR9dnozapH31Ut6ASRWEzxrF8j0ucXFGFr94Xx+8qMNGYVJFqP4RBRI9FHvzLMD21o6AxJbacrFvOoBRVTqNu50TB8YSNUeFOj81ywPWbWiHC5PbaLDPinWxCBDsUQgMQckytk00eYso6MWIYTd59s4lqGlPIskyNJeDvZzCa8A0Ic2DILwWhnyywuQuE+rZHTOlxUa8yqyUie/ZFEkeZbtPkD7OEKVNs3g9mgS1eXl+GKQUlH97ey7WKOcIC4qO1XLMeDjGVH6EHFVMNVpiL0Rmdnt1nbqIBkNI6kya9QjC9m0mwgpEa1leESPVb0OB2Oh+UiAm+6sRxqQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=G9g2kC7GJafYz6p6d3zmWi9XVAF4GUMDGn3HWgiuvOQ=; b=mXTFeAkm9AI07FgRyewePylItJLaT8ht9fU9gw3lollmpBXdEi9hJav6hN658GwBDYL7i4mHZx+C3cjAXlzO+wwNVniFtHmf69d7YuCFWzFiOZTE3De0Ibmq9bHYTWSVm4sbtDuEFg9CASW5KrPySBVCXvbDMTZQW7cxYSI8qU4= Received: from SJ0PR03CA0356.namprd03.prod.outlook.com (2603:10b6:a03:39c::31) by CH2PR12MB4136.namprd12.prod.outlook.com (2603:10b6:610:a4::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.19; Tue, 23 Sep 2025 05:19:24 +0000 Received: from SJ5PEPF000001D1.namprd05.prod.outlook.com (2603:10b6:a03:39c:cafe::54) by SJ0PR03CA0356.outlook.office365.com (2603:10b6:a03:39c::31) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:19:23 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by SJ5PEPF000001D1.mail.protection.outlook.com (10.167.242.53) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:19:23 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:19:18 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 32/35] KVM: selftests: Add IOAPIC tests for Secure AVIC Date: Tue, 23 Sep 2025 10:39:39 +0530 Message-ID: <20250923050942.206116-33-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001D1:EE_|CH2PR12MB4136:EE_ X-MS-Office365-Filtering-Correlation-Id: 48bab5a2-91f8-4305-15e8-08ddfa60c22b X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|376014|82310400026|36860700013; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?ZDpuFzJmYDQNoj63y/f8/7Gy/lwvSM6EzIDKhjJMaZfWknO7qkCAlRrG09/V?= =?us-ascii?Q?e7Tj5HuWwzcBux1Feset0WRWJBoe9xFOlPk3d4okJyUWN5YixmKWo1oIwGjE?= =?us-ascii?Q?SKsrx25tn8hN2YiNYHOywyhBvh16b3gg8QEzNqhfpZNQAwdPUR9LQ1VYTmZc?= =?us-ascii?Q?EDmNALOCTmRPB8C1o89DbEFUrXQyB7jZf/zbxgoJ71xctMG9iF9DTHMTeirr?= =?us-ascii?Q?w9l2BoYOYi6EZKqPvWqHjZ705ZEtEI9hLSWKD349tWkOKqfHuxlnKa0uc6Fz?= =?us-ascii?Q?NbUFkPnWwjkqd/Lso65zBVQcLPG4j12jSb1yu6+74NqbXa+LBkXyfCreWljY?= =?us-ascii?Q?qSRwjZHWE2EDjMPq+FvoZCFWcY1f7JDsr+ukfa7kq6CXlbEi4TQACzDoQq0u?= =?us-ascii?Q?Y+Ri7jCRah9FsETs0rNBtuZRCHylJUo6MtgcUywl0Qqx/FbyCsD0nWjKljrr?= =?us-ascii?Q?GCFYE1kZADFO9b7PfKBwWy1d2qamZWlV1Sg9UT0l2LB1URiBAtQ7Q1AXbgvL?= =?us-ascii?Q?3mmxyzPVoKAxaBc9b9NfgMLBoUQWAJ8pJ+qmkYeTYk8cuPLncZnZoBzC2fhe?= =?us-ascii?Q?f9WiqpUIJxS5tOWMtUKGv6lpizDMoIzfIyETWMoloDkQ/SOq9nlO4iflkknB?= =?us-ascii?Q?NvJXon+hMfwW64zuOMkWUDB1/wnQauxyP1nSOTKvXqnyPG4ghZ5xqmsKYiJe?= =?us-ascii?Q?N8DVWMk2WHFzZNG/lCoUbKQwbZdQmGhMNfl+QvQ+xZ+sGYFTXL55mowphUzA?= =?us-ascii?Q?7xiRNLh264EHMoHEmz5EULxBUHGzwrzdImOzC5FyQu1LYG8sq0bp4vcV6uva?= =?us-ascii?Q?utTe+Cu02QtgT1r32LMtimYeHCNVA2MnQKjg2Ffx67HvJ7JtEsgu6KkcWXkW?= =?us-ascii?Q?xQdXNv0rAqL8GJUvs4BqvGQWS5QMhm5MVtWlv6crcr8kohQO0UMxfxBf/cBf?= =?us-ascii?Q?P6s/50fuYxmtkdXF56S4Mx8EVtgMclHmScPHYHHuWd0kdbrmhmMw/slab/wA?= =?us-ascii?Q?cvd9BzLUIuoQGoLTjoDkf+aAO958dBb9uy0Of7qxOGjiI54ixS/JOsxuoLWK?= =?us-ascii?Q?wd/dxdj+9rnhyA1Flq1OAt9TYS9Akm5N/8Gzlng7yypYyDFtHwwQ62xz9s7G?= =?us-ascii?Q?IBee90FOtiggExFsIdRUO+qWhpPzsJ7Sp75OTFRs5S6Uo2mpEcSnSC0jUDLJ?= =?us-ascii?Q?Kag9jPtZuyNT0xIQBVBhXErTEOPwriHJKPShTKIgKCSFGDmbdnxA2nbWxGjf?= =?us-ascii?Q?ESIMKHAEFUfs2KAxcq+QMN9G0+AuPWV1CtX8trStw2Lx9BaTMas2qR0bXyQN?= =?us-ascii?Q?xD/ktWCHLvoOSdpcr00ZQ/zJeuiTUy8cO4CAA8Iv0qkwq1d93EHJkRGZ4ap6?= =?us-ascii?Q?6tVFubet5qDyTdsRN54Mq01YdVixVCfVYpzVK0JjUPEX/p7J3d4Tg2OUZsf/?= =?us-ascii?Q?TI2dUvVvNZUohv1jKv/nfgtnCRwvX69tPxXU+QbiF8rzRI1atatm00RPoU3B?= =?us-ascii?Q?Ro7tppxakx3GOlP7aaTVLZjOrn+rjihEFcVo?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(376014)(82310400026)(36860700013);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:19:23.6530 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 48bab5a2-91f8-4305-15e8-08ddfa60c22b X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ5PEPF000001D1.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH2PR12MB4136 Content-Type: text/plain; charset="utf-8" Extend the Secure AVIC (SAVIC) selftest to validate the delivery of external interrupts via the IOAPIC. This is a critical validation step, as the interrupt injection path for SAVIC guests is different from traditional APIC modes and requires explicit guest cooperation. In SAVIC mode, for the hardware to inject an external interrupt, the guest must first grant permission for the corresponding vector. This is done by setting a bit in a designated "allowed IRR" region within its private APIC backing page. If the vector is not allowed, the interrupt is dropped by the hardware. Add a new test case to savic_test.c and verify this entire flow of IOAPIC interrupt injection for both edge and level-triggered interrupts. Also test the special-cased RTC GSI (IRQ 8). To support this, add new helpers for reading/writing the IOAPIC MMIO region and updating the IOAPIC redirection table. Signed-off-by: Neeraj Upadhyay --- .../testing/selftests/kvm/include/kvm_util.h | 1 + .../testing/selftests/kvm/include/x86/apic.h | 49 ++++ .../testing/selftests/kvm/include/x86/savic.h | 1 + tools/testing/selftests/kvm/lib/kvm_util.c | 17 ++ .../testing/selftests/kvm/lib/x86/processor.c | 2 +- tools/testing/selftests/kvm/lib/x86/savic.c | 11 + tools/testing/selftests/kvm/x86/savic_test.c | 253 +++++++++++++++++- 7 files changed, 330 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing= /selftests/kvm/include/kvm_util.h index e5f322994f44..513e68f88179 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -952,6 +952,7 @@ void *vcpu_map_dirty_ring(struct kvm_vcpu *vcpu); void vcpu_args_set(struct kvm_vcpu *vcpu, unsigned int num, ...); =20 void kvm_irq_line(struct kvm_vm *vm, uint32_t irq, int level); +void kvm_irq_line_status(struct kvm_vm *vm, uint32_t irq, int level); int _kvm_irq_line(struct kvm_vm *vm, uint32_t irq, int level); =20 #define KVM_MAX_IRQ_ROUTES 4096 diff --git a/tools/testing/selftests/kvm/include/x86/apic.h b/tools/testing= /selftests/kvm/include/x86/apic.h index af555638086f..765c463dff33 100644 --- a/tools/testing/selftests/kvm/include/x86/apic.h +++ b/tools/testing/selftests/kvm/include/x86/apic.h @@ -12,6 +12,7 @@ #include "ucall_common.h" =20 #define APIC_DEFAULT_GPA 0xfee00000ULL +#define IOAPIC_DEFAULT_GPA 0xfec00000ULL =20 /* APIC base address MSR and fields */ #define MSR_IA32_APICBASE 0x0000001b @@ -122,5 +123,53 @@ static inline void x2apic_write_reg_fault(unsigned int= reg, uint64_t value) APIC_BASE_MSR + (reg >> 4), value, fault); } =20 +struct ioapic_redirect_entry { + uint8_t vector; + uint8_t delivery_mode:3; + uint8_t dest_mode:1; + uint8_t delivery_status:1; + uint8_t polarity:1; + uint8_t remote_irr:1; + uint8_t trig_mode:1; + uint8_t mask:1; + uint8_t reserve:7; + uint8_t reserved[4]; + uint8_t dest_id; +}; + +enum trigger_mode { + TRIGGER_EDGE =3D 0, + TRIGGER_LEVEL, + TRIGGER_MAX, +}; + +static void *ioapic_addr =3D (void *)IOAPIC_DEFAULT_GPA; + +static inline void ioapic_write_reg(uint32_t reg, uint32_t val) +{ + *(volatile uint32_t *)ioapic_addr =3D reg; + *(volatile u32 *)(ioapic_addr + 0x10) =3D val; +} + +static inline void ioapic_write_redir(unsigned int line, struct ioapic_red= irect_entry e) +{ + ioapic_write_reg(0x10 + line * 2 + 0, ((uint32_t *)&e)[0]); + ioapic_write_reg(0x10 + line * 2 + 1, ((uint32_t *)&e)[1]); +} + +static inline uint32_t ioapic_read_reg(unsigned int reg) +{ + *(volatile uint32_t *)ioapic_addr =3D reg; + return *(volatile uint32_t *)(ioapic_addr + 0x10); +} + +static inline struct ioapic_redirect_entry ioapic_read_redir(unsigned int = line) +{ + struct ioapic_redirect_entry e; + + ((u32 *)&e)[0] =3D ioapic_read_reg(0x10 + line * 2 + 0); + ((u32 *)&e)[1] =3D ioapic_read_reg(0x10 + line * 2 + 1); =20 + return e; +} #endif /* SELFTEST_KVM_APIC_H */ diff --git a/tools/testing/selftests/kvm/include/x86/savic.h b/tools/testin= g/selftests/kvm/include/x86/savic.h index 33f19f5e39b3..73965edfef5c 100644 --- a/tools/testing/selftests/kvm/include/x86/savic.h +++ b/tools/testing/selftests/kvm/include/x86/savic.h @@ -21,4 +21,5 @@ void savic_enable(void); int savic_nr_pages_required(uint64_t page_size); void savic_vc_handler(struct ex_regs *regs); struct guest_apic_page *get_guest_apic_page(void); +void savic_allow_vector(int vec); #endif diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index 23272f797f5f..e830425d5d60 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -1964,6 +1964,23 @@ void kvm_irq_line(struct kvm_vm *vm, uint32_t irq, i= nt level) TEST_ASSERT(ret >=3D 0, KVM_IOCTL_ERROR(KVM_IRQ_LINE, ret)); } =20 +int _kvm_irq_line_status(struct kvm_vm *vm, uint32_t irq, int level) +{ + struct kvm_irq_level irq_level =3D { + .irq =3D irq, + .level =3D level, + }; + + return __vm_ioctl(vm, KVM_IRQ_LINE_STATUS, &irq_level); +} + +void kvm_irq_line_status(struct kvm_vm *vm, uint32_t irq, int level) +{ + int ret =3D _kvm_irq_line_status(vm, irq, level); + + TEST_ASSERT(ret >=3D 0, KVM_IOCTL_ERROR(KVM_IRQ_LINE_STATUS, ret)); +} + struct kvm_irq_routing *kvm_gsi_routing_create(void) { struct kvm_irq_routing *routing; diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testin= g/selftests/kvm/lib/x86/processor.c index fc57b948c041..af2604483e60 100644 --- a/tools/testing/selftests/kvm/lib/x86/processor.c +++ b/tools/testing/selftests/kvm/lib/x86/processor.c @@ -229,7 +229,7 @@ void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, u= int64_t paddr, int level) "PTE already present for 4k page at vaddr: 0x%lx", vaddr); *pte =3D PTE_PRESENT_MASK | PTE_WRITABLE_MASK | (paddr & PHYSICAL_PAGE_MA= SK); =20 - if (paddr =3D=3D APIC_DEFAULT_GPA) { + if (paddr =3D=3D APIC_DEFAULT_GPA || paddr =3D=3D IOAPIC_DEFAULT_GPA) { *pte |=3D vm->arch.s_bit; return; } diff --git a/tools/testing/selftests/kvm/lib/x86/savic.c b/tools/testing/se= lftests/kvm/lib/x86/savic.c index da01bb5deae1..c941fd3f22df 100644 --- a/tools/testing/selftests/kvm/lib/x86/savic.c +++ b/tools/testing/selftests/kvm/lib/x86/savic.c @@ -45,6 +45,7 @@ enum lapic_lvt_entry { #define SVM_EXIT_AVIC_UNACCELERATED_ACCESS 0x402 #define SVM_EXIT_AVIC_INCOMPLETE_IPI 0x401 =20 +#define SAVIC_ALLOWED_IRR (APIC_IRR + 0x4) #define SAVIC_NMI_REQ_OFFSET 0x278 =20 /* @@ -107,6 +108,16 @@ struct guest_apic_page *get_guest_apic_page(void) return &apic_page_pool->guest_apic_page[x2apic_read_reg(APIC_ID)]; } =20 +void savic_allow_vector(int vec) +{ + struct guest_apic_page *apage =3D get_guest_apic_page(); + + savic_write_reg(apage, SAVIC_ALLOWED_IRR + APIC_REG_OFF(vec), + savic_read_reg(apage, SAVIC_ALLOWED_IRR + APIC_REG_OFF(vec)) | + BIT_ULL(APIC_VEC_POS(vec))); + +} + /* * Write APIC reg offset in the guest APIC backing page. * diff --git a/tools/testing/selftests/kvm/x86/savic_test.c b/tools/testing/s= elftests/kvm/x86/savic_test.c index 9108ac0077a9..aa8a7244aa55 100644 --- a/tools/testing/selftests/kvm/x86/savic_test.c +++ b/tools/testing/selftests/kvm/x86/savic_test.c @@ -14,9 +14,15 @@ #include "savic.h" =20 #define NR_SAVIC_VCPUS 1 -#define IDLE_HLT_INTR_VECTOR 0x30 #define NUM_ITERATIONS 2000 =20 +#define IDLE_HLT_INTR_VECTOR 0x30 +#define IOAPIC_VECTOR_START 0x81 +#define IOAPIC_NUM_EDGE_VECTORS 2 +#define IOAPIC_NUM_LEVEL_VECTORS 2 +#define RTC_GSI 8 +#define RTC_GSI_IRQ 0x85 + static bool irq_received; static struct kvm_vcpu *vcpus[NR_SAVIC_VCPUS]; static pthread_t threads[NR_SAVIC_VCPUS]; @@ -28,8 +34,21 @@ static pthread_t threads[NR_SAVIC_VCPUS]; enum savic_test_state { SAVIC_TEST_STATE(SAVIC_APIC_MSR_ACCESSES), SAVIC_TEST_STATE(SAVIC_IDLE_HALT), + SAVIC_TEST_STATE(SAVIC_IOAPIC), + SAVIC_TEST_STATE(SAVIC_IOAPIC2), +}; + +/* Data struct shared between host main thread and vCPUs */ +struct test_data_page { + uint64_t ioapic_eirq1_count; + uint64_t ioapic_eirq2_count; + uint64_t ioapic_lirq1_count; + uint64_t ioapic_lirq2_count; + uint64_t ioapic_rtc_gsi_irq_count; }; =20 +static struct test_data_page *test_data[NR_SAVIC_VCPUS]; + #define SAVIC_GUEST_SYNC(sync, func) ({\ GUEST_SYNC(sync ## _START); \ func(id); \ @@ -262,6 +281,177 @@ static void guest_savic_idle_halt(int id) } } =20 +static void _ioapic_level_irq_handler(int vec) +{ + uint32_t isr, tmr; + int offset, pos; + + offset =3D APIC_REG_OFF(vec); + pos =3D APIC_VEC_POS(vec); + isr =3D savic_hv_read_reg(APIC_ISR + offset); + tmr =3D savic_hv_read_reg(APIC_TMR + offset); + + __GUEST_ASSERT(tmr & BIT_ULL(pos), + "IOAPIC level vector %d trigger mode in not set in host TMR: %x", + vec, tmr); + __GUEST_ASSERT(isr & BIT_ULL(pos), + "IOAPIC level vector %d in not set in host ISR: %x", + vec, isr); + + x2apic_write_reg(APIC_EOI, 0x00); + savic_hv_write_reg(APIC_EOI, 0); + + isr =3D savic_hv_read_reg(APIC_ISR + offset); + __GUEST_ASSERT(!(isr & BIT_ULL(pos)), + "IOAPIC level vector %d set in host ISR after EOI", + vec); +} + +static void ioapic_level_irq1_intr_handler(struct ex_regs *regs) +{ + struct test_data_page *data =3D test_data[x2apic_read_reg(APIC_ID)]; + int vec; + + vec =3D IOAPIC_VECTOR_START + IOAPIC_NUM_EDGE_VECTORS; + WRITE_ONCE(data->ioapic_lirq1_count, data->ioapic_lirq1_count + 1); + _ioapic_level_irq_handler(vec); +} + +static void ioapic_level_irq2_intr_handler(struct ex_regs *regs) +{ + struct test_data_page *data =3D test_data[x2apic_read_reg(APIC_ID)]; + int vec; + + vec =3D IOAPIC_VECTOR_START + IOAPIC_NUM_EDGE_VECTORS + 1; + WRITE_ONCE(data->ioapic_lirq2_count, data->ioapic_lirq2_count + 1); + _ioapic_level_irq_handler(vec); +} + +static void ioapic_edge_irq1_intr_handler(struct ex_regs *regs) +{ + struct test_data_page *data =3D test_data[x2apic_read_reg(APIC_ID)]; + + WRITE_ONCE(data->ioapic_eirq1_count, data->ioapic_eirq1_count + 1); + x2apic_write_reg(APIC_EOI, 0x00); +} + +static void ioapic_edge_irq2_intr_handler(struct ex_regs *regs) +{ + struct test_data_page *data =3D test_data[x2apic_read_reg(APIC_ID)]; + + WRITE_ONCE(data->ioapic_eirq2_count, data->ioapic_eirq2_count + 1); + x2apic_write_reg(APIC_EOI, 0x00); +} + +static void ioapic_rtc_gsi_intr_handler(struct ex_regs *regs) +{ + struct test_data_page *data =3D test_data[x2apic_read_reg(APIC_ID)]; + + WRITE_ONCE(data->ioapic_rtc_gsi_irq_count, data->ioapic_rtc_gsi_irq_count= + 1); + x2apic_write_reg(APIC_EOI, 0x00); +} + +static void __savic_ioapic(int count) +{ + struct test_data_page *data =3D test_data[x2apic_read_reg(APIC_ID)]; + int vec =3D IOAPIC_VECTOR_START; + + __GUEST_ASSERT(READ_ONCE(data->ioapic_eirq1_count) =3D=3D count, + "Invalid ioapic edge irq %d count: %ld, expected: %d", + vec, READ_ONCE(data->ioapic_eirq1_count), count); + __GUEST_ASSERT(READ_ONCE(data->ioapic_eirq2_count) =3D=3D count, + "Invalid ioapic edge irq %d count: %ld, expected: %d", + vec + 1, READ_ONCE(data->ioapic_eirq2_count), count); + __GUEST_ASSERT(READ_ONCE(data->ioapic_lirq1_count) =3D=3D count, + "Invalid ioapic level irq %d count: %ld, expected: %d", + vec + 2, READ_ONCE(data->ioapic_lirq1_count), count); + __GUEST_ASSERT(READ_ONCE(data->ioapic_lirq2_count) =3D=3D count, + "Invalid ioapic level irq %d count: %ld, expected: %d", + vec + 3, READ_ONCE(data->ioapic_lirq2_count), count); + __GUEST_ASSERT(READ_ONCE(data->ioapic_rtc_gsi_irq_count) =3D=3D count, + "Invalid ioapic RTC irq %d count: %ld, expected: %d", + RTC_GSI_IRQ, READ_ONCE(data->ioapic_rtc_gsi_irq_count), + count); +} + +static void savic_ioapic(int id) +{ + __savic_ioapic(1); +} + +static void savic_ioapic2(int id) +{ + __savic_ioapic(2); +} + +static void ioapic_set_redir(unsigned int line, unsigned int vec, + enum trigger_mode trig_mode) +{ + struct ioapic_redirect_entry e =3D { + .vector =3D vec, + .delivery_mode =3D 0, + .dest_mode =3D 0, + .trig_mode =3D trig_mode, + .mask =3D 0, + .dest_id =3D 0, + .delivery_status =3D 0, + .remote_irr =3D 0, + }; + + ioapic_write_redir(line, e); +} + +static void guest_setup_ioapic(int id) +{ + int vec =3D IOAPIC_VECTOR_START; + struct ioapic_redirect_entry e; + int i, line =3D 0; + + for (i =3D 0; i < IOAPIC_NUM_EDGE_VECTORS; i++) { + ioapic_set_redir(line, vec, TRIGGER_EDGE); + e =3D ioapic_read_redir(line); + __GUEST_ASSERT( + e.vector =3D=3D vec && e.trig_mode =3D=3D TRIGGER_EDGE && + e.dest_id =3D=3D 0, + "Invalid IOAPIC redir entry for line : %d, trig_mode: %d vector: %d", + line, e.trig_mode, e.vector); + vec++; + line++; + } + + for (i =3D 0; i < IOAPIC_NUM_LEVEL_VECTORS; i++) { + ioapic_set_redir(line, vec, TRIGGER_LEVEL); + e =3D ioapic_read_redir(line); + __GUEST_ASSERT( + e.vector =3D=3D vec && e.trig_mode =3D=3D TRIGGER_LEVEL && + e.dest_id =3D=3D 0, + "Invalid IOAPIC redir entry for line : %d, trig_mode: %d vector: %d", + line, e.trig_mode, e.vector); + line++; + vec++; + } + + vec =3D RTC_GSI_IRQ; + line =3D RTC_GSI; + ioapic_set_redir(line, vec, TRIGGER_EDGE); + e =3D ioapic_read_redir(line); + __GUEST_ASSERT( + e.vector =3D=3D vec && e.trig_mode =3D=3D TRIGGER_EDGE && + e.dest_id =3D=3D 0, + "Invalid IOAPIC redir entry for line : %d, trig_mode: %d vector: %d", + line, e.trig_mode, e.vector); + + x2apic_write_reg(APIC_TASKPRI, 0); + + for (i =3D 0; i < (IOAPIC_NUM_EDGE_VECTORS + IOAPIC_NUM_LEVEL_VECTORS); i= ++) { + vec =3D IOAPIC_VECTOR_START + i; + savic_allow_vector(vec); + } + + vec =3D RTC_GSI_IRQ; + savic_allow_vector(vec); +} + static void guest_code(int id) { GUEST_ASSERT(rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SNP_SECURE_AVIC); @@ -274,9 +464,41 @@ static void guest_code(int id) =20 SAVIC_GUEST_SYNC(SAVIC_IDLE_HALT, guest_savic_idle_halt); =20 + guest_setup_ioapic(id); + SAVIC_GUEST_SYNC(SAVIC_IOAPIC, savic_ioapic); + SAVIC_GUEST_SYNC(SAVIC_IOAPIC2, savic_ioapic2); + GUEST_DONE(); } =20 +static void host_send_ioapic_irq(struct kvm_vm *vm, int id) +{ + kvm_irq_line(vm, 0, 1); + kvm_irq_line(vm, 1, 1); + kvm_irq_line(vm, 0, 0); + kvm_irq_line(vm, 1, 0); + kvm_irq_line(vm, 2, 1); + kvm_irq_line(vm, 2, 0); + kvm_irq_line(vm, 3, 1); + kvm_irq_line(vm, 3, 0); + kvm_irq_line_status(vm, RTC_GSI, 1); + kvm_irq_line_status(vm, RTC_GSI, 0); +} + +static void host_test_savic(struct kvm_vm *vm, int id, enum savic_test_sta= te test_state) +{ + switch (test_state) { + case SAVIC_IOAPIC_START: + host_send_ioapic_irq(vm, id); + break; + case SAVIC_IOAPIC2_START: + host_send_ioapic_irq(vm, id); + break; + default: + break; + } +} + static void *vcpu_thread(void *arg) { struct kvm_vcpu *vcpu =3D (struct kvm_vcpu *)arg; @@ -288,6 +510,7 @@ static void *vcpu_thread(void *arg) vcpu_run(vcpu); switch (get_ucall(vcpu, &uc)) { case UCALL_SYNC: + host_test_savic(vcpu->vm, vcpu->id, uc.args[1]); break; case UCALL_DONE: return NULL; @@ -299,7 +522,6 @@ static void *vcpu_thread(void *arg) default: TEST_FAIL("Unknown ucall 0x%lx.", uc.cmd); } - } =20 return NULL; @@ -309,6 +531,11 @@ static void install_exception_handlers(struct kvm_vm *= vm) { vm_install_exception_handler(vm, IDLE_HLT_INTR_VECTOR, guest_idle_hlt_int= r_handler); vm_install_exception_handler(vm, 29, savic_vc_handler); + vm_install_exception_handler(vm, IOAPIC_VECTOR_START, ioapic_edge_irq1_in= tr_handler); + vm_install_exception_handler(vm, IOAPIC_VECTOR_START + 1, ioapic_edge_irq= 2_intr_handler); + vm_install_exception_handler(vm, IOAPIC_VECTOR_START + 2, ioapic_level_ir= q1_intr_handler); + vm_install_exception_handler(vm, IOAPIC_VECTOR_START + 3, ioapic_level_ir= q2_intr_handler); + vm_install_exception_handler(vm, RTC_GSI_IRQ, ioapic_rtc_gsi_intr_handler= ); } =20 int main(int argc, char *argv[]) @@ -316,8 +543,10 @@ int main(int argc, char *argv[]) struct kvm_sev_init args =3D { .vmsa_features =3D BIT_ULL(SVM_FEAT_SECURE_AVIC) }; + struct test_data_page *shared_data[NR_SAVIC_VCPUS]; + vm_vaddr_t test_data_page_vaddr; struct kvm_vm *vm; - int r; + int i, r; =20 TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV_SNP)); TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SECURE_AVIC)); @@ -326,11 +555,21 @@ int main(int argc, char *argv[]) vm =3D _vm_sev_create_with_one_vcpu(KVM_X86_SNP_VM, guest_code, &vcpus[0]= , &args); =20 virt_pg_map(vm, APIC_DEFAULT_GPA, APIC_DEFAULT_GPA); + virt_pg_map(vm, IOAPIC_DEFAULT_GPA, IOAPIC_DEFAULT_GPA); =20 install_exception_handlers(vm); =20 vcpu_args_set(vcpus[0], 1, vcpus[0]->id); =20 + for (i =3D 0; i < NR_SAVIC_VCPUS; i++) { + test_data_page_vaddr =3D vm_vaddr_alloc_page_shared(vm); + test_data[i] =3D (struct test_data_page *)test_data_page_vaddr; + shared_data[i] =3D addr_gva2hva(vm, test_data_page_vaddr); + vm_mem_set_shared(vm, addr_hva2gpa(vm, shared_data[i]), getpagesize()); + } + + sync_global_to_guest(vm, test_data); + vm_sev_launch(vm, snp_default_policy(), NULL); =20 r =3D pthread_create(&threads[0], NULL, vcpu_thread, vcpus[0]); @@ -338,6 +577,14 @@ int main(int argc, char *argv[]) =20 pthread_join(threads[0], NULL); =20 + for (i =3D 0; i < NR_SAVIC_VCPUS; i++) { + struct test_data_page *shared_state =3D shared_data[i]; + + fprintf(stderr, "VCPU %d ioapic edge irq1 count: %ld edge irq2 count: %l= d\n", i, shared_state->ioapic_eirq1_count, shared_state->ioapic_eirq2_count= ); + fprintf(stderr, "VCPU %d ioapic level irq1 count: %ld level irq2 count: = %ld\n", i, shared_state->ioapic_lirq1_count, shared_state->ioapic_lirq2_cou= nt); + fprintf(stderr, "VCPU %d ioapic RTC GSI irq1 count: %ld\n", i, shared_st= ate->ioapic_rtc_gsi_irq_count); + } + kvm_vm_free(vm); =20 return 0; --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from CH5PR02CU005.outbound.protection.outlook.com (mail-northcentralusazon11012071.outbound.protection.outlook.com [40.107.200.71]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5A32A27511F; Tue, 23 Sep 2025 05:19:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.200.71 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604790; cv=fail; b=pyiXgFml3GCGKfQU+iKGZ6yzS0tchHGdziWkiRUpv/dqyHN+/W2uBW2W6t/L72glnRSG5+fuGTwT3Y4DBhp4C+hOjP8AHMxpnwf6d6gWrCk/mNtcOcQddXvj3sBjv6vYd6+xt+pejXis3UiDV/TgE4D3I04O+20SNPzdtMr4a38= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604790; c=relaxed/simple; bh=C53+Ci0hQrsTfdRIHMjM9/b+JLo2q1cuhrW6wyYeylM=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=SeBDqLp37UP+3aZ7Q98Rx/RsOcLxo4bIWCpBitZNlZcAz0QhQkj8yjbRq+pjEdR/zphLZDfp40L36QwQ1MsSuu2mYw+/mY1KvgLn5vBciEkDA6R/aSoowqsHrTs4eifjdDBxdABzSiDiUyVjT1aeld94AeMFQMgEhhb7DN7+xVE= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=rFiTE+bo; arc=fail smtp.client-ip=40.107.200.71 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="rFiTE+bo" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=nufn0iUELMRMwviiUBKLUrnmiTdCTGeL1AF8PPDE03DrP7ALHn97NYlo04W6stOqZeWlrEkaSKycYOCtKWVYzHp5MO/WMZjGM9htlKUoYUxeXFHAlmOPtb3NzaHn1bkO8DsYNYPKzFneJal0D3oYcy3Ca4Rk9jmFPMcQpUdIShPH83aSYjkxoaBRX6nBTskNLtsodZz0JQD2JHmW2mDFqt0Oo6r4frnhNwSx0RVHkNeALD03012Sfna9I0/efrw6vdwF1wWcWc/B/fbYReVp9HJ6QGCVI+g0vFgf+thh9INCH8XxHpokehM6/VL6/V9b+uE+0ckcvsNKvcbH2sVxgA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=7qskP59LqFMsYmg73iE0T4FLX7RtlfTRagDa03N0oAg=; b=q69Owa/1H1il3XpTSSHJw4jUprS9qNfbZhW4LsLK7tIhGB9AXdMceDlLXjUCsFMgsAQXV1yySqCswPoi3EW79IA8reSr/QDl8ALMqeYARt7nGMqz4B0IeLwREY3aALScq2mV1nOVJ78ZmgI+EdLAouZmPjapSGH5uSSb9//z0MlgG/qk1MHwpphojKXIoyDTqBEP7YY2QvrDknVUWraOWX+VkO3fb4HY6H+fLbThwR/vC4odSBxzMJmrQowdkoG2PVHJK6CmpKAV8w6NbRqAnXUUb8xG/vMCPk75PcZdq3r/QAu1YONpnMNMv7HAXe0ghvvMA6jOxgXYWIR3sjEtpA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=7qskP59LqFMsYmg73iE0T4FLX7RtlfTRagDa03N0oAg=; b=rFiTE+boetpHYBawx/nCzwgAQZ3Rw+b2rKuC6059pWAt/vt9w5zyOS+N0+NUgdLKNhy3fadPY5FEOBx0rmEO4hA4Hsh4BD9ojgGL/jD7viYoc5SKe4rlI1Wwc6dYtqhcZaNzy1kmzRKQO5dUz9E0HwAUlrJWTG1reqwivItYQjA= Received: from BY3PR05CA0038.namprd05.prod.outlook.com (2603:10b6:a03:39b::13) by MN2PR12MB4391.namprd12.prod.outlook.com (2603:10b6:208:269::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.20; Tue, 23 Sep 2025 05:19:42 +0000 Received: from SJ5PEPF000001D0.namprd05.prod.outlook.com (2603:10b6:a03:39b:cafe::d9) by BY3PR05CA0038.outlook.office365.com (2603:10b6:a03:39b::13) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9160.9 via Frontend Transport; Tue, 23 Sep 2025 05:19:41 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by SJ5PEPF000001D0.mail.protection.outlook.com (10.167.242.52) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:19:41 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:19:35 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 33/35] KVM: selftests: Add cross-vCPU IPI testing for SAVIC guests Date: Tue, 23 Sep 2025 10:39:40 +0530 Message-ID: <20250923050942.206116-34-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001D0:EE_|MN2PR12MB4391:EE_ X-MS-Office365-Filtering-Correlation-Id: 607b8bfa-c744-4c95-4ba5-08ddfa60ccdc X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|376014|36860700013|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?NnxLBPqaHdz2GxIzWpmtfyJkHYLQyUWHckxTWOUbMKtg5yVd/lfoNFT8MP3L?= =?us-ascii?Q?6cAiF/zj4sD4ylM4yoV5sRPgslFR6Pk7xBfDUzmBzqjMC46hqMgORKtpBVbY?= =?us-ascii?Q?J+BR9JNybKWNDsQ5P7v3l+s0wdWlQ0dkzlRENYpoWDtTaJus9GymsMp4xdu1?= =?us-ascii?Q?FqjUC6L06qq+cxiz3qm5G841Bf0JdYCMrtLxayLF+DoqFprVW3e/F5LS5YFk?= =?us-ascii?Q?jUUkTy7ajh3Q2v5Znxrj2cmyA/D8PRfQ8RQmEndLgYYWKw6RIt5HoQRpo367?= =?us-ascii?Q?5LFyeitALnn/ZUu8/ad7yEyLyCSHt6ZV/ZeCyAYVMe/x9d9w2K9c6kvGOw0W?= =?us-ascii?Q?97lrvxzRuWgAfuJZiLLyjXlP0FU71030zyJIT266RWg3x59DGQIlrBD/1B5I?= =?us-ascii?Q?2de5D+xorulrlwE61Sq/KYYvXnoNfekY4hoRp/AltOY45PLho1RHXyYkZvoG?= =?us-ascii?Q?FlAFQiUb9LULOrFnPu85tNiAH+bKSN28AV1Mx9Vb7UAep3MWw2kobLpUKJ50?= =?us-ascii?Q?BJfuapbjZK2V7czF/PPbtz4PuTnjKWuZZDuO9fXSnsctRwnk4gu06DFAseAJ?= =?us-ascii?Q?Kn/CPVNMr3Q2bRuTK84esVu4LHEC19oZ3uXOOHwAHHSdJWqqbn3WC4MEEt78?= =?us-ascii?Q?mzHG0Co6hqK3ketvd5K5FkpMyBhamM3vFhLuwm95nOHgJ0OlvbO+uqCXyurD?= =?us-ascii?Q?B88BGviwGbIjwRJHZTZjqrHlIioP+wo2p1TtNbGyCA/11Cck0+ybbtLgX7Mu?= =?us-ascii?Q?a4TKA4YDeDg3W0q6/WxlGNG314SmcQBWh0TJKa+yadHeu0ZEezcFQUPtxWmH?= =?us-ascii?Q?RAK6f8vfJkTsgDbKncTW+Pz2yatu4m1N3HrsorvCmTv0ymp356N3Oc+5ZCAn?= =?us-ascii?Q?f1G6Dqf10Om3t/WkhOHVVyOORbLQtPQ4nytgEGrT+TWL5ECz+0MhiZMpwJ/d?= =?us-ascii?Q?ryjKopJDV0+CssJYCWF0BilmN8D8DvpuKcSQDtdFS/gqmm1e1oY0kTry+Lg2?= =?us-ascii?Q?UUfOkKdTfb6/WRMmFWC3u8nvN5WBheYlupU9ON3Oqziai6C+v0HTOo64EZHU?= =?us-ascii?Q?ott9VmlS+MNcE5VYtEMGc+cZJDtEUqxMN+kem1MnHisoqO4zBvIbSFA8P2iD?= =?us-ascii?Q?MSUDhY2j2tpuUxdKFOKLRsnz3zL+u30JqexmBE9uazv8G71jjvS5FLEcNarg?= =?us-ascii?Q?O+YxNynkmoCmkSFGb/i6mgHt6/Isol1Qx1A2xQm7I4nGIUjibMzzDFBupF9Q?= =?us-ascii?Q?zTN2aDCFZNCHAE/gSgFhqx9Qu3uf/u/fR8B3v4YKTav34CWsldAk44ndiUxR?= =?us-ascii?Q?f4oViZHjHglVPecx4qWWrxl+ZaqCDWU5jwk2uMJ6OsPM7LCJZDgFIkmsdz4u?= =?us-ascii?Q?J5fHMQawxgeSMCznalU+ypJccXuWD2RCHIJ+Qo8Tdjtw+p1pptkt1bh126Bq?= =?us-ascii?Q?hHm6IfXKhkOeT+5sb8O7AoKgBVE61KoW8WMr5x5u7sLoU8AjRNKAMSWCyzr7?= =?us-ascii?Q?r9w6Oz8efKjmWw9RmArgtGOPGM01Glns+ZL2?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(376014)(36860700013)(1800799024);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:19:41.5932 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 607b8bfa-c744-4c95-4ba5-08ddfa60ccdc X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ5PEPF000001D0.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4391 Content-Type: text/plain; charset="utf-8" Extend the savic_test to validate Inter-Processor Interrupt (IPI) delivery between vCPUs in a Secure AVIC (SAVIC) enabled guest. When a vCPU in SAVIC mode sends an IPI, the hardware triggers a #VC(INCOMPLETE_IPI) exception. The responsibility of routing and delivering the IPI to the target vCPU(s) falls to the guest's #VC handler. Exercise this guest-side emulation logic thoroughly. Extend the test to use multiple vCPUsand verify IPIs using various destination modes and shorthands, including: Fixed (physical) destination Fixed-logical destination Broadcast to all vCPUs (including self) Broadcast to all vCPUs (excluding self) This provides essential test coverage, ensuring that the SAVIC IPI emulation mechanism is robust and correct across all standard addressing modes. Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/x86/savic_test.c | 305 ++++++++++++++++++- 1 file changed, 299 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/kvm/x86/savic_test.c b/tools/testing/s= elftests/kvm/x86/savic_test.c index aa8a7244aa55..4251f3427a32 100644 --- a/tools/testing/selftests/kvm/x86/savic_test.c +++ b/tools/testing/selftests/kvm/x86/savic_test.c @@ -13,7 +13,7 @@ #include "test_util.h" #include "savic.h" =20 -#define NR_SAVIC_VCPUS 1 +#define NR_SAVIC_VCPUS 2 #define NUM_ITERATIONS 2000 =20 #define IDLE_HLT_INTR_VECTOR 0x30 @@ -22,6 +22,10 @@ #define IOAPIC_NUM_LEVEL_VECTORS 2 #define RTC_GSI 8 #define RTC_GSI_IRQ 0x85 +#define FIXED_IPI_VEC 0x31 +#define FIXED_LOGICAL_IPI_VEC 0x32 +#define BROADCAST_ALL_IPI_VEC 0x33 +#define BROADCAST_NOSELF_IPI_VEC 0x34 =20 static bool irq_received; static struct kvm_vcpu *vcpus[NR_SAVIC_VCPUS]; @@ -36,6 +40,7 @@ enum savic_test_state { SAVIC_TEST_STATE(SAVIC_IDLE_HALT), SAVIC_TEST_STATE(SAVIC_IOAPIC), SAVIC_TEST_STATE(SAVIC_IOAPIC2), + SAVIC_TEST_STATE(SAVIC_IPI), }; =20 /* Data struct shared between host main thread and vCPUs */ @@ -45,6 +50,18 @@ struct test_data_page { uint64_t ioapic_lirq1_count; uint64_t ioapic_lirq2_count; uint64_t ioapic_rtc_gsi_irq_count; + uint64_t fixed_ipi_wake_count; + uint64_t fixed_ipi_hlt_count; + uint64_t fixed_logical_ipi_hlt_count; + uint64_t fixed_logical_ipi_wake_count; + uint64_t broadcast_ipi_hlt_count; + uint64_t broadcast_ipi_wake_count; + uint64_t broadcast_noself_ipi_hlt_count; + uint64_t broadcast_noself_ipi_wake_count; + uint64_t fixed_ipi_count; + uint64_t fixed_logical_ipi_count; + uint64_t broadcast_ipi_count; + uint64_t broadcast_noself_ipi_count; }; =20 static struct test_data_page *test_data[NR_SAVIC_VCPUS]; @@ -452,6 +469,247 @@ static void guest_setup_ioapic(int id) savic_allow_vector(vec); } =20 +static void savic_fixed_ipi(bool logical) +{ + uint64_t last_wake_cnt, last_hlt_cnt; + uint64_t last_fixed_ipi_cnt; + uint64_t tsc_start; + uint64_t *fixed_ipi_p; + uint64_t *fixed_ipi_hlt_cnt_p; + uint64_t *fixed_ipi_wake_cnt_p; + int vec; + int i, j; + + for (i =3D 1; i < NR_SAVIC_VCPUS; i++) { + struct test_data_page *data =3D test_data[i]; + uint64_t dst_apic_id =3D i; + + if (logical) { + fixed_ipi_p =3D &data->fixed_logical_ipi_count; + fixed_ipi_hlt_cnt_p =3D &data->fixed_logical_ipi_hlt_count; + fixed_ipi_wake_cnt_p =3D &data->fixed_logical_ipi_wake_count; + vec =3D FIXED_LOGICAL_IPI_VEC | APIC_DEST_LOGICAL; + dst_apic_id =3D 1 << i; + } else { + fixed_ipi_p =3D &data->fixed_ipi_count; + fixed_ipi_hlt_cnt_p =3D &data->fixed_ipi_hlt_count; + fixed_ipi_wake_cnt_p =3D &data->fixed_ipi_wake_count; + vec =3D FIXED_IPI_VEC; + dst_apic_id =3D i; + } + + last_wake_cnt =3D READ_ONCE(*fixed_ipi_wake_cnt_p); + while (!READ_ONCE(*fixed_ipi_hlt_cnt_p)) + ; + + last_hlt_cnt =3D READ_ONCE(*fixed_ipi_hlt_cnt_p); + last_fixed_ipi_cnt =3D READ_ONCE(*fixed_ipi_p); + + for (j =3D 0; j < NUM_ITERATIONS; j++) { + tsc_start =3D rdtsc(); + x2apic_write_reg(APIC_ICR, dst_apic_id << 32 | + APIC_INT_ASSERT | vec); + while (rdtsc() - tsc_start < 1000000000) { + if (READ_ONCE(*fixed_ipi_wake_cnt_p) !=3D last_wake_cnt && + READ_ONCE(*fixed_ipi_hlt_cnt_p) !=3D last_hlt_cnt && + READ_ONCE(*fixed_ipi_p) !=3D last_fixed_ipi_cnt) + break; + } + + __GUEST_ASSERT(READ_ONCE(*fixed_ipi_wake_cnt_p) !=3D last_wake_cnt && + READ_ONCE(*fixed_ipi_hlt_cnt_p) !=3D last_hlt_cnt && + READ_ONCE(*fixed_ipi_p) !=3D last_fixed_ipi_cnt, + "wakeup_cnt: %ld last_wake_cnt: %ld hlt_count: %ld last_hlt_cnt= : %ld d_ipi_count: %ld last_d_ipi_count: %ld", + READ_ONCE(*fixed_ipi_wake_cnt_p), last_wake_cnt, + READ_ONCE(*fixed_ipi_hlt_cnt_p), last_hlt_cnt, + READ_ONCE(*fixed_ipi_p), last_fixed_ipi_cnt); + + last_wake_cnt =3D READ_ONCE(*fixed_ipi_wake_cnt_p); + last_hlt_cnt =3D READ_ONCE(*fixed_ipi_hlt_cnt_p); + last_fixed_ipi_cnt =3D READ_ONCE(*fixed_ipi_p); + } + } +} + +static void savic_send_broadcast(int dsh) +{ + uint64_t last_wake_cnt[NR_SAVIC_VCPUS], last_hlt_cnt[NR_SAVIC_VCPUS]; + uint64_t last_ipi_cnt[NR_SAVIC_VCPUS]; + uint64_t tsc_start; + uint64_t *broadcast_ipi_p; + uint64_t *broadcast_ipi_hlt_cnt_p; + uint64_t *broadcast_ipi_wake_cnt_p; + struct test_data_page *data; + int i, j; + int vec; + + if (dsh =3D=3D APIC_DEST_ALLINC) + vec =3D BROADCAST_ALL_IPI_VEC; + else + vec =3D BROADCAST_NOSELF_IPI_VEC; + + for (i =3D 1; i < NR_SAVIC_VCPUS; i++) { + data =3D test_data[i]; + + if (dsh =3D=3D APIC_DEST_ALLINC) + broadcast_ipi_hlt_cnt_p =3D &data->broadcast_ipi_hlt_count; + else + broadcast_ipi_hlt_cnt_p =3D &data->broadcast_noself_ipi_hlt_count; + + while (!READ_ONCE(*broadcast_ipi_hlt_cnt_p)) + ; + } + + for (j =3D 0; j < NUM_ITERATIONS; j++) { + for (i =3D 1; i < NR_SAVIC_VCPUS; i++) { + data =3D test_data[i]; + + if (dsh =3D=3D APIC_DEST_ALLINC) { + last_hlt_cnt[i] =3D READ_ONCE(data->broadcast_ipi_hlt_count); + last_ipi_cnt[i] =3D READ_ONCE(data->broadcast_ipi_count); + last_wake_cnt[i] =3D READ_ONCE(data->broadcast_ipi_wake_count); + } else { + last_hlt_cnt[i] =3D READ_ONCE(data->broadcast_noself_ipi_hlt_count); + last_ipi_cnt[i] =3D READ_ONCE(data->broadcast_noself_ipi_count); + last_wake_cnt[i] =3D READ_ONCE(data->broadcast_noself_ipi_wake_count); + } + } + + x2apic_write_reg(APIC_ICR, APIC_INT_ASSERT | dsh | vec); + + tsc_start =3D rdtsc(); + + for (i =3D 1; i < NR_SAVIC_VCPUS; i++) { + data =3D test_data[i]; + + if (dsh =3D=3D APIC_DEST_ALLINC) { + broadcast_ipi_p =3D &data->broadcast_ipi_count; + broadcast_ipi_hlt_cnt_p =3D &data->broadcast_ipi_hlt_count; + broadcast_ipi_wake_cnt_p =3D &data->broadcast_ipi_wake_count; + } else { + broadcast_ipi_p =3D &data->broadcast_noself_ipi_count; + broadcast_ipi_hlt_cnt_p =3D &data->broadcast_noself_ipi_hlt_count; + broadcast_ipi_wake_cnt_p =3D &data->broadcast_noself_ipi_wake_count; + } + + while (rdtsc() - tsc_start < 1000000000) { + if (READ_ONCE(*broadcast_ipi_wake_cnt_p) !=3D last_wake_cnt[i] && + READ_ONCE(*broadcast_ipi_hlt_cnt_p) !=3D last_hlt_cnt[i] && + READ_ONCE(*broadcast_ipi_p) !=3D last_ipi_cnt[i]) + break; + } + + __GUEST_ASSERT(READ_ONCE(*broadcast_ipi_wake_cnt_p) !=3D last_wake_cnt[= i] && + READ_ONCE(*broadcast_ipi_hlt_cnt_p) !=3D last_hlt_cnt[i] && + READ_ONCE(*broadcast_ipi_p) !=3D last_ipi_cnt[i], + "wakeup_cnt: %ld last_wake_cnt: %ld hlt_count: %ld last_hlt_cnt= : %ld b_ipi_count: %ld last_b_ipi_count: %ld", + READ_ONCE(*broadcast_ipi_wake_cnt_p), last_wake_cnt[i], + READ_ONCE(*broadcast_ipi_hlt_cnt_p), last_hlt_cnt[i], + READ_ONCE(*broadcast_ipi_p), last_ipi_cnt[i]); + + last_wake_cnt[i] =3D READ_ONCE(*broadcast_ipi_wake_cnt_p); + last_hlt_cnt[i] =3D READ_ONCE(*broadcast_ipi_hlt_cnt_p); + last_ipi_cnt[i] =3D READ_ONCE(*broadcast_ipi_p); + } + } +} + +void savic_ipi(int id) +{ + savic_fixed_ipi(false); + savic_fixed_ipi(true); + + asm volatile("sti;":::"memory"); + x2apic_write_reg(APIC_TASKPRI, 0); + savic_send_broadcast(APIC_DEST_ALLINC); + savic_send_broadcast(APIC_DEST_ALLBUT); +} + +void guest_fixed_ipi_handler(struct ex_regs *regs) +{ + struct test_data_page *data =3D test_data[x2apic_read_reg(APIC_ID)]; + + WRITE_ONCE(data->fixed_ipi_count, data->fixed_ipi_count + 1); + x2apic_write_reg(APIC_EOI, 0x00); +} + +void guest_fixed_logical_ipi_handler(struct ex_regs *regs) +{ + struct test_data_page *data =3D test_data[x2apic_read_reg(APIC_ID)]; + + WRITE_ONCE(data->fixed_logical_ipi_count, data->fixed_logical_ipi_count += 1); + x2apic_write_reg(APIC_EOI, 0x00); +} + +void guest_broadcast_ipi_handler(struct ex_regs *regs) +{ + struct test_data_page *data =3D test_data[x2apic_read_reg(APIC_ID)]; + + WRITE_ONCE(data->broadcast_ipi_count, data->broadcast_ipi_count + 1); + x2apic_write_reg(APIC_EOI, 0x00); +} + +void guest_broadcast_noself_ipi_handler(struct ex_regs *regs) +{ + struct test_data_page *data =3D test_data[x2apic_read_reg(APIC_ID)]; + + WRITE_ONCE(data->broadcast_noself_ipi_count, data->broadcast_noself_ipi_c= ount + 1); + x2apic_write_reg(APIC_EOI, 0x00); +} + +static void ipi_guest_code(int id, unsigned long secondary_entry) +{ + struct test_data_page *data; + uint64_t *ipi_count_p, *hlt_count_p, *wake_count_p; + int i; + + x2apic_enable(); + id =3D x2apic_read_reg(APIC_ID); + data =3D test_data[id]; + savic_enable(); + x2apic_write_reg(APIC_TASKPRI, 0); + + uint64_t *ipi_count_types[][3] =3D { + { + &data->fixed_ipi_hlt_count, + &data->fixed_ipi_count, + &data->fixed_ipi_wake_count + }, + { + &data->fixed_logical_ipi_hlt_count, + &data->fixed_logical_ipi_count, + &data->fixed_logical_ipi_wake_count + }, + { + &data->broadcast_ipi_hlt_count, + &data->broadcast_ipi_count, + &data->broadcast_ipi_wake_count + }, + { + &data->broadcast_noself_ipi_hlt_count, + &data->broadcast_noself_ipi_count, + &data->broadcast_noself_ipi_wake_count + }, + }; + + for (i =3D 0; i < ARRAY_SIZE(ipi_count_types); i++) { + hlt_count_p =3D ipi_count_types[i][0]; + ipi_count_p =3D ipi_count_types[i][1]; + wake_count_p =3D ipi_count_types[i][2]; + + while (READ_ONCE(*ipi_count_p) !=3D NUM_ITERATIONS) { + asm volatile("cli"); + WRITE_ONCE(*hlt_count_p, *hlt_count_p + 1); + asm volatile("sti; hlt" : : : "memory"); + WRITE_ONCE(*wake_count_p, *wake_count_p + 1); + } + + WRITE_ONCE(*hlt_count_p, *hlt_count_p + 1); + } + + GUEST_DONE(); +} + static void guest_code(int id) { GUEST_ASSERT(rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SNP_SECURE_AVIC); @@ -468,6 +726,8 @@ static void guest_code(int id) SAVIC_GUEST_SYNC(SAVIC_IOAPIC, savic_ioapic); SAVIC_GUEST_SYNC(SAVIC_IOAPIC2, savic_ioapic2); =20 + SAVIC_GUEST_SYNC(SAVIC_IPI, savic_ipi); + GUEST_DONE(); } =20 @@ -536,6 +796,11 @@ static void install_exception_handlers(struct kvm_vm *= vm) vm_install_exception_handler(vm, IOAPIC_VECTOR_START + 2, ioapic_level_ir= q1_intr_handler); vm_install_exception_handler(vm, IOAPIC_VECTOR_START + 3, ioapic_level_ir= q2_intr_handler); vm_install_exception_handler(vm, RTC_GSI_IRQ, ioapic_rtc_gsi_intr_handler= ); + vm_install_exception_handler(vm, FIXED_IPI_VEC, guest_fixed_ipi_handler); + vm_install_exception_handler(vm, FIXED_LOGICAL_IPI_VEC, guest_fixed_logic= al_ipi_handler); + vm_install_exception_handler(vm, BROADCAST_ALL_IPI_VEC, guest_broadcast_i= pi_handler); + vm_install_exception_handler(vm, BROADCAST_NOSELF_IPI_VEC, + guest_broadcast_noself_ipi_handler); } =20 int main(int argc, char *argv[]) @@ -547,19 +812,28 @@ int main(int argc, char *argv[]) vm_vaddr_t test_data_page_vaddr; struct kvm_vm *vm; int i, r; + struct vm_shape shape =3D { + .mode =3D VM_MODE_DEFAULT, + .type =3D KVM_X86_SNP_VM, + }; =20 TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV_SNP)); TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SECURE_AVIC)); TEST_REQUIRE(this_cpu_has(X86_FEATURE_IDLE_HLT)); =20 - vm =3D _vm_sev_create_with_one_vcpu(KVM_X86_SNP_VM, guest_code, &vcpus[0]= , &args); + vm =3D __vm_create_with_args(shape, NR_SAVIC_VCPUS, 0, &args); + + vcpus[0] =3D vm_vcpu_add(vm, 0, guest_code); + for (i =3D 1; i < NR_SAVIC_VCPUS; ++i) + vcpus[i] =3D vm_vcpu_add(vm, i, ipi_guest_code); =20 virt_pg_map(vm, APIC_DEFAULT_GPA, APIC_DEFAULT_GPA); virt_pg_map(vm, IOAPIC_DEFAULT_GPA, IOAPIC_DEFAULT_GPA); =20 install_exception_handlers(vm); =20 - vcpu_args_set(vcpus[0], 1, vcpus[0]->id); + for (i =3D 0; i < NR_SAVIC_VCPUS; i++) + vcpu_args_set(vcpus[i], 1, vcpus[i]->id); =20 for (i =3D 0; i < NR_SAVIC_VCPUS; i++) { test_data_page_vaddr =3D vm_vaddr_alloc_page_shared(vm); @@ -572,10 +846,13 @@ int main(int argc, char *argv[]) =20 vm_sev_launch(vm, snp_default_policy(), NULL); =20 - r =3D pthread_create(&threads[0], NULL, vcpu_thread, vcpus[0]); - TEST_ASSERT(r =3D=3D 0, "pthread_create failed errno=3D%d", errno); + for (i =3D 0; i < NR_SAVIC_VCPUS; i++) { + r =3D pthread_create(&threads[i], NULL, vcpu_thread, vcpus[i]); + TEST_ASSERT(r =3D=3D 0, "pthread_create failed errno=3D%d", errno); + } =20 - pthread_join(threads[0], NULL); + for (i =3D 0; i < NR_SAVIC_VCPUS; i++) + pthread_join(threads[i], NULL); =20 for (i =3D 0; i < NR_SAVIC_VCPUS; i++) { struct test_data_page *shared_state =3D shared_data[i]; @@ -583,6 +860,22 @@ int main(int argc, char *argv[]) fprintf(stderr, "VCPU %d ioapic edge irq1 count: %ld edge irq2 count: %l= d\n", i, shared_state->ioapic_eirq1_count, shared_state->ioapic_eirq2_count= ); fprintf(stderr, "VCPU %d ioapic level irq1 count: %ld level irq2 count: = %ld\n", i, shared_state->ioapic_lirq1_count, shared_state->ioapic_lirq2_cou= nt); fprintf(stderr, "VCPU %d ioapic RTC GSI irq1 count: %ld\n", i, shared_st= ate->ioapic_rtc_gsi_irq_count); + fprintf(stderr, "vCPU %d fixed IPI counts wake: %ld hlt: %ld num-IPI: %l= d\n", + i, shared_state->fixed_ipi_wake_count, + shared_state->fixed_ipi_hlt_count, + shared_state->fixed_ipi_count); + fprintf(stderr, "vCPU %d fixed-logical IPI counts wake: %ld hlt: %ld num= -IPI: %ld\n", + i, shared_state->fixed_logical_ipi_wake_count, + shared_state->fixed_logical_ipi_hlt_count, + shared_state->fixed_logical_ipi_count); + fprintf(stderr, "vCPU %d broadcast IPI counts wake: %ld hlt: %ld num-IPI= : %ld\n", + i, shared_state->broadcast_ipi_wake_count, + shared_state->broadcast_ipi_hlt_count, + shared_state->broadcast_ipi_count); + fprintf(stderr, "vCPU %d broadcast exluding self IPI counts wake: %ld hl= t: %ld num-IPI: %ld\n", + i, shared_state->broadcast_noself_ipi_wake_count, + shared_state->broadcast_noself_ipi_hlt_count, + shared_state->broadcast_noself_ipi_count); } =20 kvm_vm_free(vm); --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from SA9PR02CU001.outbound.protection.outlook.com (mail-southcentralusazon11013030.outbound.protection.outlook.com [40.93.196.30]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E227927511F; Tue, 23 Sep 2025 05:20:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.196.30 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604807; cv=fail; b=bG1J+nFRgvNAVRT4O3NfkjxRkDQUoEXaqD4SX0SAcNVnaml6DbCjVhg4+UW+ZooV8+3yYUfUmWrdGgil/bTZne0RrH14hQYPM/cWhjwgfo2LXB6aLuZRDUIWHxrVfRHcmmUOe3RVwpfQPPfTOrWufv9pvhacSPVett49Ve5vODA= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604807; c=relaxed/simple; bh=QLvsY+EmIH0Jl3x0PR09pTyahiekPBBHLuHzFzK6Ejk=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=C8RNxxv1NC5GTgjsQW3WCwPwAtprOylZXYPYtzVLrC/HaYIyrz7+fMCMH4w0ThfT5wq7/WOtqzv8gTAgQGdtEI/OUC8kTp9BuLxp59d5XHXS4fLzAUT33q5X4+cCU41oTyeyjjHDXfWA3abAHQ5bTqfAq0CaGD3BvjgChR+wbZ0= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=JuC8y9Nc; arc=fail smtp.client-ip=40.93.196.30 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="JuC8y9Nc" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=NGToNwgbInbhnv8sULoXjWFh0NmraIrHitdOrPEH+7LiZfQd/J3327YqsZFCo/zskF5HqTfhtpc83qm3ANh1M3Z+hoPet2xKyLJu2FFs5I6LUZSP0pE847od0OAYUO9DAMiX4lpzPAwVeBzy7cfwolr+hKxeHjXKK+Hat3Sq/z362d755IwGH95QnFQPSaOin1phGzm50j4W6k1wv7jRFXQj6teM4bktja3RdhcjU0exRBRiNyduk43a7WgvTiNqVShyhcuDLXI87jVOXnU1x5HGT8/1yL2yV5ALClamSX715Vkwm+1dZFfEcvIHFPJsg0EI0ZwPLK/UP2kc57zXfQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=8gktajsV8YqjkU2pYujSNfYFg3o5Y3Jg6Juicd7/KqI=; b=RHY1q9ZeLsIBNkbga8GUcQ2en8yIgAcW9zbyVVDYqUvezyMIMaVc3djTzmDKUffohRCajzvdQt11K6BEZByMuYRVroT70Vp4FI7JUKE3EfvfAsIsD0zBseK2WrcAMC5RYZyqD61ou7lYgNa6Dsf5d2IPf0uO0PuyNCwWz1FmbnBwXgYFw6/JkNJcKwoZB6aklXL3xuuDvqhkuZrIzUD6e94sfDBgxGISVFJ7PIRDMv3mKijRF/+jFYTCWxekXvO2f4flN0HvdRmV/ZP/qz1jzgvTYdkc2P1vs2YBdQpRM4ZyMMTKa3Jk/moyDlmE/+onmpd3ip8zgNI3ovQx6k75Ow== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=8gktajsV8YqjkU2pYujSNfYFg3o5Y3Jg6Juicd7/KqI=; b=JuC8y9NcnUa8U0YuK4j5q7/ybI0IqZLzJW2U6KI112NQTZ9oNeyVSNr7JyswZbuGCxgasYmnKpRTME4YbrUQ58Q9RaupCtwfVpRKO9SJpGkrr0qEG7PfGY2iyKRGRx15fvL5cyt7BvuX+9VgwXf3tuqFzM5gedCAeaWWj/KHkrU= Received: from BY5PR16CA0014.namprd16.prod.outlook.com (2603:10b6:a03:1a0::27) by CYYPR12MB8892.namprd12.prod.outlook.com (2603:10b6:930:be::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.20; Tue, 23 Sep 2025 05:20:00 +0000 Received: from SJ5PEPF000001D7.namprd05.prod.outlook.com (2603:10b6:a03:1a0:cafe::55) by BY5PR16CA0014.outlook.office365.com (2603:10b6:a03:1a0::27) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.20 via Frontend Transport; Tue, 23 Sep 2025 05:19:59 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by SJ5PEPF000001D7.mail.protection.outlook.com (10.167.242.59) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:19:59 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:19:53 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 34/35] KVM: selftests: Add NMI test for SAVIC guests Date: Tue, 23 Sep 2025 10:39:41 +0530 Message-ID: <20250923050942.206116-35-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001D7:EE_|CYYPR12MB8892:EE_ X-MS-Office365-Filtering-Correlation-Id: c816b3f1-7a26-4a86-c3b2-08ddfa60d7a1 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|376014|82310400026|36860700013; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?0eq0MIbG1ORx7ikfPM/yAmjl37bZtBjt/uHoXbx4jX/iMOX8Y33zNoKaJaWz?= =?us-ascii?Q?s8zFFJshG2gr+M0NS7giarGJM8zojulAZGlx3B+MgKqYIke9FVihAt5OSdUc?= =?us-ascii?Q?ZzCRKlCJ11YCp2okWAsWoO0ebF9/23IAJpQtfXIuvP/KYWHtp+QLBUznflZU?= =?us-ascii?Q?OM5RMKrMP7lxlv1uC/A85Rt5jECTJrZ6/SQ4ff6Q1/sgOoYrZEWKOUR9ibZY?= =?us-ascii?Q?hk8CtoOvGU6mRaTP6qzrktudVq1JYdDO8VgH7lsllJkpFq07KlQvyTpwGTA+?= =?us-ascii?Q?H4eYfDqZMemaVUJQdyZWA7RfAEzPyFXl3EsOjnVZCobLxO4QyiOLrAyHijf5?= =?us-ascii?Q?OnOCYfvsJ6J/P3F1vuIlhclkmqO6h8uLpQtNUGNV9zPWRCg/cCpkkimOblrH?= =?us-ascii?Q?pKfk42iFfJlgxuJX1igtL0qbdmas4R9R909Zy/TekVoUWcfN2VIRIX570WWx?= =?us-ascii?Q?RJNvrcSjB45U2B3VtsEEkOeMHJ7GO7V5K0oNUPSVEriJcuw5uqynE7IlVGI5?= =?us-ascii?Q?Do/kfLUDHzIgSX3mf284kZssyT1KIy4Kv/mfilVL36y/j2j/ZPs1+VejDX9S?= =?us-ascii?Q?fbkksrwP1AGlXWiaTS/t8U14/hqeeiZZKIXfcMsTPuUvYVGY7mljjgWfc02v?= =?us-ascii?Q?7fC81v8Un15efSF4HKoSN9hM0hbf0+VdCTgE9s6pwKhOfrYsGFgKjS1nl0uQ?= =?us-ascii?Q?aPsE+StaxkuUKuvRDAK3hbq6XxEzo7sOXGPgaNdqOdBVHsxm3BA9BzyiSddy?= =?us-ascii?Q?pV5OGhSPGEEuIo7fnmY0s8XPTLp0Ovut/pBuM0uNQbZIBOrM/A5bbxMbiB+q?= =?us-ascii?Q?AJ77AXDi8OlMo2XJnidLkbfqPqvbxQz3IV4ghvdYtYKTInPeNGAO/PFDXdJ1?= =?us-ascii?Q?XUpeJuuL5HLUoqm1ei/EKog5VI2CDvkP8BbrRqL5/kT0/dds7g+GAPeKMZuh?= =?us-ascii?Q?JvvJLOEWnTi7RnnABPLm7uiKDR8F4rzX1yzp6B7VQ0rRe5Ekc63ClxwjojAY?= =?us-ascii?Q?4ynm/0A8OmNonLhfuk9qKHCBhucQQXXshTvayUJ77a1oWVx/gFbCRQbLcu+c?= =?us-ascii?Q?bnXldsMWmEPKQrCkFFNvGa/f0ZM7zkjlZXIac7IOEUdwKZYEYdrlLUyJux03?= =?us-ascii?Q?T7oLXgIhi6TPnAsae94vfQOhk4S7gzRO+VJ2ynaJhMvufpDi5+/KIXKQzXkd?= =?us-ascii?Q?tKRe9aFONFkS1xGxwBR6R/NqjQX7XKO54P4zTXInw1u7KHhZtxMeXYa5xF4t?= =?us-ascii?Q?A8SSNtqiSOSb+Nr+N8GawGTOQIRmbnMoDes4gUQZ5FF4aGMt8hdihDv655je?= =?us-ascii?Q?FdErzakx97gYMiocXQWkr1nYHbspiODZg3z3NZYSyPx9hkglQ1NXOslaI30y?= =?us-ascii?Q?4DNe6dSZ0Q6ffckVUfqiXjZg9dLSxDmPGP4nWyrXRgnp7fvvUOq+Be1PGDdT?= =?us-ascii?Q?Jy/fXGdZF526Y5rADc+zXyxIKmMJC0dQ8Kaxt0Jr02HFOqDpz4nUr9RTs7+r?= =?us-ascii?Q?q5J3CUhNI28UfjYgfS2W+CXkTxB4kkwzpgsN?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(376014)(82310400026)(36860700013);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:19:59.6643 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: c816b3f1-7a26-4a86-c3b2-08ddfa60d7a1 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ5PEPF000001D7.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CYYPR12MB8892 Content-Type: text/plain; charset="utf-8" Extend the Secure AVIC (SAVIC) selftest to validate the handling of Non-Maskable Interrupts (NMIs). In SAVIC mode, NMI delivery requires explicit coordination between the guest and the hypervisor: the guest must explicitly permit the host to inject NMIs by setting the AllowedNMI bit in the MSR_AMD64_SECURE_AVIC_CONTROL. If this bit is clear, host-injected NMIs are dropped. After handling an NMI, the guest must notify the hypervisor by issuing a VMGEXIT with a new NMI_COMPLETE exit code. This unblocks the hardware's NMI-pending state, allowing subsequent NMIs to be delivered. ICR-based NMIs : NMIs sent via the Interrupt Command Register (ICR) are handled by the guest's #VC handler, following the same INCOMPLETE_IPI exception path as regular IPIs. Add a comprehensive set of test cases to savic_test.c to validate this entire flow: * Verify that a host-injected NMI is correctly dropped when the AllowedNMI bit is clear. * Test that if a second NMI is injected while one is already pending, it is correctly blocked by the hardware and delivered only after the guest signals completion of the first NMI via the new sev_es_nmi_complete() GHCB call. * Add tests for cross-vCPU NMIs sent via the ICR, covering all destination modes (fixed-physical, fixed-logical, broadcast-all, and broadcast-excluding-self) to ensure the guest's #VC handler correctly routes them. Signed-off-by: Neeraj Upadhyay --- .../selftests/kvm/include/x86/processor.h | 5 + tools/testing/selftests/kvm/include/x86/sev.h | 1 + tools/testing/selftests/kvm/lib/x86/savic.c | 15 +- tools/testing/selftests/kvm/lib/x86/sev.c | 22 + tools/testing/selftests/kvm/x86/savic_test.c | 388 ++++++++++++++---- 5 files changed, 351 insertions(+), 80 deletions(-) diff --git a/tools/testing/selftests/kvm/include/x86/processor.h b/tools/te= sting/selftests/kvm/include/x86/processor.h index 769c6be41f1b..bdbd353fc683 100644 --- a/tools/testing/selftests/kvm/include/x86/processor.h +++ b/tools/testing/selftests/kvm/include/x86/processor.h @@ -924,6 +924,11 @@ static inline void vcpu_xcrs_set(struct kvm_vcpu *vcpu= , struct kvm_xcrs *xcrs) vcpu_ioctl(vcpu, KVM_SET_XCRS, xcrs); } =20 +static inline void vcpu_nmi(struct kvm_vcpu *vcpu) +{ + vcpu_ioctl(vcpu, KVM_NMI, NULL); +} + const struct kvm_cpuid_entry2 *get_cpuid_entry(const struct kvm_cpuid2 *cp= uid, uint32_t function, uint32_t index); const struct kvm_cpuid2 *kvm_get_supported_cpuid(void); diff --git a/tools/testing/selftests/kvm/include/x86/sev.h b/tools/testing/= selftests/kvm/include/x86/sev.h index 3a95b13fb6c0..3bcbccf771ed 100644 --- a/tools/testing/selftests/kvm/include/x86/sev.h +++ b/tools/testing/selftests/kvm/include/x86/sev.h @@ -172,4 +172,5 @@ void sev_es_vc_handler(struct ex_regs *regs); void sev_es_pv_msr_rw(uint64_t msr, uint64_t *data, bool write); void sev_es_pv_mmio_rw(uint32_t *reg_gpa, uint32_t *data, bool write); void sev_es_savic_notify_gpa(uint64_t gpa); +void sev_es_nmi_complete(void); #endif /* SELFTEST_KVM_SEV_H */ diff --git a/tools/testing/selftests/kvm/lib/x86/savic.c b/tools/testing/se= lftests/kvm/lib/x86/savic.c index c941fd3f22df..75cfb85166d8 100644 --- a/tools/testing/selftests/kvm/lib/x86/savic.c +++ b/tools/testing/selftests/kvm/lib/x86/savic.c @@ -90,13 +90,15 @@ int savic_nr_pages_required(uint64_t page_size) */ void set_savic_control_msr(struct guest_apic_page *apic_page, bool enable,= bool enable_nmi) { - uint64_t val =3D apic_page->gpa | BIT_ULL(MSR_AMD64_SECURE_AVIC_EN_BIT); + uint64_t val; =20 if (!enable) { wrmsr(MSR_AMD64_SECURE_AVIC_CONTROL, 0); return; } =20 + val =3D apic_page->gpa | BIT_ULL(MSR_AMD64_SECURE_AVIC_EN_BIT); + if (enable_nmi) val |=3D BIT_ULL(MSR_AMD64_SECURE_AVIC_ALLOWED_NMI_BIT); =20 @@ -440,15 +442,18 @@ static void savic_handle_icr_write(uint64_t icr_data) bool logical =3D icr_data & APIC_DEST_LOGICAL; bool nmi =3D (icr_data & APIC_DM_FIXED_MASK) =3D=3D APIC_DM= _NMI; uint64_t self_icr_data =3D APIC_DEST_SELF | APIC_INT_ASSERT | vector; - - if (nmi) - self_icr_data |=3D APIC_DM_NMI; + struct guest_apic_page *apic_page; =20 switch (dsh) { case APIC_DEST_ALLINC: savic_send_ipi_all_but(vector, nmi); savic_hv_write_reg(APIC_ICR, icr_data); - x2apic_write_reg(APIC_ICR, self_icr_data); + if (nmi) { + apic_page =3D &apic_page_pool->guest_apic_page[x2apic_read_reg(APIC_ID)= ]; + savic_write_reg(apic_page, SAVIC_NMI_REQ_OFFSET, 1); + } else { + x2apic_write_reg(APIC_ICR, self_icr_data); + } break; case APIC_DEST_ALLBUT: savic_send_ipi_all_but(vector, nmi); diff --git a/tools/testing/selftests/kvm/lib/x86/sev.c b/tools/testing/self= tests/kvm/lib/x86/sev.c index 840504f0243c..ad1531cd0a5a 100644 --- a/tools/testing/selftests/kvm/lib/x86/sev.c +++ b/tools/testing/selftests/kvm/lib/x86/sev.c @@ -20,6 +20,7 @@ #define SVM_VMGEXIT_MMIO_READ 0x80000001 #define SVM_VMGEXIT_MMIO_WRITE 0x80000002 #define SVM_VMGEXIT_SECURE_AVIC 0x8000001a +#define SVM_VMGEXIT_NMI_COMPLETE 0x80000003 =20 struct ghcb_entry { struct ghcb ghcb; @@ -750,3 +751,24 @@ void sev_es_savic_notify_gpa(uint64_t gpa) __GUEST_ASSERT(!ret, "Secure AVIC GPA notification failed, ret: %d", ret); ghcb_free(entry); } + +void sev_es_nmi_complete(void) +{ + struct ghcb_entry *entry; + struct ghcb *ghcb; + int ret; + + entry =3D ghcb_alloc(); + ghcb =3D &entry->ghcb; + register_ghcb_page(entry->gpa); + + ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_NMI_COMPLETE); + ghcb_set_sw_exit_info_1(ghcb, 0); + ghcb_set_sw_exit_info_2(ghcb, 0); + + do_vmg_exit(entry->gpa); + ret =3D ghcb->save.sw_exit_info_1 & 0xffffffff; + __GUEST_ASSERT(!ret, "NMI completion failed, ret: %d", ret); + + ghcb_free(entry); +} diff --git a/tools/testing/selftests/kvm/x86/savic_test.c b/tools/testing/s= elftests/kvm/x86/savic_test.c index 4251f3427a32..3efefc1e69f5 100644 --- a/tools/testing/selftests/kvm/x86/savic_test.c +++ b/tools/testing/selftests/kvm/x86/savic_test.c @@ -13,8 +13,8 @@ #include "test_util.h" #include "savic.h" =20 -#define NR_SAVIC_VCPUS 2 -#define NUM_ITERATIONS 2000 +#define NR_SAVIC_VCPUS 4 +#define NUM_ITERATIONS 1000 =20 #define IDLE_HLT_INTR_VECTOR 0x30 #define IOAPIC_VECTOR_START 0x81 @@ -41,6 +41,13 @@ enum savic_test_state { SAVIC_TEST_STATE(SAVIC_IOAPIC), SAVIC_TEST_STATE(SAVIC_IOAPIC2), SAVIC_TEST_STATE(SAVIC_IPI), + SAVIC_TEST_STATE(SAVIC_NMI), + SAVIC_TEST_STATE(SAVIC_NMI2), + SAVIC_TEST_STATE(SAVIC_NMI3), + SAVIC_TEST_STATE(SAVIC_ICR_FIXED_PHYS_NMI), + SAVIC_TEST_STATE(SAVIC_ICR_FIXED_LOGICAL_NMI), + SAVIC_TEST_STATE(SAVIC_ICR_BROADCAST_NMI), + SAVIC_TEST_STATE(SAVIC_ICR_BROADCAST_NOSELF_NMI), }; =20 /* Data struct shared between host main thread and vCPUs */ @@ -50,18 +57,32 @@ struct test_data_page { uint64_t ioapic_lirq1_count; uint64_t ioapic_lirq2_count; uint64_t ioapic_rtc_gsi_irq_count; - uint64_t fixed_ipi_wake_count; - uint64_t fixed_ipi_hlt_count; + uint64_t fixed_phys_ipi_wake_count; + uint64_t fixed_phys_ipi_hlt_count; uint64_t fixed_logical_ipi_hlt_count; uint64_t fixed_logical_ipi_wake_count; uint64_t broadcast_ipi_hlt_count; uint64_t broadcast_ipi_wake_count; uint64_t broadcast_noself_ipi_hlt_count; uint64_t broadcast_noself_ipi_wake_count; - uint64_t fixed_ipi_count; + uint64_t fixed_phys_ipi_count; uint64_t fixed_logical_ipi_count; uint64_t broadcast_ipi_count; uint64_t broadcast_noself_ipi_count; + uint64_t *nmi_count_p; + uint64_t nmi_count; + uint64_t fixed_phys_nmi_hlt_count; + uint64_t fixed_phys_nmi_wake_count; + uint64_t fixed_phys_nmi_count; + uint64_t fixed_logical_nmi_hlt_count; + uint64_t fixed_logical_nmi_wake_count; + uint64_t fixed_logical_nmi_count; + uint64_t broadcast_nmi_hlt_count; + uint64_t broadcast_nmi_wake_count; + uint64_t broadcast_nmi_count; + uint64_t broadcast_noself_nmi_hlt_count; + uint64_t broadcast_noself_nmi_wake_count; + uint64_t broadcast_noself_nmi_count; }; =20 static struct test_data_page *test_data[NR_SAVIC_VCPUS]; @@ -324,9 +345,14 @@ static void _ioapic_level_irq_handler(int vec) vec); } =20 +static inline struct test_data_page *get_test_data(void) +{ + return test_data[x2apic_read_reg(APIC_ID)]; +} + static void ioapic_level_irq1_intr_handler(struct ex_regs *regs) { - struct test_data_page *data =3D test_data[x2apic_read_reg(APIC_ID)]; + struct test_data_page *data =3D get_test_data(); int vec; =20 vec =3D IOAPIC_VECTOR_START + IOAPIC_NUM_EDGE_VECTORS; @@ -336,7 +362,7 @@ static void ioapic_level_irq1_intr_handler(struct ex_re= gs *regs) =20 static void ioapic_level_irq2_intr_handler(struct ex_regs *regs) { - struct test_data_page *data =3D test_data[x2apic_read_reg(APIC_ID)]; + struct test_data_page *data =3D get_test_data(); int vec; =20 vec =3D IOAPIC_VECTOR_START + IOAPIC_NUM_EDGE_VECTORS + 1; @@ -346,7 +372,7 @@ static void ioapic_level_irq2_intr_handler(struct ex_re= gs *regs) =20 static void ioapic_edge_irq1_intr_handler(struct ex_regs *regs) { - struct test_data_page *data =3D test_data[x2apic_read_reg(APIC_ID)]; + struct test_data_page *data =3D get_test_data(); =20 WRITE_ONCE(data->ioapic_eirq1_count, data->ioapic_eirq1_count + 1); x2apic_write_reg(APIC_EOI, 0x00); @@ -354,7 +380,7 @@ static void ioapic_edge_irq1_intr_handler(struct ex_reg= s *regs) =20 static void ioapic_edge_irq2_intr_handler(struct ex_regs *regs) { - struct test_data_page *data =3D test_data[x2apic_read_reg(APIC_ID)]; + struct test_data_page *data =3D get_test_data(); =20 WRITE_ONCE(data->ioapic_eirq2_count, data->ioapic_eirq2_count + 1); x2apic_write_reg(APIC_EOI, 0x00); @@ -362,7 +388,7 @@ static void ioapic_edge_irq2_intr_handler(struct ex_reg= s *regs) =20 static void ioapic_rtc_gsi_intr_handler(struct ex_regs *regs) { - struct test_data_page *data =3D test_data[x2apic_read_reg(APIC_ID)]; + struct test_data_page *data =3D get_test_data(); =20 WRITE_ONCE(data->ioapic_rtc_gsi_irq_count, data->ioapic_rtc_gsi_irq_count= + 1); x2apic_write_reg(APIC_EOI, 0x00); @@ -370,7 +396,7 @@ static void ioapic_rtc_gsi_intr_handler(struct ex_regs = *regs) =20 static void __savic_ioapic(int count) { - struct test_data_page *data =3D test_data[x2apic_read_reg(APIC_ID)]; + struct test_data_page *data =3D get_test_data(); int vec =3D IOAPIC_VECTOR_START; =20 __GUEST_ASSERT(READ_ONCE(data->ioapic_eirq1_count) =3D=3D count, @@ -469,10 +495,40 @@ static void guest_setup_ioapic(int id) savic_allow_vector(vec); } =20 -static void savic_fixed_ipi(bool logical) +static void set_fixed_counters( + struct test_data_page *data, + uint64_t **fixed_ipi_p, + uint64_t **fixed_ipi_hlt_cnt_p, + uint64_t **fixed_ipi_wake_cnt_p, + bool logical, bool nmi) +{ + if (logical) { + *fixed_ipi_p =3D + nmi ? &data->fixed_logical_nmi_count : + &data->fixed_logical_ipi_count; + *fixed_ipi_hlt_cnt_p =3D + nmi ? &data->fixed_logical_nmi_hlt_count : + &data->fixed_logical_ipi_hlt_count; + *fixed_ipi_wake_cnt_p =3D + nmi ? &data->fixed_logical_nmi_wake_count : + &data->fixed_logical_ipi_wake_count; + } else { + *fixed_ipi_p =3D + nmi ? &data->fixed_phys_nmi_count : + &data->fixed_phys_ipi_count; + *fixed_ipi_hlt_cnt_p =3D + nmi ? &data->fixed_phys_nmi_hlt_count : + &data->fixed_phys_ipi_hlt_count; + *fixed_ipi_wake_cnt_p =3D + nmi ? &data->fixed_phys_nmi_wake_count : + &data->fixed_phys_ipi_wake_count; + } +} + +static void savic_fixed_ipi(bool logical, bool nmi) { uint64_t last_wake_cnt, last_hlt_cnt; - uint64_t last_fixed_ipi_cnt; + uint64_t last_fixed_phys_ipi_cnt; uint64_t tsc_start; uint64_t *fixed_ipi_p; uint64_t *fixed_ipi_hlt_cnt_p; @@ -484,26 +540,26 @@ static void savic_fixed_ipi(bool logical) struct test_data_page *data =3D test_data[i]; uint64_t dst_apic_id =3D i; =20 + set_fixed_counters(data, &fixed_ipi_p, + &fixed_ipi_hlt_cnt_p, &fixed_ipi_wake_cnt_p, + logical, nmi); if (logical) { - fixed_ipi_p =3D &data->fixed_logical_ipi_count; - fixed_ipi_hlt_cnt_p =3D &data->fixed_logical_ipi_hlt_count; - fixed_ipi_wake_cnt_p =3D &data->fixed_logical_ipi_wake_count; vec =3D FIXED_LOGICAL_IPI_VEC | APIC_DEST_LOGICAL; dst_apic_id =3D 1 << i; } else { - fixed_ipi_p =3D &data->fixed_ipi_count; - fixed_ipi_hlt_cnt_p =3D &data->fixed_ipi_hlt_count; - fixed_ipi_wake_cnt_p =3D &data->fixed_ipi_wake_count; vec =3D FIXED_IPI_VEC; dst_apic_id =3D i; } =20 + if (nmi) + vec |=3D APIC_DM_NMI; + last_wake_cnt =3D READ_ONCE(*fixed_ipi_wake_cnt_p); while (!READ_ONCE(*fixed_ipi_hlt_cnt_p)) ; =20 last_hlt_cnt =3D READ_ONCE(*fixed_ipi_hlt_cnt_p); - last_fixed_ipi_cnt =3D READ_ONCE(*fixed_ipi_p); + last_fixed_phys_ipi_cnt =3D READ_ONCE(*fixed_ipi_p); =20 for (j =3D 0; j < NUM_ITERATIONS; j++) { tsc_start =3D rdtsc(); @@ -512,31 +568,73 @@ static void savic_fixed_ipi(bool logical) while (rdtsc() - tsc_start < 1000000000) { if (READ_ONCE(*fixed_ipi_wake_cnt_p) !=3D last_wake_cnt && READ_ONCE(*fixed_ipi_hlt_cnt_p) !=3D last_hlt_cnt && - READ_ONCE(*fixed_ipi_p) !=3D last_fixed_ipi_cnt) + READ_ONCE(*fixed_ipi_p) !=3D last_fixed_phys_ipi_cnt) break; } =20 __GUEST_ASSERT(READ_ONCE(*fixed_ipi_wake_cnt_p) !=3D last_wake_cnt && READ_ONCE(*fixed_ipi_hlt_cnt_p) !=3D last_hlt_cnt && - READ_ONCE(*fixed_ipi_p) !=3D last_fixed_ipi_cnt, - "wakeup_cnt: %ld last_wake_cnt: %ld hlt_count: %ld last_hlt_cnt= : %ld d_ipi_count: %ld last_d_ipi_count: %ld", + READ_ONCE(*fixed_ipi_p) !=3D last_fixed_phys_ipi_cnt, + "%s fixed-%s wake: %ld last_wake: %ld hlt: %ld last_hlt: %ld ip= i: %ld last_ipi: %ld", + nmi ? "nmi" : "ipi", + logical ? "logical" : "phys", READ_ONCE(*fixed_ipi_wake_cnt_p), last_wake_cnt, READ_ONCE(*fixed_ipi_hlt_cnt_p), last_hlt_cnt, - READ_ONCE(*fixed_ipi_p), last_fixed_ipi_cnt); + READ_ONCE(*fixed_ipi_p), last_fixed_phys_ipi_cnt); =20 last_wake_cnt =3D READ_ONCE(*fixed_ipi_wake_cnt_p); last_hlt_cnt =3D READ_ONCE(*fixed_ipi_hlt_cnt_p); - last_fixed_ipi_cnt =3D READ_ONCE(*fixed_ipi_p); + last_fixed_phys_ipi_cnt =3D READ_ONCE(*fixed_ipi_p); } } } =20 -static void savic_send_broadcast(int dsh) +static uint64_t *get_broadcast_ipi_counter(struct test_data_page *data, + int dsh, bool nmi) +{ + if (dsh =3D=3D APIC_DEST_ALLINC) + return nmi ? + &data->broadcast_nmi_count : + &data->broadcast_ipi_count; + else + return nmi ? + &data->broadcast_noself_nmi_count : + &data->broadcast_noself_ipi_count; +} + + +static uint64_t *get_broadcast_hlt_counter(struct test_data_page *data, + int dsh, bool nmi) +{ + if (dsh =3D=3D APIC_DEST_ALLINC) + return nmi ? + &data->broadcast_nmi_hlt_count : + &data->broadcast_ipi_hlt_count; + else + return nmi ? + &data->broadcast_noself_nmi_hlt_count : + &data->broadcast_noself_ipi_hlt_count; +} + +static uint64_t *get_broadcast_wake_counter(struct test_data_page *data, + int dsh, bool nmi) +{ + if (dsh =3D=3D APIC_DEST_ALLINC) + return nmi ? + &data->broadcast_nmi_wake_count : + &data->broadcast_ipi_wake_count; + else + return nmi ? + &data->broadcast_noself_nmi_wake_count : + &data->broadcast_noself_ipi_wake_count; +} + +static void savic_send_broadcast(int dsh, bool nmi) { uint64_t last_wake_cnt[NR_SAVIC_VCPUS], last_hlt_cnt[NR_SAVIC_VCPUS]; uint64_t last_ipi_cnt[NR_SAVIC_VCPUS]; uint64_t tsc_start; - uint64_t *broadcast_ipi_p; + uint64_t *broadcast_ipi_cnt_p; uint64_t *broadcast_ipi_hlt_cnt_p; uint64_t *broadcast_ipi_wake_cnt_p; struct test_data_page *data; @@ -551,10 +649,8 @@ static void savic_send_broadcast(int dsh) for (i =3D 1; i < NR_SAVIC_VCPUS; i++) { data =3D test_data[i]; =20 - if (dsh =3D=3D APIC_DEST_ALLINC) - broadcast_ipi_hlt_cnt_p =3D &data->broadcast_ipi_hlt_count; - else - broadcast_ipi_hlt_cnt_p =3D &data->broadcast_noself_ipi_hlt_count; + broadcast_ipi_hlt_cnt_p =3D get_broadcast_hlt_counter( + data, dsh, nmi); =20 while (!READ_ONCE(*broadcast_ipi_hlt_cnt_p)) ; @@ -564,17 +660,20 @@ static void savic_send_broadcast(int dsh) for (i =3D 1; i < NR_SAVIC_VCPUS; i++) { data =3D test_data[i]; =20 - if (dsh =3D=3D APIC_DEST_ALLINC) { - last_hlt_cnt[i] =3D READ_ONCE(data->broadcast_ipi_hlt_count); - last_ipi_cnt[i] =3D READ_ONCE(data->broadcast_ipi_count); - last_wake_cnt[i] =3D READ_ONCE(data->broadcast_ipi_wake_count); - } else { - last_hlt_cnt[i] =3D READ_ONCE(data->broadcast_noself_ipi_hlt_count); - last_ipi_cnt[i] =3D READ_ONCE(data->broadcast_noself_ipi_count); - last_wake_cnt[i] =3D READ_ONCE(data->broadcast_noself_ipi_wake_count); - } + broadcast_ipi_cnt_p =3D get_broadcast_ipi_counter( + data, dsh, nmi); + broadcast_ipi_hlt_cnt_p =3D get_broadcast_hlt_counter( + data, dsh, nmi); + broadcast_ipi_wake_cnt_p =3D get_broadcast_wake_counter( + data, dsh, nmi); + last_ipi_cnt[i] =3D *broadcast_ipi_cnt_p; + last_hlt_cnt[i] =3D *broadcast_ipi_hlt_cnt_p; + last_wake_cnt[i] =3D *broadcast_ipi_wake_cnt_p; } =20 + if (nmi) + vec |=3D APIC_DM_NMI; + x2apic_write_reg(APIC_ICR, APIC_INT_ASSERT | dsh | vec); =20 tsc_start =3D rdtsc(); @@ -582,60 +681,59 @@ static void savic_send_broadcast(int dsh) for (i =3D 1; i < NR_SAVIC_VCPUS; i++) { data =3D test_data[i]; =20 - if (dsh =3D=3D APIC_DEST_ALLINC) { - broadcast_ipi_p =3D &data->broadcast_ipi_count; - broadcast_ipi_hlt_cnt_p =3D &data->broadcast_ipi_hlt_count; - broadcast_ipi_wake_cnt_p =3D &data->broadcast_ipi_wake_count; - } else { - broadcast_ipi_p =3D &data->broadcast_noself_ipi_count; - broadcast_ipi_hlt_cnt_p =3D &data->broadcast_noself_ipi_hlt_count; - broadcast_ipi_wake_cnt_p =3D &data->broadcast_noself_ipi_wake_count; - } + broadcast_ipi_cnt_p =3D get_broadcast_ipi_counter( + data, dsh, nmi); + broadcast_ipi_hlt_cnt_p =3D get_broadcast_hlt_counter( + data, dsh, nmi); + broadcast_ipi_wake_cnt_p =3D get_broadcast_wake_counter( + data, dsh, nmi); =20 while (rdtsc() - tsc_start < 1000000000) { if (READ_ONCE(*broadcast_ipi_wake_cnt_p) !=3D last_wake_cnt[i] && READ_ONCE(*broadcast_ipi_hlt_cnt_p) !=3D last_hlt_cnt[i] && - READ_ONCE(*broadcast_ipi_p) !=3D last_ipi_cnt[i]) + READ_ONCE(*broadcast_ipi_cnt_p) !=3D last_ipi_cnt[i]) break; } =20 __GUEST_ASSERT(READ_ONCE(*broadcast_ipi_wake_cnt_p) !=3D last_wake_cnt[= i] && READ_ONCE(*broadcast_ipi_hlt_cnt_p) !=3D last_hlt_cnt[i] && - READ_ONCE(*broadcast_ipi_p) !=3D last_ipi_cnt[i], - "wakeup_cnt: %ld last_wake_cnt: %ld hlt_count: %ld last_hlt_cnt= : %ld b_ipi_count: %ld last_b_ipi_count: %ld", + READ_ONCE(*broadcast_ipi_cnt_p) !=3D last_ipi_cnt[i], + "%s broadcast-%s wake: %ld last_wake: %ld hlt: %ld last_hlt: %l= d ipi: %ld last_ipi: %ld", + nmi ? "nmi" : "ipi", + dsh =3D=3D APIC_DEST_ALLINC ? "all" : "excl-self", READ_ONCE(*broadcast_ipi_wake_cnt_p), last_wake_cnt[i], READ_ONCE(*broadcast_ipi_hlt_cnt_p), last_hlt_cnt[i], - READ_ONCE(*broadcast_ipi_p), last_ipi_cnt[i]); + READ_ONCE(*broadcast_ipi_cnt_p), last_ipi_cnt[i]); =20 last_wake_cnt[i] =3D READ_ONCE(*broadcast_ipi_wake_cnt_p); last_hlt_cnt[i] =3D READ_ONCE(*broadcast_ipi_hlt_cnt_p); - last_ipi_cnt[i] =3D READ_ONCE(*broadcast_ipi_p); + last_ipi_cnt[i] =3D READ_ONCE(*broadcast_ipi_cnt_p); } } } =20 void savic_ipi(int id) { - savic_fixed_ipi(false); - savic_fixed_ipi(true); + savic_fixed_ipi(false, false); + savic_fixed_ipi(true, false); =20 asm volatile("sti;":::"memory"); x2apic_write_reg(APIC_TASKPRI, 0); - savic_send_broadcast(APIC_DEST_ALLINC); - savic_send_broadcast(APIC_DEST_ALLBUT); + savic_send_broadcast(APIC_DEST_ALLINC, false); + savic_send_broadcast(APIC_DEST_ALLBUT, false); } =20 -void guest_fixed_ipi_handler(struct ex_regs *regs) +void guest_fixed_phys_ipi_handler(struct ex_regs *regs) { - struct test_data_page *data =3D test_data[x2apic_read_reg(APIC_ID)]; + struct test_data_page *data =3D get_test_data(); =20 - WRITE_ONCE(data->fixed_ipi_count, data->fixed_ipi_count + 1); + WRITE_ONCE(data->fixed_phys_ipi_count, data->fixed_phys_ipi_count + 1); x2apic_write_reg(APIC_EOI, 0x00); } =20 void guest_fixed_logical_ipi_handler(struct ex_regs *regs) { - struct test_data_page *data =3D test_data[x2apic_read_reg(APIC_ID)]; + struct test_data_page *data =3D get_test_data(); =20 WRITE_ONCE(data->fixed_logical_ipi_count, data->fixed_logical_ipi_count += 1); x2apic_write_reg(APIC_EOI, 0x00); @@ -643,7 +741,7 @@ void guest_fixed_logical_ipi_handler(struct ex_regs *re= gs) =20 void guest_broadcast_ipi_handler(struct ex_regs *regs) { - struct test_data_page *data =3D test_data[x2apic_read_reg(APIC_ID)]; + struct test_data_page *data =3D get_test_data(); =20 WRITE_ONCE(data->broadcast_ipi_count, data->broadcast_ipi_count + 1); x2apic_write_reg(APIC_EOI, 0x00); @@ -651,13 +749,65 @@ void guest_broadcast_ipi_handler(struct ex_regs *regs) =20 void guest_broadcast_noself_ipi_handler(struct ex_regs *regs) { - struct test_data_page *data =3D test_data[x2apic_read_reg(APIC_ID)]; + struct test_data_page *data =3D get_test_data(); =20 WRITE_ONCE(data->broadcast_noself_ipi_count, data->broadcast_noself_ipi_c= ount + 1); x2apic_write_reg(APIC_EOI, 0x00); } =20 -static void ipi_guest_code(int id, unsigned long secondary_entry) +static void savic_nmi(int id) +{ + struct test_data_page *data =3D get_test_data(); + + __GUEST_ASSERT(!data->nmi_count, "Invalid NMI count: %ld\n", data->nmi_co= unt); + set_savic_control_msr(get_guest_apic_page(), true, true); +} + +static void savic_nmi2(int id) +{ + struct test_data_page *data =3D get_test_data(); + + __GUEST_ASSERT(data->nmi_count =3D=3D 2, "Invalid NMI count: %ld\n", data= ->nmi_count); +} + +static void savic_nmi3(int id) +{ + struct test_data_page *data =3D get_test_data(); + + __GUEST_ASSERT(data->nmi_count =3D=3D 4, "Invalid NMI count: %ld\n", data= ->nmi_count); +} + +static void savic_icr_fixed_phys(int id) +{ + savic_fixed_ipi(false, true); +} + +static void savic_icr_fixed_logical(int id) +{ + savic_fixed_ipi(true, true); +} + +static void savic_icr_bcast(int id) +{ + savic_send_broadcast(APIC_DEST_ALLINC, true); +} + +static void savic_icr_bcast_noself(int id) +{ + savic_send_broadcast(APIC_DEST_ALLBUT, true); +} + +static void guest_nmi_handler(struct ex_regs *regs) +{ + struct test_data_page *data =3D get_test_data(); + + WRITE_ONCE(*data->nmi_count_p, *data->nmi_count_p + 1); + /* Skip NMI completed notification for ICR based NMI. */ + if (data->nmi_count_p =3D=3D &data->nmi_count) + sev_es_nmi_complete(); +} + +static void ipi_guest_code(int id) { struct test_data_page *data; uint64_t *ipi_count_p, *hlt_count_p, *wake_count_p; @@ -671,9 +821,9 @@ static void ipi_guest_code(int id, unsigned long second= ary_entry) =20 uint64_t *ipi_count_types[][3] =3D { { - &data->fixed_ipi_hlt_count, - &data->fixed_ipi_count, - &data->fixed_ipi_wake_count + &data->fixed_phys_ipi_hlt_count, + &data->fixed_phys_ipi_count, + &data->fixed_phys_ipi_wake_count }, { &data->fixed_logical_ipi_hlt_count, @@ -690,6 +840,26 @@ static void ipi_guest_code(int id, unsigned long secon= dary_entry) &data->broadcast_noself_ipi_count, &data->broadcast_noself_ipi_wake_count }, + { + &data->fixed_phys_nmi_hlt_count, + &data->fixed_phys_nmi_count, + &data->fixed_phys_nmi_wake_count + }, + { + &data->fixed_logical_nmi_hlt_count, + &data->fixed_logical_nmi_count, + &data->fixed_logical_nmi_wake_count + }, + { + &data->broadcast_nmi_hlt_count, + &data->broadcast_nmi_count, + &data->broadcast_nmi_wake_count + }, + { + &data->broadcast_noself_nmi_hlt_count, + &data->broadcast_noself_nmi_count, + &data->broadcast_noself_nmi_wake_count + }, }; =20 for (i =3D 0; i < ARRAY_SIZE(ipi_count_types); i++) { @@ -698,9 +868,11 @@ static void ipi_guest_code(int id, unsigned long secon= dary_entry) wake_count_p =3D ipi_count_types[i][2]; =20 while (READ_ONCE(*ipi_count_p) !=3D NUM_ITERATIONS) { - asm volatile("cli"); + if (i < 4) + asm volatile("cli"); WRITE_ONCE(*hlt_count_p, *hlt_count_p + 1); - asm volatile("sti; hlt" : : : "memory"); + if (i < 4) + asm volatile("sti; hlt" : : : "memory"); WRITE_ONCE(*wake_count_p, *wake_count_p + 1); } =20 @@ -712,6 +884,9 @@ static void ipi_guest_code(int id, unsigned long second= ary_entry) =20 static void guest_code(int id) { + struct test_data_page *data; + int i; + GUEST_ASSERT(rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SNP_SECURE_AVIC); =20 x2apic_enable(); @@ -728,6 +903,39 @@ static void guest_code(int id) =20 SAVIC_GUEST_SYNC(SAVIC_IPI, savic_ipi); =20 + /* Disable host NMI injection in control MSR. */ + set_savic_control_msr(get_guest_apic_page(), true, false); + + data =3D test_data[id]; + data->nmi_count_p =3D &data->nmi_count; + SAVIC_GUEST_SYNC(SAVIC_NMI, savic_nmi); + SAVIC_GUEST_SYNC(SAVIC_NMI2, savic_nmi2); + SAVIC_GUEST_SYNC(SAVIC_NMI3, savic_nmi3); + + for (i =3D 0; i < NR_SAVIC_VCPUS; i++) { + data =3D test_data[i]; + data->nmi_count_p =3D &data->fixed_phys_nmi_count; + } + SAVIC_GUEST_SYNC(SAVIC_ICR_FIXED_PHYS_NMI, savic_icr_fixed_phys); + + for (i =3D 0; i < NR_SAVIC_VCPUS; i++) { + data =3D test_data[i]; + data->nmi_count_p =3D &data->fixed_logical_nmi_count; + } + SAVIC_GUEST_SYNC(SAVIC_ICR_FIXED_LOGICAL_NMI, savic_icr_fixed_logical); + + for (i =3D 0; i < NR_SAVIC_VCPUS; i++) { + data =3D test_data[i]; + data->nmi_count_p =3D &data->broadcast_nmi_count; + } + SAVIC_GUEST_SYNC(SAVIC_ICR_BROADCAST_NMI, savic_icr_bcast); + + for (i =3D 0; i < NR_SAVIC_VCPUS; i++) { + data =3D test_data[i]; + data->nmi_count_p =3D &data->broadcast_noself_nmi_count; + } + SAVIC_GUEST_SYNC(SAVIC_ICR_BROADCAST_NOSELF_NMI, savic_icr_bcast_noself); + GUEST_DONE(); } =20 @@ -745,6 +953,12 @@ static void host_send_ioapic_irq(struct kvm_vm *vm, in= t id) kvm_irq_line_status(vm, RTC_GSI, 0); } =20 +static void host_send_nmi(int id) +{ + vcpu_nmi(vcpus[id]); + vcpu_nmi(vcpus[id]); +} + static void host_test_savic(struct kvm_vm *vm, int id, enum savic_test_sta= te test_state) { switch (test_state) { @@ -754,6 +968,11 @@ static void host_test_savic(struct kvm_vm *vm, int id,= enum savic_test_state tes case SAVIC_IOAPIC2_START: host_send_ioapic_irq(vm, id); break; + case SAVIC_NMI_START: + case SAVIC_NMI2_START: + case SAVIC_NMI3_START: + host_send_nmi(id); + break; default: break; } @@ -796,11 +1015,12 @@ static void install_exception_handlers(struct kvm_vm= *vm) vm_install_exception_handler(vm, IOAPIC_VECTOR_START + 2, ioapic_level_ir= q1_intr_handler); vm_install_exception_handler(vm, IOAPIC_VECTOR_START + 3, ioapic_level_ir= q2_intr_handler); vm_install_exception_handler(vm, RTC_GSI_IRQ, ioapic_rtc_gsi_intr_handler= ); - vm_install_exception_handler(vm, FIXED_IPI_VEC, guest_fixed_ipi_handler); + vm_install_exception_handler(vm, FIXED_IPI_VEC, guest_fixed_phys_ipi_hand= ler); vm_install_exception_handler(vm, FIXED_LOGICAL_IPI_VEC, guest_fixed_logic= al_ipi_handler); vm_install_exception_handler(vm, BROADCAST_ALL_IPI_VEC, guest_broadcast_i= pi_handler); vm_install_exception_handler(vm, BROADCAST_NOSELF_IPI_VEC, guest_broadcast_noself_ipi_handler); + vm_install_exception_handler(vm, NMI_VECTOR, guest_nmi_handler); } =20 int main(int argc, char *argv[]) @@ -861,9 +1081,9 @@ int main(int argc, char *argv[]) fprintf(stderr, "VCPU %d ioapic level irq1 count: %ld level irq2 count: = %ld\n", i, shared_state->ioapic_lirq1_count, shared_state->ioapic_lirq2_cou= nt); fprintf(stderr, "VCPU %d ioapic RTC GSI irq1 count: %ld\n", i, shared_st= ate->ioapic_rtc_gsi_irq_count); fprintf(stderr, "vCPU %d fixed IPI counts wake: %ld hlt: %ld num-IPI: %l= d\n", - i, shared_state->fixed_ipi_wake_count, - shared_state->fixed_ipi_hlt_count, - shared_state->fixed_ipi_count); + i, shared_state->fixed_phys_ipi_wake_count, + shared_state->fixed_phys_ipi_hlt_count, + shared_state->fixed_phys_ipi_count); fprintf(stderr, "vCPU %d fixed-logical IPI counts wake: %ld hlt: %ld num= -IPI: %ld\n", i, shared_state->fixed_logical_ipi_wake_count, shared_state->fixed_logical_ipi_hlt_count, @@ -872,10 +1092,28 @@ int main(int argc, char *argv[]) i, shared_state->broadcast_ipi_wake_count, shared_state->broadcast_ipi_hlt_count, shared_state->broadcast_ipi_count); - fprintf(stderr, "vCPU %d broadcast exluding self IPI counts wake: %ld hl= t: %ld num-IPI: %ld\n", + fprintf(stderr, "vCPU %d broadcast excluding self IPI counts wake: %ld h= lt: %ld num-IPI: %ld\n", i, shared_state->broadcast_noself_ipi_wake_count, shared_state->broadcast_noself_ipi_hlt_count, shared_state->broadcast_noself_ipi_count); + fprintf(stderr, "vCPU %d nmi count: %ld\n", + i, shared_state->nmi_count); + fprintf(stderr, "vCPU %d nmi fixed IPI counts wake: %ld hlt: %ld num-IPI= : %ld\n", + i, shared_state->fixed_phys_nmi_wake_count, + shared_state->fixed_phys_nmi_hlt_count, + shared_state->fixed_phys_nmi_count); + fprintf(stderr, "vCPU %d nmi fixed-logical IPI counts wake: %ld hlt: %ld= num-IPI: %ld\n", + i, shared_state->fixed_logical_nmi_wake_count, + shared_state->fixed_logical_nmi_hlt_count, + shared_state->fixed_logical_nmi_count); + fprintf(stderr, "vCPU %d nmi broadcast IPI counts wake: %ld hlt: %ld num= -IPI: %ld\n", + i, shared_state->broadcast_nmi_wake_count, + shared_state->broadcast_nmi_hlt_count, + shared_state->broadcast_nmi_count); + fprintf(stderr, "vCPU %d nmi broadcast excluding self IPI counts wake: %= ld hlt: %ld num-IPI: %ld\n", + i, shared_state->broadcast_noself_nmi_wake_count, + shared_state->broadcast_noself_nmi_hlt_count, + shared_state->broadcast_noself_nmi_count); } =20 kvm_vm_free(vm); --=20 2.34.1 From nobody Tue Sep 30 18:37:56 2025 Received: from CY3PR05CU001.outbound.protection.outlook.com (mail-westcentralusazon11013010.outbound.protection.outlook.com [40.93.201.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D100626738C; Tue, 23 Sep 2025 05:20:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.201.10 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604827; cv=fail; b=eeMsEujbDL9FgdTbRWgVyEcm9iQV/pUQhq3zCMcWHH82ciVsqnBTzwsduengadg1FzlgVRYFww/XxGqliob00tfmbG66oK0n24yLk3laaQxaVdIWQHxLmEQSYyqZjYjQ6GFHrxWmBYzDUycxaVrqTsBZJJteCFKEOvDf74DgqAw= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758604827; c=relaxed/simple; bh=Nu+PwHxneVCgCYF3rgY4QV5waxKBWzc4M7v5zFQ+Foo=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=WIqZIu7TXLffr4pazkF3XTDzsTDKecLrE/cG63zq9S1RF/olwdeVOlXffycjlQ0GDRxe0/x1MwJzU//coKUSrwvnS0NSglMlVUl8FXfE4we5LWB0bb5GxDT9KYKCVk+KNG7M7B/frKRvbmM/SUWnFWlX0Y3ln8TPVcnDFQLHVJg= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=cN4XfVLh; arc=fail smtp.client-ip=40.93.201.10 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="cN4XfVLh" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=gkOuInvuiBdlF9x6A7o7fUhqPMKPN4tBMV7SmG0I+vSLOOKfPliblbLwfBvGOrtye+mfvzPh09twm9LMvwg0Xa84HVsyqvqnmxpIZYQiNHq/UigpEromvH7vLNQpnOKNGQTIEgu56cVt3ob3ugc95jlVgTy+GQ2XLLdu0q4I9Hy/ayyV9G9icWaL8B9lMV8zYgH/tmF0J5fpEILUnP9u16G0kFWA/+quFXh94tSxC23Df4vdiN6So9Lu5DxY2uMkVeaevN0iNAAPi8pqj9cpek6XsmTxtDabVxxiTTf+geTKsDLlrLsQsNul9G0m1PNpCnZZ6L97MJEXH16qmdvrWw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=1sSXaeNCv+iNNfdL5HfwJPrH00Cylwf3+emacxDv1EA=; b=oJySRaWM+DJKi66RydncfHwS/3Uflr7PlQ94zIA382TZjqRKizcuMJoj07br11geooJFkvcU6l97DduCDm0q7EBY9twq3ZcZYBdUoMhPmz+7HQAwI7hx0pDmw2Nh2qcmR6iWHBDXEU1bfGbX5m6p2ETCMbkEBknI7rnelAiCmIQVLFiWXSnrwKdqUATKTU0DLag39pcIVxLhDRTEytoyUbuw1WThExwK7HegKrOuE50fHFUnWCgpLp5I+tU6gvYjIp160uvNcJemzvNa228mrjzB6IPzipjXr/+rDQOdN5KXaOxLsz+k40tScXGf/0OeqIcqmkwyx0mR7f5oyPxOZw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=1sSXaeNCv+iNNfdL5HfwJPrH00Cylwf3+emacxDv1EA=; b=cN4XfVLhA8SqioTy2p7f5Tk+c05JsZC0Kuil3orLtZTQiSsQdmD5QafMTpf1SAL/HP3A9aimre7ODJcDWUjykHFUXnQbo92OI8nLZMxVrupCMUzYUo9jApYU5/yaqDiQrGeQQxhc2zMNefSrWDmkPuTCjCh1iCNoDcA0P/y0sJc= Received: from SJ0PR13CA0004.namprd13.prod.outlook.com (2603:10b6:a03:2c0::9) by PH8PR12MB6913.namprd12.prod.outlook.com (2603:10b6:510:1ca::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.18; Tue, 23 Sep 2025 05:20:20 +0000 Received: from SJ5PEPF000001D0.namprd05.prod.outlook.com (2603:10b6:a03:2c0:cafe::58) by SJ0PR13CA0004.outlook.office365.com (2603:10b6:a03:2c0::9) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9160.9 via Frontend Transport; Tue, 23 Sep 2025 05:20:19 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by SJ5PEPF000001D0.mail.protection.outlook.com (10.167.242.52) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Tue, 23 Sep 2025 05:20:20 +0000 Received: from BLR-L-NUPADHYA.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 22 Sep 2025 22:20:11 -0700 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , , Subject: [RFC PATCH v2 35/35] KVM: selftests: Add MSI injection test for SAVIC Date: Tue, 23 Sep 2025 10:39:42 +0530 Message-ID: <20250923050942.206116-36-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> References: <20250923050942.206116-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001D0:EE_|PH8PR12MB6913:EE_ X-MS-Office365-Filtering-Correlation-Id: ca93a262-2a2a-4bd7-39ca-08ddfa60e3ff X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|36860700013|82310400026|376014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?ajMPlGaGkPvBKgQYoPWDjJmE6zTGlBbHHZ9LkXWkBe89LBnwAsvVPJkvNY4N?= =?us-ascii?Q?amf/cFZvaNZYJIyWWnNv4sOajGnG7P0XInYKONP2T9FoCEfKPXvXMqGOSjac?= =?us-ascii?Q?KBOXrpi1drmI0WuE/nUsp2LvPXxfZRCmbaD7ZJ+lhFUl4FiwE85rysb0P3iF?= =?us-ascii?Q?bfTgC5tZZvocfccfhRacQ0LbG2qP5sD2rfFu+XmDakdruPmx7MV8vp/BM19S?= =?us-ascii?Q?pFOXoUG4wDS9SQN4+cVkm54zu/xtjF8LxcT0Wss0yZ2XtUR/JZKCzmc69hA8?= =?us-ascii?Q?VDEcgVRB9M5jgSSzeJ/yMXAxFwNp7kV7u32htFJK1vuFqVMcX5R396Vbc/Dn?= =?us-ascii?Q?BpfIL0rWgiw15bTMn+MnwrGfAjcg4gBaeZ+KG1JDGOufMhhmBGIYGTCegcGV?= =?us-ascii?Q?D228m1MOQQBjBXdGWh2xBR56za0pBCQ1lAsaC0hbEmC4CvatKa5SwVPDa+Hp?= =?us-ascii?Q?3adzIb7s5Aq4kJewp9qKTPI+1LzUQaXzUWFmYfEErZ7Mbn+F+3VKJa2jFPTy?= =?us-ascii?Q?VoKP0Ci5lT0enxlrNNR9uFRFLitHkE9AenAjs3gwUxMXCoBB7JRL+2Z4BqgC?= =?us-ascii?Q?9CFMKKC2pQWum/oGctxFL+0n/tuxV+5W379EU/zX3Ee4nSiX69J/GfI7ez/6?= =?us-ascii?Q?GcC/nZ+zvVmWbp25GVrCmRjrN+8wNQNhzltjO6rOsln+isRzKyZkJkFJTwqo?= =?us-ascii?Q?9dEl/lWgWDAbJ9Z8qUnWAySf01K8IdoyTUHcj5lDijbRQV38d8975q/RQaIR?= =?us-ascii?Q?6RkC2AJndGbkqRK4Ti1aDARvPKcjrWvyi9S6mGM3z2rPdqv95FPTAo0xtCVE?= =?us-ascii?Q?N3ozMPBJmBpjGw9DZax0LXzvG1niTSbc4lTZOIkUMJXHKL4J0tHxFgq4VNgx?= =?us-ascii?Q?sz5rcONr+oKfysOYFbYqnn47xkFCLg+yftoWzQSnQuu40u6pOjSpiUlHKd/L?= =?us-ascii?Q?i5+ShelvSFmQ8GAzSgz3VvK8hzcs1+p8eA2ua2XDoTYs60lgVr/JXsl8gr1g?= =?us-ascii?Q?lINxrV3WZFevab0JutRapAL6AuBdJSTvm6vWdNmwejN3ntVal0oHQf+WFOAu?= =?us-ascii?Q?D4lkqoIb/QAtMZMseQtUIy1wvJwhZez6ghqdN21VU3XA1nYkKcZhoaJcNUMc?= =?us-ascii?Q?Gjbs9JPKaFJRoucnn34/Ui/lgKKEKAGjOEYE3rOXDeRa7oTNeE23uhIP5Xa5?= =?us-ascii?Q?wu7xxJKXvjj0uMaHbuqd1Tj4/44ZeclCP2rmulDWEIsN8pj+yZQ+iPnWC6GS?= =?us-ascii?Q?RRbUJ6g9olWuFDSxTdwHD+L3MOAC2ORklD+ewnc7mKvz6yZ+isGlQAE6sGR4?= =?us-ascii?Q?dAvUSXdLahnY41vBdcBdf3jE+NHviEvl9eIrvBzu/fjFyId3n8Hnnjbtjto5?= =?us-ascii?Q?8PyFJ7+7sKYuxRU4xye1WfgYe0mwCkOpbK/UNk2s4WjZp+r13jyQCiTywmhg?= =?us-ascii?Q?57oldRufqcDL8PIA+1r4e5pGhKarUXTu4FW6I1T0lK/f05bthgU+SX2fcSeH?= =?us-ascii?Q?zwLcgatDXlHiBDX/E1US7a+oF/dOigEH+R9O?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(36860700013)(82310400026)(376014);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 05:20:20.4684 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: ca93a262-2a2a-4bd7-39ca-08ddfa60e3ff X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ5PEPF000001D0.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH8PR12MB6913 Content-Type: text/plain; charset="utf-8" Extend the Secure AVIC (SAVIC) selftest to validate the injection of Message-Signaled Interrupts (MSIs) from the host. In SAVIC mode, the delivery of external interrupts, including MSIs, requires explicit cooperation from the guest. For an interrupt to be successfully injected by the hardware, the guest must first grant permission by setting the corresponding vector bit in the 'ALLOWED IRR' region of its private APIC backing page. If the vector is not explicitly allowed, the hardware will drop the interrupt. Add a new test case to Secure AVIC selftest that verifies this permission model for MSIs. Verify that: 1. If the host injects an MSI while the guest has not yet allowed the vector, the interrupt is correctly dropped and not received. 2. The guest then updates the ALLOWED_IRR to permit the MSI vector. When the host injects the same MSI again, the interrupt is successfully delivered and handled. This two-stage approach provides robust validation of the SAVIC MSI delivery mechanism, ensuring both the blocking and permissive paths work as expected. Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/x86/savic_test.c | 49 ++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tools/testing/selftests/kvm/x86/savic_test.c b/tools/testing/s= elftests/kvm/x86/savic_test.c index 3efefc1e69f5..1d9861949a28 100644 --- a/tools/testing/selftests/kvm/x86/savic_test.c +++ b/tools/testing/selftests/kvm/x86/savic_test.c @@ -22,6 +22,7 @@ #define IOAPIC_NUM_LEVEL_VECTORS 2 #define RTC_GSI 8 #define RTC_GSI_IRQ 0x85 +#define MSI_VECTOR 0x40 #define FIXED_IPI_VEC 0x31 #define FIXED_LOGICAL_IPI_VEC 0x32 #define BROADCAST_ALL_IPI_VEC 0x33 @@ -40,6 +41,7 @@ enum savic_test_state { SAVIC_TEST_STATE(SAVIC_IDLE_HALT), SAVIC_TEST_STATE(SAVIC_IOAPIC), SAVIC_TEST_STATE(SAVIC_IOAPIC2), + SAVIC_TEST_STATE(SAVIC_MSI), SAVIC_TEST_STATE(SAVIC_IPI), SAVIC_TEST_STATE(SAVIC_NMI), SAVIC_TEST_STATE(SAVIC_NMI2), @@ -57,6 +59,7 @@ struct test_data_page { uint64_t ioapic_lirq1_count; uint64_t ioapic_lirq2_count; uint64_t ioapic_rtc_gsi_irq_count; + uint64_t msi_irq_count; uint64_t fixed_phys_ipi_wake_count; uint64_t fixed_phys_ipi_hlt_count; uint64_t fixed_logical_ipi_hlt_count; @@ -807,6 +810,34 @@ static void guest_nmi_handler(struct ex_regs *regs) sev_es_nmi_complete(); } =20 +static void savic_msi_not_allowed(int id) +{ + struct test_data_page *data =3D get_test_data(); + + savic_allow_vector(MSI_VECTOR); + + __GUEST_ASSERT(READ_ONCE(data->msi_irq_count) =3D=3D 0, + "Invalid MSI IRQ count: %ld, should be 0", + READ_ONCE(data->msi_irq_count)); +} + +static void savic_msi_allowed(int id) +{ + struct test_data_page *data =3D get_test_data(); + + __GUEST_ASSERT(READ_ONCE(data->msi_irq_count) =3D=3D 1, + "Invalid MSI IRQ count: %ld", + READ_ONCE(data->msi_irq_count)); +} + +static void msi_intr_handler(struct ex_regs *regs) +{ + struct test_data_page *data =3D get_test_data(); + + WRITE_ONCE(data->msi_irq_count, data->msi_irq_count + 1); + x2apic_write_reg(APIC_EOI, 0x00); +} + static void ipi_guest_code(int id) { struct test_data_page *data; @@ -901,6 +932,9 @@ static void guest_code(int id) SAVIC_GUEST_SYNC(SAVIC_IOAPIC, savic_ioapic); SAVIC_GUEST_SYNC(SAVIC_IOAPIC2, savic_ioapic2); =20 + SAVIC_GUEST_SYNC(SAVIC_MSI, savic_msi_not_allowed); + SAVIC_GUEST_SYNC(SAVIC_MSI, savic_msi_allowed); + SAVIC_GUEST_SYNC(SAVIC_IPI, savic_ipi); =20 /* Disable host NMI injection in control MSR. */ @@ -953,6 +987,17 @@ static void host_send_ioapic_irq(struct kvm_vm *vm, in= t id) kvm_irq_line_status(vm, RTC_GSI, 0); } =20 +static void host_send_msi(struct kvm_vm *vm) +{ + struct kvm_msi msi =3D { + .address_lo =3D 0, + .address_hi =3D 0, + .data =3D MSI_VECTOR, + }; + + __vm_ioctl(vm, KVM_SIGNAL_MSI, &msi); +} + static void host_send_nmi(int id) { vcpu_nmi(vcpus[id]); @@ -968,6 +1013,9 @@ static void host_test_savic(struct kvm_vm *vm, int id,= enum savic_test_state tes case SAVIC_IOAPIC2_START: host_send_ioapic_irq(vm, id); break; + case SAVIC_MSI_START: + host_send_msi(vm); + break; case SAVIC_NMI_START: case SAVIC_NMI2_START: case SAVIC_NMI3_START: @@ -1021,6 +1069,7 @@ static void install_exception_handlers(struct kvm_vm = *vm) vm_install_exception_handler(vm, BROADCAST_NOSELF_IPI_VEC, guest_broadcast_noself_ipi_handler); vm_install_exception_handler(vm, NMI_VECTOR, guest_nmi_handler); + vm_install_exception_handler(vm, MSI_VECTOR, msi_intr_handler); } =20 int main(int argc, char *argv[]) --=20 2.34.1