From patchwork Fri Feb 28 09:29:54 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13995979 Received: from NAM11-CO1-obe.outbound.protection.outlook.com (mail-co1nam11on2082.outbound.protection.outlook.com [40.107.220.82]) (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 0275C255E54; Fri, 28 Feb 2025 09:34:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.220.82 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740735253; cv=fail; b=Ocjo0nUedQd7haxfvc3Rx5I30v81P/HDqPM5d+Dvn7eWsB1qVJIX+Pshv3hC1s73HADR/yx/cF5CWXz04ZQHUB/y3v7GNrjaHp5MBaGrHdBlNZnlVCjYmLhENX+e/RmDnBGLP1Hzv+dRGrhS2fCymlLIxZyID4G08R6gwOjYWtE= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740735253; c=relaxed/simple; bh=XpAnJjgKhVW9CuPBioVE7fEw/OdvsBcHTbG60ub+YSk=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=qzZNfpou5ncWcnnc96j/UaecSB7M+2GBiKV64Vx+BR7vnoekTx+I/ZSxqv7+q4mmWGWDNg64Tme/9IyYOrvPR2pzvqIBI4Z19Vckdzw0YpXLBRhemYOQ4wX08zEcRGHd8bxanDPtBmr181Kj6W84K2dF9Ty4F/IEys2WzVLdCt0= 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=T1OuRbK7; arc=fail smtp.client-ip=40.107.220.82 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="T1OuRbK7" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=pSel9BSHlVWT0QotaIYe+N1wv3a5Tj6nZuNXMg9U/Yx+7aVBHTV5inSfEyu70OAb2Wi0cyHhy8RL9YH8Dxi370c86GEMIgXuPzUKZTfF6nMn3NRAQYr3fYhdhtbrnfPBpbL2wZeDHcM/tq4Np/CLsqE7GE/pbozA56K3M0LqxneGf0mY9tStjyR/oWG38Ohy7PzFh7dnYJGmmPP2aGvL5xCBdFRa+sGOzxIsSvFn2Tzc+HMLDYhpAnZEcDO2on6wZDAdCOACuZGgsch7VHOoZfZvI+nTF8i0WRy7LuNw1lcS2Z+ooDwuo9p/2jWpVDDKzeHf1xzfBy4qCYHmEPDKig== 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=MZVP3aZvBRW8rsS2DLI2Brk7MEZneNdCPE1hyu3aNS4=; b=pSrj2EWSD8g30zj11BzcFunJZ9iTTL/D6ag7EpzvRW0o1FMNNuamqzhGUNU8iSF1I5JceFEVS7vVC1io2rCkiXm2pvFZY70TL6aoyOvwHajUBIW7rXQhQKiABD9ZlLWwon6D9QiAmtjnx5knF9IwyGZE2hMqhImyB1DF6kaSBuqP/WXFYqjay65nTV7mKRtJWcMI9xXBnJ62ac2uBbgzeJhunrPE21+rYu98vZlA6aCkBS+WOHa38ZxKkN0cFcWj0HwPf82Cf08D7Ba0M62H0Vrt/+4QePaGwB1C6jZ+qeUf3O9JaNz3+SlcZQHFMp14iUa8e5lz8ctMriG6xlb20g== 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=MZVP3aZvBRW8rsS2DLI2Brk7MEZneNdCPE1hyu3aNS4=; b=T1OuRbK7/aH7eFnXbeJ1yG2/8+K5sFK55LAEYGgf6iAh056bEOa4RL9PavUYNpzCTFB4+T+V8Ezm16xuo2RDAupjFd6TfEz41+P+osIpWOPM26gnfqMiUuTIa8ESXgDUK4b90Wn9OcQYWyT/+4qcPkJOVMfDP1gOC9n+nf5Gqfc= Received: from MW3PR05CA0029.namprd05.prod.outlook.com (2603:10b6:303:2b::34) by SN7PR12MB6911.namprd12.prod.outlook.com (2603:10b6:806:261::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8466.20; Fri, 28 Feb 2025 09:34:08 +0000 Received: from SJ1PEPF000023CD.namprd02.prod.outlook.com (2603:10b6:303:2b:cafe::5f) by MW3PR05CA0029.outlook.office365.com (2603:10b6:303:2b::34) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8511.10 via Frontend Transport; Fri, 28 Feb 2025 09:34:08 +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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by SJ1PEPF000023CD.mail.protection.outlook.com (10.167.244.8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 09:34:07 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:31:54 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 01/31] Add GHCB with setters and getters Date: Fri, 28 Feb 2025 14:59:54 +0530 Message-ID: <20250228093024.114983-2-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF000023CD:EE_|SN7PR12MB6911:EE_ X-MS-Office365-Filtering-Correlation-Id: 8a6fbac6-6cb2-4a0e-5361-08dd57db0cd3 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700013|1800799024|82310400026|376014|7053199007; X-Microsoft-Antispam-Message-Info: a99YpjueFmuHi8ithtN2i3pNDeq29vduWb1hpClA/X32vYCm8nUYDr4C+lta2gXytNke3nMo4c+gNy3XYajgiVclbn5S8Oe6/wWC8Q9XrlTJVoEn4k9KWLw75qKfBn+oFh77X6DVPBZNS1AwN9Vxkh0zon+0yh2xhqbKC4PCqqP1ccTIDLPCV8KCQNTYYhGtPwvNJnyrLVTDnPrINRVXytPcQbz1mcPkz+JrK1aTfxEK2EQ/8w/OKkA5zXjAPEOPvdTlTG2iNSuxn+P/jvWS4dziTwdAvJHiwHK/cXI61jaDatz6CHymMwZ0m6zdmlKOEnDgZDZdWPHUmP2LI+h1gsY3/eTHpNVgXXAQMbWqacaZ9c0PWzOSDoW23+5BKzzGbsibOT1GZMqQ0B0CS9k1ilak7YR8znh0H8s5Nsr/Hp1mc0BIqCy/EYumggK9s5JzK5wxNQWvDiZ+G5l/V4CE4yV/Gp6ks3mS7T2oCCevcSSO3Ac8KeJC+apwevKIwo4Y6d0DAFINzSGGMOepGsdk9K90XLCUvlU0Jmupqzkd4rJEZCL7UAzTGUCGVPMm2SBbZwDaZGHOAYKtRPkZYm1wwG9PJuy8pYCNhGOurSd3OJ1T+0AafpnW3TI5CXCXT0zs4AXpDi8Y5L5lQWsQmTmXhLsDFMBriq3PZry8PYnGR0TmkuXxVFnircINGHiHcAL9DqXn5i3bZb3kcaUsZVKElAFoRGfpWSDMCicyr/JP+ta8rABh4h7jZLH4ce3znNnETlMO9H0QO+q1TUvf67/M/KvxSNI0T+EImaQMbv4tEXOtIrzlQbNsGvBE+AOc8oudARuaTStep5ozwaP0wqGTpxbLtmypH+XV1V8zJ25pwV4uzzYSM+EhnNq2KbzJlhJq6J3zNQw0zxJRonRY24w54D2qBlwb9I08ibLPwGwa3tGGyLfK5Oo4WeV7e/k/b6T3QRTxzXrP1X+pJVNoc3tKSZMMdcjcDlgF59ht2F66QHWbiRw5IkiQ9R086avCLkxbt/W1qtb4KJUC/ePGrVeZDOrgjW+ddzwyIdQ6/DvOshfuHjdnPYFmKVQ9dSbmHxRMS+i073lbLIEglUTCIJYJ0wvj87iqV2NisY4py6LisxyjI1ELVF4+wYj7Fhqx+5gHnoUkpMPijtjPPkhA1StnCsXXh0f5wc4a/O1Ws1ggWm349SjoIFmzz+dV7ZzSYNIWzEC1lEJMUMH+eCXJDBa1LW/7WrBVH6jjj6T59jDRLpc6HtDiPVbH/3KHWbeKMAPCP3F13Omz7qq78Ks+YnjL68rik5rjydjkVwqh+HEkb/6VAJH/ZC/mS2Sck7bY3iJifd3ZRwKpEtjP15Qs2rwPek/kfF3V1rUXkkSGYR216sg4hX9O+sjHEG0WoKeyenXtEUArl7FSV+5UIYO4g4NBOxSerYjkkIp3/ONTRoFQwEMBbkYIIvSEGT5F1Nx68ZQ5ER4fjQ1dgLUt6gjY3L+a6tBo0OWBepXGqSvk3ELsO4g= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(36860700013)(1800799024)(82310400026)(376014)(7053199007);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Feb 2025 09:34:07.9390 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 8a6fbac6-6cb2-4a0e-5361-08dd57db0cd3 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF000023CD.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR12MB6911 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/selftests/kvm/Makefile.kvm index 4277b983cace..b4894cb56861 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -226,7 +226,7 @@ LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/$(ARCH)/include CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \ -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 = 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 */ From patchwork Fri Feb 28 09:29:55 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13995980 Received: from NAM11-DM6-obe.outbound.protection.outlook.com (mail-dm6nam11on2045.outbound.protection.outlook.com [40.107.223.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 727D12566E9; Fri, 28 Feb 2025 09:35:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.223.45 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740735327; cv=fail; b=LUHpFjCwA/GSVToNEjD5QCQMh2G9BWxRNiTupoQMEOSwN3Pq3xHxFDaI1CyI6e60Fg4WQP5YR0wREqWp/DGFooO20C2A2SHp6wRibcJT6npg8G7Lukz+gIWbBkSxAp+/GRyFjHMIX4HpGwSPNwNP1VMe2+hJOpRgt5H3aXFrilw= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740735327; c=relaxed/simple; bh=mkw6Z+nGXo6t6/FyAF/ekhErovGBtEvbwSXbHXIsa3M=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=QKcLLn8TZAgTyjPIcUd3tD1rB6E/in/8kI208h/l1ZOrSBQObdQwvLNd6pF6DRSLsMVuldG9oIsWSqyirIZGAIJfrBAAcMO9LAQLyM/+++06WZwKc7LNB4aeieE/HV8nTudPuN1SWciFDxMzCTjJcOOATNb3sXpmFl+9S42RCVk= 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=P6WvydyI; arc=fail smtp.client-ip=40.107.223.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="P6WvydyI" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=qt9EOQ4wLjoY7sPY7vjkN50ChzFltOdlG1fs4+X1NP2afxUternXH755hf88PT0tek55yBaPI/LO11A4572YZdAAE+PuXQ4NKG1ecHsu/QSVIV5UuJJRXFfTIqWE3vnCdcu190BtI+Yn3ixBAsc9zoMHKw17AXV43pk8HPWWJRv1HrQMx+tVeQR7HcKzkeq293A6cIEth1wu6V1mD+y7/FONXtuv8s9hXtgJPN12nAD3k6O07jtjrrnem0r2vVAn52ruVFKZNjteuwHNd4XtMy2WQQ8WQ85KMXC3rX8zUEPjFd7W5IxVAojq4TORGG1JCMG5DtjeOLFUoTZ5OTzvbQ== 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=nfD52t+ryIKiGqrGdIY1uLkWAKDW4XSnV+R1JK8tWME=; b=cLccWcwnS7ZnmrfaI5JkgcEiGHltGeO606CAew9l79xIl9PALYWJhuhtGEsekSR1WVw37qXwuk9iXOR6uIeLVnUn3bE0wBZcAQzEu43bv7SEJ9ilnuXnjjCC29Guv2nrFuKK242ingxtCYgYPdMwTe7Cvs3BLtIdSW1qlkMa2E3UFmZDmvZEqmplo0JZzX+eMhDFNn1Xs/9qZ7KBcPFkhtn5aFb+cEUvY2YWmWcQAW1ViJF/+z8jAjf18vyN5ua/hCIjXlavxNs0PxA+YqUqIPPtikjtv0XSgWhNh5bekJLMfdbhZemhexYhRMRh+r0p32zC58m/VzIfSDy0OWCHnw== 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=nfD52t+ryIKiGqrGdIY1uLkWAKDW4XSnV+R1JK8tWME=; b=P6WvydyIyJALgwxLk/G/viqaP14qDIlQsBmY5rPqHbpZZNDKjl96zvL3FsWPOLTYDrwxUJQ3dA2GY6oeTkdcuduSfOyCKz3xr2vIso18rAhXyKQMd0FVCyPS7GA85wUhMukSnRSGVKUgYSNR3d1uJeWREaSPsuafjCu2gbAXS8A= Received: from MW4P221CA0026.NAMP221.PROD.OUTLOOK.COM (2603:10b6:303:8b::31) by BL3PR12MB6620.namprd12.prod.outlook.com (2603:10b6:208:38f::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8489.18; Fri, 28 Feb 2025 09:35:19 +0000 Received: from SJ1PEPF000023D0.namprd02.prod.outlook.com (2603:10b6:303:8b:cafe::cf) by MW4P221CA0026.outlook.office365.com (2603:10b6:303:8b::31) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.21 via Frontend Transport; Fri, 28 Feb 2025 09:35: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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by SJ1PEPF000023D0.mail.protection.outlook.com (10.167.244.4) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 09:35:18 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:33:50 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 02/31] Add arch specific additional guest pages Date: Fri, 28 Feb 2025 14:59:55 +0530 Message-ID: <20250228093024.114983-3-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF000023D0:EE_|BL3PR12MB6620:EE_ X-MS-Office365-Filtering-Correlation-Id: 7d254352-7c80-4bdd-38c8-08dd57db36d4 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: gqM3HNAWsZjohe00e36hDNOdsiL7u8GTObyC5t4sGWcho/4FEBPIYC1oGAp7EvPRljUIdRV0gEv+yh8e6Wc4FZPt30wbZuBHsqBpU7PklLSoREZTTrgaDIaCRdS2LXfeh97rqvr0wYxEqYo5L7pZY/yEVhYAnRqd70svJowteuls62RVbpZklJFHlIV9lOZlJXGW9JQ9ibZDDoWuvwEaElUNsvas9tG4yVWcrWKvOPx2IHfLYi1GWR5BMwu+vYq9Rd18xurfuqkD4wfoZ8OCEr5XnrXPc7Ap6tukLzJKXR4eVHyf6w5xFXR9fthED5JLKE6mJNC/PUqXEkyAzpeiNaDRFUOXHSu50EQ5RdlDj6HJSlnvOf+nm9ZlzUNCQGmFXrz7J9Tu/xFs5fn1QB1tGflor0UEAqGrdSRynA5JL5JQSOXcuwQfeyqxQGW9/o1BHpipQuu5gOgiTeJ50Iq7R60RhuKwtv9ViAI5TDma/8tIJsAQyokwr5U5taBhTmjA3rEHa2l4pJU1x5FlJY6O8kaUmaMlm1XjuPaNozS8wNmRcg5VobVPYdpgHII2ovz9Jzb7Mvx8gReuWP3nZzarFtUw7a7b6Gp7YL3hCGE17L1kWMXbLDVB0t2BMGgRmqHewaDd4fU0YzIziXHRz6fxRSbiIwN619cXl+VpG+kv/+Q23IoanMoZw/9ILq9SbnqBEMHZfAHCHsc62M0gmmBfd7WW9ot8X8TxOXVYRq1/ESlFQkSCdKs/pURYzsNQlZBjjGlaDB5yHl+YBD+/Uve2zmanwiAjKpkgDMenzhaMJ1p2zBtH/OZwdLFHwDvjTl/0zMyjwIffVcBiyoyCm0c8QVaXFzPoBC9mphftIU8ehoNOOpBp4NM/qIDOJl2hjohvxNlIf1NyRfoQBNbvjOhQtqLl/Lekus7+rTA0or6ulYPxAJggIIyS+0rti1ygcj+5VBjNrm2RATj2obHWMjMJo/B9A3jDA2wwOWPdss9uBXZxD8frFaWm6ta+z0WYZI2pjuZA/cc59PH1MK9kki31MKAqOdJgWIt+uUkhj9v7uQZ8UMynMhmDUxerg8P0pzhXuczWovp2dpP9AGPOjSf6LwjTQzNtrvZ/7HiqFDtIiH8OJg0txMgD1WcgCdlFq8MzQxwn3kbOL88Oi7g2VBPsXNCF8d9etUa4hT697+O7eq/lA6lEQyc6ETD7A3XmJL4BV50olI8tCKpO2zBvztqc+LGquPrcqDCSxPva7STOo+wYa89oL/DLMdk7/bIgyQPZGM7xr0oeoD4yp/jHh6BNtHq86rAlKuKv1u5wRDUn5Q79DkgJcEaPKhfuh4wi0gf6c/In3vYqcFtmN7A/D0ZC1YKMeIK08b5o/F+qbxB9qT0PxYHOyXVAPal/xW3p1Yvqls3z+fZc6QgYTp/jiKoDoVj4wpP+PGr34obvzBfqB13oYgJcuBCMYuDfMIoviETdNqUaFZDcpZhS/ipAyQHaLq+7VvdXXwBJ8VoAjSxUDwY= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.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: 28 Feb 2025 09:35:18.4248 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 7d254352-7c80-4bdd-38c8-08dd57db36d4 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF000023D0.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BL3PR12MB6620 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 4c4e5a847f67..b621a0f1907e 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -254,6 +254,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); +int kvm_arch_vm_additional_pages_required(struct vm_shape shape, + uint64_t page_size); unsigned int kvm_check_cap(long cap); static inline bool kvm_has_cap(long cap) diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index 089488e2eaf6..18a44d8220ef 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -367,11 +367,11 @@ struct kvm_vm *____vm_create(struct vm_shape shape) return vm; } -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 = vm_guest_mode_params[mode].page_size; + uint64_t page_size = vm_guest_mode_params[shape.mode].page_size; uint64_t nr_pages; TEST_ASSERT(nr_runnable_vcpus, @@ -403,13 +403,15 @@ static uint64_t vm_nr_pages_required(enum vm_guest_mode mode, /* Account for the number of pages needed by ucall. */ nr_pages += ucall_nr_pages_required(page_size); - return vm_adjust_num_guest_pages(mode, nr_pages); + nr_pages += kvm_arch_vm_additional_pages_required(shape, page_size); + + return vm_adjust_num_guest_pages(shape.mode, nr_pages); } struct kvm_vm *__vm_create(struct vm_shape shape, uint32_t nr_runnable_vcpus, uint64_t nr_extra_pages) { - uint64_t nr_pages = vm_nr_pages_required(shape.mode, nr_runnable_vcpus, + uint64_t nr_pages = vm_nr_pages_required(shape, nr_runnable_vcpus, nr_extra_pages); struct userspace_mem_region *slot0; struct kvm_vm *vm; @@ -2247,6 +2249,12 @@ __weak void kvm_arch_vm_post_create(struct kvm_vm *vm) { } +__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) { } From patchwork Fri Feb 28 09:29:56 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13995999 Received: from NAM02-BN1-obe.outbound.protection.outlook.com (mail-bn1nam02on2081.outbound.protection.outlook.com [40.107.212.81]) (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 47E312566F4; Fri, 28 Feb 2025 09:38:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.212.81 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740735483; cv=fail; b=gszxEbXFwC79uKGpzNfOug84o+VcnIyWEPZdTh3Xyh3pg6T80PQAREbGONhOFmQDiJrbdLU4EZFsnHB5Pq59QowTmMmYbDvOJ4Tjhs7WGY0hTf8w7T5YlurEtgsotMATdudn52iqN4eGDSjbl+TFbQslUUtWlCgWTw1wSFHQ2mw= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740735483; c=relaxed/simple; bh=iuXwMtuK8Qp+kBRhW2KBYwirb7fZ9EHNNjvq766Pi2k=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=iGc/u0nmw6BpX3KpjjUqHfNOzXemxFLBI6/emUvbzPgi4Vgn2T3nijggcuirI4fw2LxRIFmi2NxZUZGk2tdi5vnE05xj84RYUk2jrWpLvbT07PJ4jGz2ejf5ybb2OfmIXCMq0YErGqebcVWxwjCrWMb3uk4s8LM2mXZivPAHHmM= 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=dEMWkaJm; arc=fail smtp.client-ip=40.107.212.81 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="dEMWkaJm" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=NNZoQqrRgIpHGdrdCIViPAwb4ZpLVHo3aVDSN9s3H2s2OywMYi/FYuIxVO7WOmdwm7Gk5TgLctakJv5Esv559pxKx+zh8slze4N5iQ0Ngri0DN5yO40PH6PaohF6I6DaX12h8tVisDXUpnUTJCRyvEBWiVVkaGArvN3D40zbDF/yUi4Do/FpQK3JJjxPaUIol1zLvFg9SQmxp/Uri9slRxCcF3d1QxTAGMJcLuTKC59oyFyp5Hs74RWsX7g1M9GiSX/jCdm0QSRtCWrXqysnG7mQd/MueQPuEOS9w+IttzjVgBXFoeXIRmdItHghAjkvBlr3jO4kX5NoHAeo5I4gZQ== 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=YfBY7B+XcSZMT1vqNjMwnDAibLm7YDtm6TmfpUeX70o=; b=Xex7Mx7rvGO8En3SOVpOEuSX9heXxzfVEvjeWCtY8jqQCqMJIVxUBS+mnEjjHZOq9vWP47iW6vKdYGZXTHblvfOChhHspiC2h2MeVG9CczpqhZGG9lxw8tMCLWqW4n75Y7v6YEqIQX6FkPW3FjXCP0F1gIIZ3v4i8sIiLV9Nb0d1XBfV/ss5tUcwh6OaPSjwOdjfE/l2WpySqsDwy9ckiP+e1qnrgoW52t3TOepFxBVUNulDGuoDFLhwTHy/LlMISC56IOiABzM50j508Khs/08ITS8azP4H/EJBHPr+3g4LeEHOC8cpElLc3FBWxKyfMIVRZNnCIUPXItWh8ejkZQ== 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=YfBY7B+XcSZMT1vqNjMwnDAibLm7YDtm6TmfpUeX70o=; b=dEMWkaJmkHdVKQ2DqdJ1XJXq8gPU8gEgmFf3ZXZ5FJbIBX5oPHLLdt/cBED1P66TW0vi7IX5JtZndH34LnOTfoqtU/RDOlGnR3T9hQO0MPyabtpR67ok8wj6V/liuiOsJMN57qHFmn/ud4TLOJeQq1UL5L4qfi0cw857DrOsx5g= Received: from DM6PR11CA0006.namprd11.prod.outlook.com (2603:10b6:5:190::19) 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.8489.22; Fri, 28 Feb 2025 09:37:58 +0000 Received: from DS1PEPF00017090.namprd03.prod.outlook.com (2603:10b6:5:190:cafe::57) by DM6PR11CA0006.outlook.office365.com (2603:10b6:5:190::19) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.22 via Frontend Transport; Fri, 28 Feb 2025 09:37:58 +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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by DS1PEPF00017090.mail.protection.outlook.com (10.167.17.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 09:37:58 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:34:56 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 03/31] Add vm_vaddr_alloc_pages_shared() Date: Fri, 28 Feb 2025 14:59:56 +0530 Message-ID: <20250228093024.114983-4-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DS1PEPF00017090:EE_|MN2PR12MB4391:EE_ X-MS-Office365-Filtering-Correlation-Id: 4d937d01-71cd-4754-6d84-08dd57db961b X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|36860700013|1800799024|376014|7053199007; X-Microsoft-Antispam-Message-Info: v29dP+ojUtUMzJOMWcrfUOn08SAoekWG6hsj4zhcpLc9zjrJ8w9E+eXSFlzDre3SGkmaIimQJlDicMAfYNVl0jLfLTW3ZwE3LUa/obHsnfxkJFlm3fu4vZpDzki1/vpb6U08zY8sTrakSCQ/IGKbtMYJ5xXz/h20ssq6VOwRvWGcvBw6GOif2lyYuf/Wdg8O8veNFdOg6gXA6BjX5oi7GRKBskojV4VPyGCS6mz6hQ7b0W3seUEkzXJJ3nRwvxCgxfvkBPADZyUmAg06j08iGLQPKeTSzx3xIxbgHR3RHF66iznS+137LURvK8EMIlDo50N8Vkzy+xTiqrUidi95iT3Qmdt8/9ecUSpYimNMFtXrzdTUvBhXKuEJca9i49fmZFCmZfMlHrC0Q6Lck7FX/nerXevr0a8ksmi5fySTFfhyAAk6rzqAzyDgCy+AkYc4GySY6PNt02LU1hyVPC5QtTEsDGkFUxQyvKfgHBCZd4Hk/yXSOiai36FPflzmpvJ2IlLlLZPEEwOTQzu6x0BU4KNeAJeLK+SETQMkTY9yUtKskAm+rACYDr+MyukF1ssbpa1DAD29MBMk62kspXDmVSChdFE1LUerNYl8PBgfOW2waDeW1GC3mQOPGOK974O9EdwAdsiN9HL1DH2NW8R6V/9i1KsZUu1VfN3XMbc9r5IZZxEVbFOaHBjxc5l8GfRXSkCtOcWsGRUNWJ2YJV3LNLYyBJ50wu7MCCJujfex2RFy+XcbU6G8hqo+d4PDx6hwBDUDcJCC0bwqhXhGN/Bh4qP/t6LiRvSvvcBYws94/o8o89zhf+EeDFzwlcMjOA5wQVc0fZsTdvV/Y+KD0mhqqE0uwLMhBW/otcI8yT91HWMRcKaAjinTZ9L+Cn/ejfbSd3Wb9hVKt9hTajcSZv3oXqnKDqRnHGJEmjkR3exRCFkoJ5APHft+ac5Eu2/Elmoj60xOn19lUPhpmCDLbB6gHwx1hRlDVeaT33r8EcQmbYSLjqcqa8fCeCI8T3Zn7Fs4aV92bdQz/DBqOjWjlIggbgSMtbRAH8utEGDmj8xIOtbXep3fQAXsIAFF3ytf+t9uaTdjoDn+y2M38U194mwnLQS1Arbfg8W81TC+mWqXXmT4+tbDy2cmxH7k/8s35OTEMtMDl3fWtwH2R9YwtyFRjaGddU8Ilu7vCx4pQVB9Y9k1eNUXUZkEI63zOPMxYDbkP/NPCeCJWBVDc5zUeiViOs/O3DVWcZ5hTMxEoGT/p2o1l29e9M+j2kzrX1N0i1ivQCTu7tz7Oltxx5gVbq/hAS/aoH3obZ1Fs9GNeKMI4t4K5gwBMPP4g9HAVnyyC9MBeHe4ocMhksWdE2ANUC0tdNljf3wv/adBOxx1/DwtCYjUZMfTATswpjOsxt4BR1yTGBdid02wIHvNQva8CP/uAuUGSwhn9xryBO+4N/EE/D3TL0Xc0+7Cs7brA4A7Ael/aHbyww5QCxzIzDYoxVxx5pIil81zAgMR3I1Q6/cashk= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(36860700013)(1800799024)(376014)(7053199007);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Feb 2025 09:37:58.3375 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 4d937d01-71cd-4754-6d84-08dd57db961b 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: DS1PEPF00017090.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4391 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 b621a0f1907e..bd963ff49bf0 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -605,6 +605,7 @@ vm_vaddr_t vm_vaddr_alloc_shared(struct kvm_vm *vm, size_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/selftests/kvm/lib/kvm_util.c index 18a44d8220ef..4f3240976f6c 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -1470,6 +1470,12 @@ vm_vaddr_t vm_vaddr_alloc_pages(struct kvm_vm *vm, int nr_pages) return vm_vaddr_alloc(vm, nr_pages * getpagesize(), KVM_UTIL_MIN_VADDR); } +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_type type) { return __vm_vaddr_alloc(vm, getpagesize(), KVM_UTIL_MIN_VADDR, type); From patchwork Fri Feb 28 09:29:57 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996000 Received: from NAM12-BN8-obe.outbound.protection.outlook.com (mail-bn8nam12on2047.outbound.protection.outlook.com [40.107.237.47]) (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 F184C2586EF; Fri, 28 Feb 2025 09:38:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.237.47 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740735503; cv=fail; b=nhRUnR4ElmLF7KYVD+TvzajFyvjRXdfSUCijSXLAqAclsJ1uREHSy76TGOAnyvwRruI0hHS8V4TKxlx4j1L+Z5wAHeq3/sdJwGUyuq9udFfg/3yfP24xK81gdcL6ytRAyBXvrjfNE7yrikYt/GAOYO6T5zA+HGw9gnBgeHs6eEM= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740735503; c=relaxed/simple; bh=pLzQM4jreC0X2dOc75ntyYTKhAm+aGuQuhgqqigtUyY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=i7TYxBkNdhMm0HmGTlipId1pU2cwZz1WFU+oq6wa5Pglc65rT0tT40z5NaunYNx++ydQcwEinKgZRwbUIvDglDmc0yxw4mjAmOKusy1sIU8OOSppQ4QcbYYPMuqJjPHZz77qDolDGmtNUydLKzJlJzreMWqtGM/X/0N/qKZGYcc= 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=gnpKrWRY; arc=fail smtp.client-ip=40.107.237.47 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="gnpKrWRY" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=KNBK9RcMz/iBaF8qJbaMeYGW5ysmIydGWNmRMwUuw+gpNXJ66Zfomn2OZmcG5zlSSEHBIyBNh161zqDVOskkiGF30991OaCLcJmnBLEqHZ6fCoRpsl5Gv1TipJ6/dHXrMkyljjlJkFyWbqiTypIRsmgijwu+Slfn02fHqoEfmePbZ9abCVDRTf9cBPCnWY38wWIftSVM9WGab5+bG9jjqJuDZVXsfZeUGugh6Sxr2SQlMVj1E9WZbZS57teCnOkwnjL6GjbcefTeVYhzDWYQWtRcKw4FtQeQaBY3BoBiygj5NpNJ2XeTtPro3iRAAy/tMDbNN2WhJAPyhJQCLwFUPg== 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=ctmMtKul0Dga03a9Knk+S3EosofRdtWbdyN0YdjwB1Y=; b=CRCoxTmorKYcuXQ9zwOlopSNA9QqI2yK+8c5DytJIu86x/E4fzGq1KHzdXHxw49XDONcjXko7zjZTcn58B7XJwIaUl3v2bUrmTecWF6Qe4JSyNQFcaF1FtnAkiQnXoGDwQE32dcCkfq1eBxyoevTtoRCrpO2g/cLfgQ187p4GAPpiyJcQ5JC+9MB8XmCX6XDlcHdsKzXyG3oHDHjYCkD9yYfnIcxzOIEuwUwE6Kmz8UGE0ErmWkyLSMxzCkHxLN7ZKopDsP51LAIUQtt/CGtnjn+2lS9IZ3h6MH6kWlK+wEyn4BpG8k1O0Dbb9jUjtpit6CXlPhxL8vz1bHiRIc53g== 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=ctmMtKul0Dga03a9Knk+S3EosofRdtWbdyN0YdjwB1Y=; b=gnpKrWRYQXKotzOHbzLbdKIB3xBxlg8wHn0/xk6Ua+i54jnexeV5pvRh+aSKXn5WRKCoCFduLoObfwtyXRZxISQS/zr4nqvhFQja4RiaOJcxWEC2MQID5bRbSy1ODu8dIPm+t6g6w2XS3aTz+ulCdgRbwAM3XAF1NmLeTXaiUEg= Received: from MW4PR04CA0226.namprd04.prod.outlook.com (2603:10b6:303:87::21) by DM4PR12MB6134.namprd12.prod.outlook.com (2603:10b6:8:ad::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8489.22; Fri, 28 Feb 2025 09:38:17 +0000 Received: from SJ5PEPF000001ED.namprd05.prod.outlook.com (2603:10b6:303:87:cafe::de) by MW4PR04CA0226.outlook.office365.com (2603:10b6:303:87::21) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.21 via Frontend Transport; Fri, 28 Feb 2025 09:38:17 +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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by SJ5PEPF000001ED.mail.protection.outlook.com (10.167.242.201) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 09:38:16 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:36:10 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 04/31] Add GHCB allocations and helpers Date: Fri, 28 Feb 2025 14:59:57 +0530 Message-ID: <20250228093024.114983-5-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001ED:EE_|DM4PR12MB6134:EE_ X-MS-Office365-Filtering-Correlation-Id: f1554f4a-c9a6-45f0-f093-08dd57dba13e 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: NpuZGPHqNzFgVhvblVuaavkC3w88oN9FJDIlZZ9we+RFKm3vITXr8BVJ6tU2LtEJJ4j0zSdqkE3vpLVPs0cw5KUP9MEq1PcnvL1emqieZnhJ7SRlxm3yFO5dYIL+4JtwjbiF/xq/y0qdIRRWUWh7+jiHj5Jt+PI7TCFXo6/Eff+UsltZKzP3+67xI40Jt72uUpojQJfeEbXrANOVcYGRPEsY7J9FDecibwq06DPueEn3xYNjOdhvIjIqWky4qCczqNF/g1NapqYqF/zzTIwHbQjN2pF2YJWVhC46FSUJJIQqAt84KtHDat59wYKNl1sz0k9g+IfAPg1wzvGIQl/wQNt09/kHvorKtzhoH2MmfcyRddpT+0njk2ydd2o8HppmogS64JB3DNV7pBx82LJWI8BzOp0GE17p6PgXVy3cWmPJ9r0vYzEn0RGBdkSONKZULPeKCa4rNMOdEMjK5HGRt6oaGr8IKzjuR954VzKDwNhnLc0sEHwPdA+Tp2SNJ6p4UlLan0A9nBOz1ZG1UO/RlBeXbaok8/wGJ3zmDXpu5t3a67RwaS7Tf1dU06f2GY4kS7jZy1ovlc8H/+gWzxgDrgB9QN5LpSpY8u6Ne8Z9+oatIrlqdIK8AuWuSwgZdYQwYjZlUc7/dl1OWpxx+S5CHdYN7sIyzKPtzi3yJV1PZn59X/nQaVt8mmHJAuf/q54p0kFN3cTCovBbORc7sCk5K477quu3RqnhUUq7Gab3SWtgWVzRWGnwAhu06WZfIdNca39frBA4pLFUusvQgI7304JKpmtQTJaFPnUhaZVrrrMJfVkcySJw2+ORCOYAvzrvE67MW/9Rfez32vD04hVPmUq7tloN8BSX+TDB7j1MM7LyCD1Gqp0ZKLAF16GqXBbLPC1qPuZNvqPk4Iohd5cTeGAVmWh3PzatEQUabBkffq8sRLvk9UXyOlFCzSCfz1XNXRDl0rvgReFE8jszujyBU6/cjC0DlIA2dp70CSUZvJfYSj2jt2o5w0TeQaW2888wPMncFEXO8UctMRjIdQZ1WJS3fZjd2iN6zTDO3LE50utP26lXfMvixopqBedNqRtoml7mRywm0/IXkh6Xe5CBtDBFlcHkQfu2/qtMeuiaR5dB+eXfVEjoEkf1UyF0c6sgmOHoi0Boc2GXzigDIfSiXCfbDq96gSouk1V+Ft95KSzn1/k62KThHyH3m8VCW54W41rk+VmayRAf8E5JBKZbwht+HLS14IOtbPS6+LNyrAmEpSXB4noHhILKM/IlgqyvbCDdHYefRI0e25V40qifp7b9vRj9KeIue/YdpavrtkXho+YDlqIZ3RQOLMPktJrMAWVA3aKTr11QGDum5OZpYzQ1CkNH6WvRhNMAg5+h9ec8tPMTlAXeRDAHV8vVPmFU5nFmsN2fPF/2oXJtvj1ON7qnJxhbcabzUSy++PgEuCGr/r0FTyhhDFWp42EjGmixLJUZLr1Zce0FxPgqjLoUmJNHpJFvRcndbNj3JAhhKLg= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.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: 28 Feb 2025 09:38:16.9158 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: f1554f4a-c9a6-45f0-f093-08dd57dba13e 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ5PEPF000001ED.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM4PR12MB6134 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 | 1 + .../testing/selftests/kvm/lib/x86/processor.c | 9 +++ tools/testing/selftests/kvm/lib/x86/sev.c | 78 +++++++++++++++++++ 3 files changed, 88 insertions(+) diff --git a/tools/testing/selftests/kvm/include/x86/sev.h b/tools/testing/selftests/kvm/include/x86/sev.h index fd5d5261e10e..0b4411847cbf 100644 --- a/tools/testing/selftests/kvm/include/x86/sev.h +++ b/tools/testing/selftests/kvm/include/x86/sev.h @@ -43,6 +43,7 @@ enum sev_guest_state { bool is_sev_vm(struct kvm_vm *vm); bool is_sev_es_vm(struct kvm_vm *vm); bool is_sev_snp_vm(struct kvm_vm *vm); +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); diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testing/selftests/kvm/lib/x86/processor.c index a92dc1dad085..7129dfb652c4 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); } +int kvm_arch_vm_additional_pages_required(struct vm_shape shape, uint64_t page_size) +{ + if (shape.type == KVM_X86_SEV_ES_VM || + shape.type == 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/selftests/kvm/lib/x86/sev.c index 17d493e9907a..dd7ccf0324c5 100644 --- a/tools/testing/selftests/kvm/lib/x86/sev.c +++ b/tools/testing/selftests/kvm/lib/x86/sev.c @@ -3,6 +3,80 @@ #include #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 = vm_vaddr_alloc_shared(vm, sizeof(*hdr), KVM_UTIL_MIN_VADDR, + MEM_REGION_DATA); + hdr = (struct ghcb_header *)addr_gva2hva(vm, vaddr); + memset(hdr, 0, sizeof(*hdr)); + + for (i = 0; i < KVM_MAX_VCPUS; ++i) { + entry = &hdr->ghcbs[i]; + entry->hva = entry; + entry->gpa = (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 = 0; i < KVM_MAX_VCPUS; ++i) { + if (!test_and_set_bit(i, ghcb_pool->in_use)) { + entry = &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); +} + bool is_sev_snp_vm(struct kvm_vm *vm) { @@ -117,7 +191,11 @@ void sev_vm_launch(struct kvm_vm *vm, uint32_t policy) struct kvm_sev_guest_status status; int ctr; + 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); TEST_ASSERT_EQ(status.policy, policy); From patchwork Fri Feb 28 09:29:58 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996001 Received: from NAM11-CO1-obe.outbound.protection.outlook.com (mail-co1nam11on2054.outbound.protection.outlook.com [40.107.220.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 7AB0F2566F4; Fri, 28 Feb 2025 09:39:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.220.54 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740735546; cv=fail; b=CouoZycNhv6aq3NmRpToKB6RJ4CvyVrEFJVYYLEyEpWV4NTIiolaXWTGBRe5NdcmoP3ngy6sN1IMKet1AVIhil4cRfbwj00J4bygzaTYhgf6lbhSw4LuT9tffdNRwxuSEqAk49Z/fQsxNW/Cq2rQbu7tbh6a7WWFt8ggNv9CJbI= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740735546; c=relaxed/simple; bh=jpz7jnEhqJVgQi0b4+LeCxmRimP2f4Ybd5uGKDlld48=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=E/P8dTDSOwTPGlKql1N+vc6IbOQhfU9G6kxSc/cyFM4dkxuVjPd9K/3waH195oyD+5Ql7L0rcyzla05xwi6XF1/hnMlWB4dhVE16cJqiNKnRYC8/ME4PuxuYT1gFfCbuIxUn+KJRsOg9WSw0AxYDOMk6v8RekVF0evWRmnwLf1g= 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=jf1Sjp4o; arc=fail smtp.client-ip=40.107.220.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="jf1Sjp4o" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=UP7K9o6drAS/g5piQmOcxvIRe8YqAWRSKROihwceBZpP2gNd0htl3GuE6Zc38Kjp5JYAaqfRcitZB5o5ASj5QOUzsukKHkuD57lMl48sV5/bJaJs79MTkakCVGTFbPiFogd5PKH3NCGeXhotYNn3u0aBubFSsBGc6Ypt69TlCEDZARf+Q7TDmrhNSli/0zGe4Zbniz3XaJD5qM3QN4MmrXA4U2Vre138Qzxx3BtOzOWd2b4sMuW5UBIyN6nHdF+zCLYoNUpTm9t0pUSw1PawvWm2I2NyBLTZgoZi4PFd7r6bBkxaSExmtyaNYLAbgEoYUfL7KubyIaYr7Eci7olG3w== 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=m5zicL4dowQw8aj39dkhp6d70D8vuOsuL+DBbtzNVrQ=; b=eyw5MEBXFTCszeECOOV/HmzV/wGXhbVed8iu0uKW3c3FZeHYP5h8qS+wsg4x2JrzjrjA7GvxAiqzGhPnglRTj5psd7LS76y5VcqpBMH2xPwuzEN6OJjONpe/ejrhOMxMzg/vhLLsqF3lqowa2kH0iUixbe2fP8EtDmc0cppdYhgkMklPvaSUnCPavKlaE+CE0L9kUALII1A3blIUtUj13FnZu/44wuxxCMcEtTT3vjGXkzSVvHFGTB0rXHyRYwHkhlFZi+13Em+u89E4OAgYe+c2YuyeoqteUrPb+biajIElMHA8ghOFufiWlf74l+HFudrKw1qb1SlEyaYosHPRQw== 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=m5zicL4dowQw8aj39dkhp6d70D8vuOsuL+DBbtzNVrQ=; b=jf1Sjp4oQQCBIxDAD77tez2Fzodj+w98wspQdXmkCGVo93ejcsueHfjuYWeVKphkSgzs9xc8o0TADT7cR5ciW8hk2hjqcskF2mo1pm9pX0A2Lw+y8Qi/LTOn0nR45tSHOE87NSansWrOrb7buvf5ydtZX3amxp+Bc6L9A2l7IKY= Received: from DS7PR03CA0193.namprd03.prod.outlook.com (2603:10b6:5:3b6::18) by DS0PR12MB7772.namprd12.prod.outlook.com (2603:10b6:8:138::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8489.18; Fri, 28 Feb 2025 09:39:01 +0000 Received: from DS1PEPF00017095.namprd03.prod.outlook.com (2603:10b6:5:3b6:cafe::96) by DS7PR03CA0193.outlook.office365.com (2603:10b6:5:3b6::18) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.23 via Frontend Transport; Fri, 28 Feb 2025 09:39:00 +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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by DS1PEPF00017095.mail.protection.outlook.com (10.167.17.138) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 09:39:00 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:38:17 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 05/31] Add is_sev_enabled() helpers Date: Fri, 28 Feb 2025 14:59:58 +0530 Message-ID: <20250228093024.114983-6-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DS1PEPF00017095:EE_|DS0PR12MB7772:EE_ X-MS-Office365-Filtering-Correlation-Id: abc6d85e-90ee-429d-325c-08dd57dbbae2 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: KrWiQeSmLEBLBGYfhSTmVp6uGgXeV9POizL0JYhqvxgrg5JIgsZQZ4p2YKIjtMvLHvlo8EG7Ro/dHi2n3DkwLwkx7uQ9gvxBL1gUerAPrsOBv1GgZFDqquPNgy/4syOGWY4sfk4QYzmRAk3eugkBFua/jVrfuUTON/aEwnhftl1IOkz/Csf1aPXOxokVe1gv5YlircoK7dBzn/5mwRw2ysvRi/O1ywupvgztB3SHCdnoUqhbZiNIo40PZweueIhSXBJOH6FMDOwzgntxrSdFDIDv7ASXAo65l/zdG1xLrhlIFAmKhk3Xajv/PZlSdcJy3IKPkKaWEHUENxVsaBaXJ72rSM/sp4osJkGj45tGgfBEtBh7bGYoROT0mELay/g+77z35F2lLZlXZgjHwLyzOJ7aODmnLYX/OHifPBJfWQF+HKh4MNwMZOsdLqyCUFqYo+YHuISQgQfygCmadpKvr2iRihphH+koMf+SXaS6smM0cHwqXy3CH0AfBEY+YLXRC3vY4MQd3qwSnJbp7aKhR5bu7gHzbctMjQvfAnuWvWLpMlsCcvqgU5lpBMENi3ZsTZsvJpDckKBsQzsC30sd0N+V1igwMgXi2WSk6pLiufPcc4/m4k28EzDSRE4l2Ye0v/1gKCXGOP0iAkH+6vRs79lV5t/ddttKRiLiNQ6BtkSSgABd+xAcVwC7uK9XkrprMCsF/KXQrxU5isKJO5MO+4cRkaNOOsP6fmAordDJix64xvzjlDlb9GHXIinlPFf1OjVzZQDRvPPeWxMFo0bsZ3F1oLelP14OdcEIdRtzy1wQuRQ1iqz1z6raXN0bC3f0z09ljehe+gApIMDAlrK3SQVP5xuaSAu4jE6l9I4FtRc+vaPeuL1CiY3s69LS+7JgemKkYSssxGTedOjL4LpA0vWq8pAQ6+xqR3zogc/GiQoRmqdM0pzohzSfNkn4rfa/9DDe5lHBUo/t5qebN4IxZ8N6LrzKSryA5yoawzsQUcbp9DRg87l6bceeSXRBKClp0odpGjmismFIOZXV15kk/5bs1/93EF7wMh0X188Kx80rl5Rf2U89iL6XSLfoAjDmHsxg2UWre0Ciab1ygPoQ9sLHWA0AsjFKm01Xg82THI3SiIqXg9KEJsLSLTjssbw++N95EnOXGsrOsBi2qI5zXfd4ooRrnAUZv84I7YqnUeIy/NTaskEbILm13pP4mkjrvNCx/YLMbfhhs42ttKaUlsdKJ6qwvihACTQMH3+JAuKE1BIubWjzf8CnE6cQRfG8MKcriRVNT79zB1/0jqNeCp8UE6MunG2GuznAHfQKbZdBvA+oQdSpQYGUrrUL3MyQSiO12Pzc36Q1mU3mtlL5cQjGVTlF3i9CwxdBOWgc+EKZzPrmnrGLzA7Rdulv2vBMFkNgVoXGrZAchfYifFMbz9BgFg08EsB9sP4Jew9wU1lFKdf5lR4OiU81CoA0QGS8fn1Sg9xL0MH+4LeLTm9kvlWrBG+Mb1DOIVg0QoM6ndo= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.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: 28 Feb 2025 09:39:00.0381 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: abc6d85e-90ee-429d-325c-08dd57dbbae2 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: DS1PEPF00017095.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS0PR12MB7772 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 | 4 ++++ tools/testing/selftests/kvm/lib/x86/sev.c | 17 +++++++++++++++++ .../testing/selftests/kvm/x86/sev_smoke_test.c | 11 +++-------- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/tools/testing/selftests/kvm/include/x86/sev.h b/tools/testing/selftests/kvm/include/x86/sev.h index 0b4411847cbf..437e397ddd29 100644 --- a/tools/testing/selftests/kvm/include/x86/sev.h +++ b/tools/testing/selftests/kvm/include/x86/sev.h @@ -147,4 +147,8 @@ 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); } +bool is_sev_enabled(void); +bool is_sev_es_enabled(void); +bool is_sev_snp_enabled(void); + #endif /* SELFTEST_KVM_SEV_H */ diff --git a/tools/testing/selftests/kvm/lib/x86/sev.c b/tools/testing/selftests/kvm/lib/x86/sev.c index dd7ccf0324c5..0c542eae4184 100644 --- a/tools/testing/selftests/kvm/lib/x86/sev.c +++ b/tools/testing/selftests/kvm/lib/x86/sev.c @@ -306,3 +306,20 @@ void vm_sev_launch(struct kvm_vm *vm, uint64_t policy, uint8_t *measurement) sev_vm_launch_finish(vm); } + +bool is_sev_enabled(void) +{ + return rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SEV_ENABLED; +} + +bool is_sev_es_enabled(void) +{ + return is_sev_enabled() && + rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SEV_ES_ENABLED; +} + +bool is_sev_snp_enabled(void) +{ + return is_sev_es_enabled() && + rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SEV_SNP_ENABLED; +} diff --git a/tools/testing/selftests/kvm/x86/sev_smoke_test.c b/tools/testing/selftests/kvm/x86/sev_smoke_test.c index 4fcd0f6290ae..29382dcab18c 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 @@ static void guest_snp_code(void) { - uint64_t sev_msr = 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()); 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()); /* * 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()); GUEST_DONE(); } From patchwork Fri Feb 28 09:29:59 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996002 Received: from NAM11-CO1-obe.outbound.protection.outlook.com (mail-co1nam11on2065.outbound.protection.outlook.com [40.107.220.65]) (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 9A34C1DDC34; Fri, 28 Feb 2025 09:40:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.220.65 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740735646; cv=fail; b=NkkklMfyvFnTqPIisUb/axW7r29Y9hdGUJ8VzZiOLggUZlqOSaDmudikRDiZGukGxVKLKlY2BH1X2+M2b8vXlOPSe8i0Bb2Z6B5Hu9KsjZD/C5T/Mj5aItjKn4uLyznZxUpoiZQIqFGstp2aCY13cckFsH4Gj0EaILntJO2h6Q0= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740735646; c=relaxed/simple; bh=rD4//r3kR549+koh44xW2WmWWkHs6+2jXM1nzwv9uqM=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=q6+Afy18OYIQgnwa/VsJ83+Nnu20r/dUyrkiZo7T+H1yxo+AzpJWJqzCVn53+WTRGikS687zn4rxtAu8d/e06Z2ToT1rwS+x6iQeRTwtrlx48kknnxS0AZb6ZtOxx4QgaRLCcX5HDUuz5Dv9oQod3R4B9tnRN7TyAV5KQnGKsu4= 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=S2sJlGji; arc=fail smtp.client-ip=40.107.220.65 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="S2sJlGji" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=I1FNJDVKyI2t78ZS/d0Dj9t+VYsJzG8zfmbn4YuEPJ/U9mgkMQCI44rPHo7G1jxEvN4en/3u4rTtRCr8kJfuCqUPcS7FuSIJeo7gX+6dqrWS8k1CIALRPQjclhDl9szORAstPPThUZ+VZ4mlDXVjATStlAoiVQtujmTUaxPNOw5ATyMNr/iSMbI5dVhnCQ+liyRUiq4lIh6Ieex7omT4XyeuYksMxf2V8zykANutR2IN2Tck7qdf27Lk18UpNxLdiD5qx60QkcTjhlUDfSzAXxzJiEk3mtBWeOSty0ZcnXl2eHL3FkkG+BNemjodws/rkiSZXl42UpKdJxGqTtdIZg== 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=q+WjIGEPo/PnZY1jqhkhGZqdkRLYhgXwOVwliXRhFFM=; b=rXYJQz9uYj57FX3C4o1b2nUCafJkDxxme7c0+qiK8Q7UEe4nPJd7TIn6NmBd18y5CA/hpRvtURl31B+6gkyrYWUXYLE0zLyX9/sJiTKz6rZwc7/kAPB1ZMG6Xb7pxWtC1CDx9HB31KZpbpq7XzeQzIY9E1cZ4sIuKiff13JAL8X1nK13WD8tza1fQ7QHV2kifI3i49QjbQu54bQ7B/jekfIRjn2PmJ7SECTnbiAldHinLTAyjSPIjoRSpShEqr8McTOyO4ifRzkN8njRSZ2tZvGZViVr9nCjG+VQ0HuFVuD+U94RemOTimPfHZ0Ad4rvpBWHeAapcpBfZ6qdaLXL7A== 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=q+WjIGEPo/PnZY1jqhkhGZqdkRLYhgXwOVwliXRhFFM=; b=S2sJlGjinz84yQUl/wxfwLeeYRhjsQHOOLT7JoQPiSgej2lsxZ40keQYu+e2A7sMoaXXmNcbAPgjDYS4qyo18wOiSvPUu4pOx68qIxo9EOw/UeUoiQSiLsGVnLMpCmPRYmXLCe4qccl3bRSrcGUA1KlYsY9q4I1nQtqZ23YcieY= Received: from BYAPR05CA0071.namprd05.prod.outlook.com (2603:10b6:a03:74::48) by DS0PR12MB6533.namprd12.prod.outlook.com (2603:10b6:8:c2::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8489.18; Fri, 28 Feb 2025 09:40:39 +0000 Received: from MWH0EPF000989EB.namprd02.prod.outlook.com (2603:10b6:a03:74:cafe::15) by BYAPR05CA0071.outlook.office365.com (2603:10b6:a03:74::48) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8511.9 via Frontend Transport; Fri, 28 Feb 2025 09:40:39 +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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by MWH0EPF000989EB.mail.protection.outlook.com (10.167.241.138) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 09:40:39 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:39:23 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 06/31] Add ability for SEV-ES guests to use ucalls via GHCB Date: Fri, 28 Feb 2025 14:59:59 +0530 Message-ID: <20250228093024.114983-7-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: MWH0EPF000989EB:EE_|DS0PR12MB6533:EE_ X-MS-Office365-Filtering-Correlation-Id: ee25f1d5-5dfe-4e89-bd6b-08dd57dbf5f9 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|376014|36860700013|1800799024|7053199007; X-Microsoft-Antispam-Message-Info: 8IdC1MhoMLdhn8P0rYSuFQVkKp8EI3zvLcRz9wQ5jCf7Q60QZ8/qQSjbJTPOralAl4PVu1RDZS36rKzILA0PLRXbxA3T5y9cwnlTwMK6gW8KUecMzhMLmzTCX8XB/62HpKBsT5URm8d4oNgZ2JjdnEYPJj+4vvKzPoKhbHx8e9e93q6PcmzXdBMLg8ACx4YIqtes5jbCJChKdXW+ZIiVOMwy1SCEBjPjFhtah8U/EFXKLnGT50D4MCmiwh8FtBg7T456WFp7bEaEth4BNt6poYf+IuqQfeyvOBJRj0A/q4NRo5feKcs1K/36eIhJARnEYpUdEJrBZzMq9Lk8WKNFAe8NrvMCldg1Zz+0Cf+kBAeWUpuGPin3Z69dvmdw+kAyporHrMumhzQjhm6mBtl00MfGTlNwq+taaL8XzBZgTnZ2YDRnkew4HINdwFDF6e7voP+lPsR2ozXYN7Oj0C/1YA13MDLdHY7RODimrj0iu/XHrPRTCMBRPXBIQDj3wRybaZ3Jj4AKy0wDuHKtqVyav1wT4KIS1d6zF86SBw/Bu+DDObUYzRVRrHPwb28keF9kN2euoNCnXPj0SXo7pOl16vooCDH7RjFHADwJowwJvuvbBPi69mO8Z09hCXw58JdBIdjOcTlUlS/Jfl1fqAmkAfc4f92wqcSYKXin6VUldo0Vy1rU8+WWP8/heDAdNxvGDcTGifh1DC0RrYWRmTCSSPLb2Q1gR7TwTC/WkBpAMZBPzLDFojXpyq2QkJabBD3DNEzw0G+FRuRO9687LkgLz3g+nRt+I/15TM5adSB7Gx8QCF8MOwPKrzDhzw7q3CcgDnqoJY5ITqb/pSPms6Z/lVJ3/qVfa4FkepwotjEr+KAEJlwLIld4LEwkk7W4DzNf6CSGI0xxRmzr/lDFx3eetqkCq+eL8S32ANfmWnTG7cxYgckOhCgSWc3sN/xEnWc7NTZY0Fdzuoh6EOXvM1kNS1UFdfhmAzmFVAmSrqgJ1pVETuHW5gfaIyYbxnM2PhtySlb68MCKDgsZb4wmil5I9mCRzGlVIKtvG3TF/cBqzkBE2KyMLJIDSZs+EV+I0I6EzZ4k4EgfnfBe1YcOUYxVMblS1ciH70GDSBiaVK58e90THqV+GMsIMXTLWklOAdfMbvUl04LvcXm/wkqKTUudfkKNWuWFMt2BfvWkzmCJVNmIXVu93vhgSccMmJu8iALlLJHun1EoWxZaqypkmzDDuVz2ZZQVLbUMcycBar9bgw2EwM8bakH8ihYL2JOE/hUrtPPQ2E0QXjuOzrcOvoDJ9AwO5Z+ca23gs0OCDX8Ouabt/TT+FIUEj85ThARoIbnzWgJ1YX47+Zhqub1GOhF8/Afc+S0nxZlkm1SKLYgmF4IPpVzb/wZycsw4h8bAa76vci/01DClz+kCk3fRgjZOZMe5Q4KX/2RT3FXpBpa9mSUzMT7SdZOjbnkL8SI0YEMpQhubNvSdT7y43jDDWyNI0DczpP2wMisGoX217iDFKtY= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(376014)(36860700013)(1800799024)(7053199007);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Feb 2025 09:40:39.1780 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: ee25f1d5-5dfe-4e89-bd6b-08dd57dbf5f9 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: MWH0EPF000989EB.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS0PR12MB6533 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 437e397ddd29..bd6ab3f38679 100644 --- a/tools/testing/selftests/kvm/include/x86/sev.h +++ b/tools/testing/selftests/kvm/include/x86/sev.h @@ -151,4 +151,6 @@ bool is_sev_enabled(void); bool is_sev_es_enabled(void); bool is_sev_snp_enabled(void); +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/selftests/kvm/lib/x86/sev.c index 0c542eae4184..425ec8a3a3c7 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" +#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; /* Guest physical address of this GHCB. */ - void *gpa; + uint64_t gpa; /* 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 = align_up(sizeof(struct ghcb_header), vm_guest_mode_params[vm->mode].page_size); - vaddr = vm_vaddr_alloc_shared(vm, sizeof(*hdr), KVM_UTIL_MIN_VADDR, + vaddr = vm_vaddr_alloc_shared(vm, sz, KVM_UTIL_MIN_VADDR, MEM_REGION_DATA); hdr = (struct ghcb_header *)addr_gva2hva(vm, vaddr); - memset(hdr, 0, sizeof(*hdr)); + memset(hdr, 0, sz); for (i = 0; i < KVM_MAX_VCPUS; ++i) { entry = &hdr->ghcbs[i]; entry->hva = entry; - entry->gpa = (void *)addr_hva2gpa(vm, &entry->ghcb); + entry->gpa = (uint64_t)addr_hva2gpa(vm, &entry->ghcb); } + 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); } +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; if (!ghcb_pool) @@ -62,12 +79,18 @@ static struct ghcb_entry *ghcb_alloc(void) for (i = 0; i < KVM_MAX_VCPUS; ++i) { if (!test_and_set_bit(i, ghcb_pool->in_use)) { entry = &ghcb_pool->ghcbs[i]; - memset(&entry->ghcb, 0, sizeof(entry->ghcb)); + ghcb = &entry->ghcb; + + memset(&ghcb, 0, sizeof(*ghcb)); + ghcb->ghcb_usage = 0; + ghcb->protocol_version = 1; + return entry; } } ucall_failed: + sev_es_terminate(); return NULL; } @@ -191,9 +214,6 @@ void sev_vm_launch(struct kvm_vm *vm, uint32_t policy) struct kvm_sev_guest_status status; int ctr; - 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); @@ -285,6 +305,9 @@ struct kvm_vm *vm_sev_create_with_one_vcpu(uint32_t type, void *guest_code, void vm_sev_launch(struct kvm_vm *vm, uint64_t policy, uint8_t *measurement) { + if (is_sev_es_vm(vm)) + ghcb_init(vm); + if (is_sev_snp_vm(vm)) { vm_enable_cap(vm, KVM_CAP_EXIT_HYPERCALL, (1 << KVM_HC_MAP_GPA_RANGE)); @@ -323,3 +346,62 @@ bool is_sev_snp_enabled(void) return is_sev_es_enabled() && rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SEV_SNP_ENABLED; } + +static uint64_t setup_exitinfo1_portio(uint32_t port) +{ + uint64_t exitinfo1 = 0; + + exitinfo1 |= IOIO_TYPE_STR; + exitinfo1 |= ((port & 0xffff) << 16); + exitinfo1 |= IOIO_SEG_DS; + exitinfo1 |= IOIO_DATA_8; + exitinfo1 |= 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 = setup_exitinfo1_portio(port); + + entry = ghcb_alloc(); + ghcb = &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/selftests/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" #define UCALL_PIO_PORT ((uint16_t)0x1000) @@ -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" + 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) if (run->exit_reason == KVM_EXIT_IO && run->io.port == UCALL_PIO_PORT) { struct kvm_regs regs; + uint64_t addr; + + if (is_sev_es_vm(vcpu->vm)) { + TEST_ASSERT( + run->io.count == 8 && run->io.size == 1, + "SEV-ES ucall exit requires 8 byte string out\n"); + + addr = *(uint64_t *)((uint8_t *)(run) + run->io.data_offset); + return (void *)addr; + } 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/testing/selftests/kvm/x86/sev_smoke_test.c index 29382dcab18c..3834d3664219 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()); - wrmsr(MSR_AMD64_SEV_ES_GHCB, GHCB_MSR_TERM_REQ); - VMGEXIT(); + GUEST_DONE(); } 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()); - /* - * 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(); } static void guest_sev_code(void) @@ -102,12 +96,7 @@ static void __test_sync_vmsa(uint32_t type, uint64_t policy) vcpu_run(vcpu); - TEST_ASSERT(vcpu->run->exit_reason == 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); compare_xsave((u8 *)&xsave, (u8 *)hva); @@ -128,16 +117,6 @@ static void __test_sev(void *guest_code, uint32_t type, uint64_t policy) for (;;) { vcpu_run(vcpu); - if (is_sev_es_vm(vm)) { - TEST_ASSERT(vcpu->run->exit_reason == 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; From patchwork Fri Feb 28 09:30:00 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996025 Received: from NAM10-BN7-obe.outbound.protection.outlook.com (mail-bn7nam10on2048.outbound.protection.outlook.com [40.107.92.48]) (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 A6C6D1EBFE0; Fri, 28 Feb 2025 09:41:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.92.48 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740735702; cv=fail; b=Sc+JeiVV7dbdeQ4c1YFdLVbrsVwbXD9H1vGbrFidctT7dCHXhUlGNd/jDHAuVL6AcqeKE/Mti9B58TKqsskL1vbWcQnypwLQUMj/2Lh/tugKhQuoezfT4yrkyofVqksJvlzeHliiIRvDXaROSdlhUVCs9hlFKh0YjwqdOOFOmng= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740735702; c=relaxed/simple; bh=l1GrBEV12A92csOWVniOKLDuy79SOKz7IJYOEKyV/hU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Bn2M5VIaanKZ4Rp89/oyrVGnTWxcIjLta2p3LeJBCs10XtObAnqcXRXItkMLAa+/DGkzefAwM9gTvgQAM8S3gPRKrDCHovWa3EUZbunidlHdEvRrKTp4nmGca9J1elDBmQzTGpztSl/Gl41wUFcphMgNMZRN43qnohrl7VUFKGY= 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=JAt+m8WX; arc=fail smtp.client-ip=40.107.92.48 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="JAt+m8WX" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=OTfEp6yWN6G+Sd8jnH37TRwFE2z+bDFxuHYAFFtCGH7Vx0XdYFD2Aydiu4tTypxq0c2KSohjiEpvqmGGZZAlmul6xxeALZ8A7STOzdBEmysCPwS4nFeF12qOUr6pZ7hLAGzbmJMac4xov+0371iFspHHyLp182ITUcBY0EldITbB00yCRlYMgvVJv8ZjCU4WpozE92CXOoV/9gK6pUUelnZSbop5j8JKqevkimmd30ul7kDBzRnM1Kao+3nyS5EzfVAHOtQLgJZRWui3opvaPkf7UuHpRGQwI+tLsp4MGJBrDFlyC9S27Aw/cJk1/FGtGFb3JIlCqf5iDjg0rwlV5w== 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=QEd0SS0r4OkSqGLl0Eh5JJ+3hY+Wt1rzWTN57dvfdus=; b=eQOGQH5Tnk5vpEwRE/XEEggyFO3q6HogqrrkGvzrOWUj1Hlpam1troWbBgkRml7yRKjn64B98xaGPGZRAeaknYtj6DmbsbqhJJNj70lDRmlXv/nksBzuPiF2jUCHDt3zKh8UGU6EEScO6L69iGVK1W5D3oVks+Ad89Vo9NU5g+1PnszDUW3AASYVJU0Ok9qgo3JvwDR7Oppg9reLpgmPi2NmJbzfd8zDzdrWBrTA0g0N/wNKRVCZX6+NLXzae0eCN82A8wI6ImkmGso0TTBHnPksU9JZ3RnmMy5DXq1N7pOjwZFNDkJNc07U4kfD8t1wGCI3polvfkAgw/LGObzj1w== 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=QEd0SS0r4OkSqGLl0Eh5JJ+3hY+Wt1rzWTN57dvfdus=; b=JAt+m8WX+r1Myk1th4Eb5zWvCZSk2FxqSksxoBooprlZVmSKknwXJAEUyQbfo1epZYDCm0psHxKmiSoazsVB9A5riqogrZFq0+mX05JubD8I9SXTf5xQVyKriCTJ97VK/2BKjUIaBXSSJhb9nzzXhD+mkynKJQY59fzDXBoug4k= Received: from DM6PR06CA0080.namprd06.prod.outlook.com (2603:10b6:5:336::13) by PH7PR12MB8123.namprd12.prod.outlook.com (2603:10b6:510:2bb::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8466.20; Fri, 28 Feb 2025 09:41:35 +0000 Received: from DS1PEPF00017093.namprd03.prod.outlook.com (2603:10b6:5:336:cafe::b4) by DM6PR06CA0080.outlook.office365.com (2603:10b6:5:336::13) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.22 via Frontend Transport; Fri, 28 Feb 2025 09:41: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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by DS1PEPF00017093.mail.protection.outlook.com (10.167.17.136) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 09:41:35 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:40:38 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 07/31] KVM: selftests: Fix ghcb_entry returned in ghcb_alloc() Date: Fri, 28 Feb 2025 15:00:00 +0530 Message-ID: <20250228093024.114983-8-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DS1PEPF00017093:EE_|PH7PR12MB8123:EE_ X-MS-Office365-Filtering-Correlation-Id: 2195acca-6dad-4f26-b3ae-08dd57dc17b0 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: UeUrh0Yyh2s+i+9Z2EWhbJlLGkeOug/O/m4XG16FngI1Oe93FTRoAeKMXxzpeP7hmikz+8PJEw49BWSeI7t10H8tXPN+j+sDSU+zqFX3VP6+guCyxbx/x96PCWRs9ukmxIQpxR8D85P520gU7B3hHgKYik2JM7hSnUv/TCGPgfjT4debv43rUF2AnzV+XY46MvyrKNw84LCjlegMN3qCr8630fSnkhywNjtJNiUk7nheCkNvZTDdisQZaBcBTTYepFqXInmt4a5l5gL4NT6IWRENBOqSG6L1NeJMgcDJG1ZYJiOO9H3kaY0X2LEHHmDNzIEIr1Uyow4cH6UfaV2W93jH+Nh770iRoG1B7g+/d8fbxmj0eWfHf/ZxtMOkjMSs2eo0Sk+1++1tZsftl3Td9NHgIL86QyRzsv3svcm1WtqkyTfvItioZTZ4MtVtdS9xCjkXEtvxWQl0d4ZkhegWyozRW9bM9eZaBoTmCPb+InSR3mk+QWH1wRWQ4DxXq13wKNjW3TTLP8UOHcgiAaNCsaJhjCdhhE567pjAUkmptV7w9ucwMqVxI2Mpt9zUgWqOVuXduoZtXCSEfF5cgT++tIYf4xdJu45kgNsf+fyGS3Uimf0oCCOMkAcLwazK2WvhsCFfnW3o3yGPoyAATKBvaD20ATLxgtFeRxYqHLKObQO20kkNdStJsr4kXmQpK96ce7W2BjHyMEQR/vDNwUJLZKE9r9uD8XiVRJYfFBkFaBnQmsPIXQlNw/JIkNvAkG4u9eSjASiPLWIfweSWynWxLDNW0TQ0VgYuzBWRzetwuwU0NqioocAOh9+8Ud8NectPHWi0t8zdznlzuEJ9pwZXVDgtoD5V/tcsJ1ndufUtBI3gRo+O9893hmBflmOOGRBBnfkvJOeiLFZyjMFlTeKRlrFY6gkQq4VK3AaRuqj07RqMYHxbdbNIhw1FZZ3P14P4A3rEdl19W9nVFvibI4QJgpEwUbr09LYecaQiB5pZK9d8slc+dcL7pffXYaoR33kwJFgOt+FcyRAWp3X0oCFKQxUjX/rmei+L0JVWMPPGJGHLzhL3nO9u7ZfqY6fZhslZThenOZU7zv1s76OHOEPOcTqmuJj6dU9NbAOHLp9Pmrp8ShTj5ZdiczWVzoWrKiba2FcVVVFsKdHHm11TwozAV+mDE8ua/pbILZG27R3XBRrtq/zoums2btrmxVT1zsam6Z0wt1CuLYNzvliAwOrcMyCXZY15o0b8jWoSza9mECSRuHd/lDT6GrHA4LS17zW1S1Cie11++xFXIw8EZaHDEsqqi2GaYYX5uMFU4OmeFUoXmaKY/gZ18yT7uLvuZy97mliZMH8vdFdWTencmxd7iKJOCl7F3XjL2lfPMA6KmfCqF6qGpmHMV3gMt04oOiksIIinMRdwaGcTTnWNJMEXUWf6oVP9ellqAaumyVEbhqB08dnIV9TySd1TtY52Dsulpvq8ruXQkKOl8zPYcayWO+8SzmvtjBjXQRLt81+47J4= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.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: 28 Feb 2025 09:41:35.7418 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 2195acca-6dad-4f26-b3ae-08dd57dc17b0 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: DS1PEPF00017093.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR12MB8123 Currently, ghcb_alloc() always returns first entry. Fix it to return an unused entry. 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/selftests/kvm/lib/x86/sev.c index 425ec8a3a3c7..228c446072a8 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) 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 = &ghcb_pool->ghcbs[i]; ghcb = &entry->ghcb; - memset(&ghcb, 0, sizeof(*ghcb)); + memset(ghcb, 0, sizeof(*ghcb)); ghcb->ghcb_usage = 0; ghcb->protocol_version = 1; From patchwork Fri Feb 28 09:30:01 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996026 Received: from NAM04-BN8-obe.outbound.protection.outlook.com (mail-bn8nam04on2081.outbound.protection.outlook.com [40.107.100.81]) (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 A8C301F30A2; Fri, 28 Feb 2025 09:41:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.100.81 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740735703; cv=fail; b=JotGaq4z/K9cvIcdBPA3YXMKZDWzGNA4fqVxzDQmPItEP8cvyox6QZCDKun96xaK9SvUZGvWMIeuVg0d+3k7HtYF0HAtLIHeZ7/rjlZCbT/jl6XQushPGeA2Vo5CtqCLfddEVCNqYb2YyWGygFK4cOYilASHXEXHXsUwJPHr+4E= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740735703; c=relaxed/simple; bh=dNjXxv3BO7f11ZaZeBBWY+yuLZ/Xtb00ia7/yhpafXQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=M8YiSKCEqrl3H9+kui8SZoJyirpvPsJ0jde/fcyd7xec68JxqFyEZiyalNMiZW/hO2aMjXcZiqo4AT+B4fD20KfGG+vU3jT9ws9475tVKMap08EqbWlyZY8QD3aQ4QUaU5sp3Ib8pUSOb95QFtRJLFOLEZ0b3cPMJBp7MnIGxZU= 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=UCiF6RDk; arc=fail smtp.client-ip=40.107.100.81 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="UCiF6RDk" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=KZ5wrnj6GBSJ8+aw9la8bqJ12VOrPhbKxhmOG/zbRS5KMStAGUmIE6+mmi4JnO43lhqTQxyuGPRmxzvIbFCE4RUzX+4vnOVd8cS1ErX4pTR9WNPu9AFGE91Zptjkji7o9bUEKhcvVR9XuHNBGCgosY3+afLxChADfynHM38AzJnWMhL9jP8XdrAbOMVTSKD6Y985m4n0NjUiX6smqhjry6nW7y61wZgvR3qEK6Q0SkMtOyAUFC9Wet1bKxTk1YrNGIyPThn0nbeqqSS4BPw4kf8YcSpZZCDVFUcZdRcq9gA41HsJhMx3riSkZe1Aaeq9icZBbTfnQu4EZLPbh1i/ug== 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=/QeGIWIgArPXOI/rlX9Uo1GEIGOqE6uyjaNnc9riVss=; b=ppqnV37HevuI6xHd6vfNeLPImxerbXAB+CGac68cwp2fnUNpms8X/YIlZ2DTTYSKnSvK+as6oIRoUKR98iZ5dKHrnd+LrP191oqDgs93OdEpz2jMeF4QkjIwiargfZRatkbhjE6LH9+MRxPxArHxA8728Ah9aGtcn0LkyNxblzvivldTafb1nGoW8RdlKBdAKJRwS9Uly8+Yc1WY0dSn7VsJNkiWv85Kj3qwmGApjA1sl0rOhYdUgSAWEzVPEySrnibUGsF+GtRBp4oiqP1o1N059qDWjCf7h3Ie/1EACdHTKcOSeGWqv5BH3hl+16xT+adjuE3YJRAbUF3l61N9Og== 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=/QeGIWIgArPXOI/rlX9Uo1GEIGOqE6uyjaNnc9riVss=; b=UCiF6RDk9KeE4mVtMbj3MY717RQqq/Avk1WJFfSUFAhqiqfCxVCWhdAMWV4tEhikipfBFd+2M+ARLK3Zum+qom69Q5WqLCnSDptSM5GvuRMW00wYlZgnsxctYAsB6EwQm81HUyuvqSbuIuJz2ngpOaXAtFBIPY/VsXmCsuz/GaA= Received: from DM6PR06CA0095.namprd06.prod.outlook.com (2603:10b6:5:336::28) by BL4PR12MB9478.namprd12.prod.outlook.com (2603:10b6:208:58e::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8489.22; Fri, 28 Feb 2025 09:41:39 +0000 Received: from DS1PEPF00017093.namprd03.prod.outlook.com (2603:10b6:5:336:cafe::7e) by DM6PR06CA0095.outlook.office365.com (2603:10b6:5:336::28) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.23 via Frontend Transport; Fri, 28 Feb 2025 09:41:39 +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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by DS1PEPF00017093.mail.protection.outlook.com (10.167.17.136) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 09:41:39 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:41:34 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 08/31] KVM: selftests: Make GHCB entry page size aligned Date: Fri, 28 Feb 2025 15:00:01 +0530 Message-ID: <20250228093024.114983-9-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DS1PEPF00017093:EE_|BL4PR12MB9478:EE_ X-MS-Office365-Filtering-Correlation-Id: d78b2514-efe2-4647-120a-08dd57dc19b6 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700013|376014|1800799024|82310400026; X-Microsoft-Antispam-Message-Info: Xris8klAUIpoQGF7xdOmw0Ck670gXtzhci+BISC1HVroOvKx8I5eCcz5IOY/A/k66vBI00VtrYEuOJTMuFEkaDGxOMGwiWFGGUbB1SY0Ig7EcikJRwoFn1RIr7OTpKrDf34Y4l+ZGl+JMQNKPC7cqJYnYEvwCis3KBcAdhcu6cnDalGrS3eiBvjJpfxau/z9EJDBnkiNtxQFzwHnkmBITfXW+3mffDncHs7MtvnijEi5fh+71yHrKjmiPXt3grrl5+Kfd5UI/tACl/07PVmt1FuyYwN9woKtP3QtRKKrJghocJw8NoPwQETvr0+x+O1j3hwARTF2HkNKx+GMOENjTYPyyFbua+RvyuYIG/b5Qu1R2ymoHSp50bfeC3Cacxk3wHG/24GioZCT3NB9j0MFkuVbAR8bwpA0SpY9jnO2TAWxyUPrBuR7HyMAQmPXrCZLIq1bRWofqHdboOxwCJOEkmXEu+5Apn3L3FV/S6BnH8AlMNEsRCrbaXer84L/YsbLjp1M26m0CwxzrD3kSaTdFZXMa2oNiA+GHVMuYO9CX3jLtHweF1TSlX8rDu4/XHtuOLb4yZFmI+ivtKuH683y7p6/Gf2mfzq8flc4bXUKwKhwjPzJOAeX1NU5PliYdUGMGGCzv5eU2w3iYw4ZpF9STyR74+zNRwInhP8w37FuQqb+Vmeku/pLq4zfw+m0v+T8sxd49UcJjJI8s+0QhDe7J16YR9mCifIyBMjpI6T4huPkMGL5ls0Py00pB9K05ttwSBmA/gqaZn3PLS3c8Nzqd224ceKeUiZhf+HFOTY9FBG4myY+f4Pe2HSoPqborpVXVvC9uBi+3QoHtJo3+3Z0Vzpmc5HZbw2Rugx7Pd8tyENtq1BkfM8s3o38OXWlOWUKpTv7xnF8gS8Yzsd22TPo2LzUNID+uStkuxXsM7LHVNDnD2BpPYRn0BCRhc8yj1mmtNBOo7LKu0GmgVhDL99ullaPK6KFL7w45ANlTGWgkrO2Vk4XRk40/P6XLACxX9PVBL74qlRgT/yTj5uXUMpO/LyZKshr4yLsuSLaHS8ByJGeJmQ9t8/c7WnlFB8dLbXGT0liv2h0HWbvyq2a3N0tNfdQXnKJ9uGqNJDuEw/M5tZqTcfxLGi1ydwdKQr/k60t9A23P2XkHphm7nAig8SbgjXhR559p5fKFjbCh0zMMBX2xjDKoWKmpjY3vxrW0iUFBqB4EqRvP0GD426OzOQ/WATY3/g9bSBmwpIHzWyhQ7LYHIf9bPyMPOYPSye34F+CAWiqSDfAuBYD8ElOP2AsiFZcx+0OJsrr7xOQ1jTJgYF5rW6YHKkKQcqSgagEM3x4RiRaAtP5BazyiCvnDJGS5NM9q5wD5n1lNzdpkWUVYlqA9Tw5GUx8AqKOsuD0Y0b8PvPRuMOuAa6JvzaN56tX6SRjQMOlkIbr3AAaKzwn/kpLBZ8/L8dtKI+oXrhd9/1Ye+ZwdJnVMKI9LMPG6RV8FUZpOuSEG1cqcu1uUWXG4dQ= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(36860700013)(376014)(1800799024)(82310400026);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Feb 2025 09:41:39.1325 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: d78b2514-efe2-4647-120a-08dd57dc19b6 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: DS1PEPF00017093.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BL4PR12MB9478 Make GHCB entry page size aligned. Without this change GHCB GPA registration gets incorrectly interpreted in host as a GHCB MSR protocol 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/selftests/kvm/lib/x86/sev.c index 228c446072a8..38813f60c252 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 { /* Host virtual address of this struct. */ struct ghcb_entry *hva; -}; +} __attribute__((__aligned__(PAGE_SIZE))); struct ghcb_header { struct ghcb_entry ghcbs[KVM_MAX_VCPUS]; From patchwork Fri Feb 28 09:30:02 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996027 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (mail-dm6nam12on2084.outbound.protection.outlook.com [40.107.243.84]) (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 9518B1FDA8B; Fri, 28 Feb 2025 09:43:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.243.84 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740735784; cv=fail; b=SAiFm/tlVy8DJuIIf9q6kFu48VATah2Bn9bTd7wgeR4uAEQ1XrpUMNThRBaorPpMHFCQ56gmLre8tib3QKAJ8PwXtlxEXG/oWOv6R5EVdDSfgi6B48O5TatuNiPlvxwoFZg913pmY2dUZwmnmswLCl9/wIg4Kbgzo4Gqd2V6740= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740735784; c=relaxed/simple; bh=PhRW352o94JPPShsysnJdpsi0OU7P42OZ10BJMj/AAU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=TbThCl9Ln2x+pOU+HwHeZKPewFyambU4WrrVUCm6Y9FUOS2KEG+oOgI8HKfeiREULoW9gf1Wmi/a4bM0wunTe8yXclMnSR11++WiCxF/zZLm0ywdy9SgefEtW/FJPcK+YXbB3cbPm2vBrmiA2MA+Ht5T7zqgoa9v0YBQcy5jHdw= 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=oZpiPmnx; arc=fail smtp.client-ip=40.107.243.84 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="oZpiPmnx" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=UUXJyvNEu2XjNse5LCn4RvJZkdKa9ZP7kZUpO/nKfens/cBMd129auzWkPvDaQo8vlI8GZRVlYXMnoCxKEL7qfX0IRGZFGGi6umW7RbgelwvUc5K0BkKE71xsA7jXdHnjOxI16FXZvTxTaijMeKk3F7PXGrNIEp1WQLlKcYOcGZbInRYb6GYZLAtT6Fl/husqevpx25TMoNVp7F8y4sGrOi2YpyAv5xu0LYkEJcI4o1TynmMGH9I+TRQE1dxXGYB5oU1tHpZfnDrGQv/jfj1Jr5H2dVjKmnTlRTMk3D0gTJ67FXj+s6hhSaqaGgVSKdC7po7BTtSfBu8+FtpKnPpFA== 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=2PJTW92VFlCbweoGHo1wZnHEhehDGEBMja5M4pUyERc=; b=w99NwaS0CbAl+WbEeDKlvoVOvZFwZVDxb79IIxcX4zsdOjqDgA2x2SUtyIDpqrH3zMaWDe52pazi9231L06P59u5EBTfYe+zfpl0F84lUneSDJeV+TIr41F4FhaXDoPXTklOQd3CF6yEJx+uoA2kXur7lvjNiUy9k4MGCgHOoJvbbE77mEmkheCLqreAQiedMzkDxNr0G+hvevj2KUu9HDOQ8c7Gu5Gif0Y5RC+Ydphc6g/17PJ/5Bonp403M9xSaUVDaps7PDI2zU6lI7WXy9AQE5D7ObUhFCnj3MN9r0roDeMea77R+PZTZg8qafoszlaiDkN0Hzy4szRj5IUlXw== 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=2PJTW92VFlCbweoGHo1wZnHEhehDGEBMja5M4pUyERc=; b=oZpiPmnxHKZMXqv8p2g9WykvecOh3HQO5PbWu9SXQTiXhQCuox+ImJtZ6639NHBOyHKVp5JTwlZ3qMPPxTiYfU7bCB8BNSUip/ICm0lDhsB+UVQZOFRHWQDlsrJpafoex3NnpZe4it6e/h4dCBOFNiIWTk75gzb+LpnLgEZwi7k= Received: from CY5PR13CA0078.namprd13.prod.outlook.com (2603:10b6:930:a::40) by DM4PR12MB6181.namprd12.prod.outlook.com (2603:10b6:8:a9::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8489.18; Fri, 28 Feb 2025 09:42:59 +0000 Received: from CY4PEPF0000FCC1.namprd03.prod.outlook.com (2603:10b6:930:a:cafe::29) by CY5PR13CA0078.outlook.office365.com (2603:10b6:930:a::40) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8511.10 via Frontend Transport; Fri, 28 Feb 2025 09:42: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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by CY4PEPF0000FCC1.mail.protection.outlook.com (10.167.242.103) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 09:42:59 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:42:04 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 09/31] KVM: selftests: Add support for #VC in x86 exception handlers Date: Fri, 28 Feb 2025 15:00:02 +0530 Message-ID: <20250228093024.114983-10-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY4PEPF0000FCC1:EE_|DM4PR12MB6181:EE_ X-MS-Office365-Filtering-Correlation-Id: a506aa78-a1ef-421c-11a8-08dd57dc4989 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|36860700013|82310400026|1800799024; X-Microsoft-Antispam-Message-Info: 8kEksL7xKVquiN7XizVW+noKgm6ulg0hdLBqdoVKtHWnVXboNxnIcEWcnHqEKVYEWuvu7it8EEWHqUAzUr/xjsWo0+2EAQPmo3B8cxLYzZ8lwFmFEEOmKSlhIpyg5N5i07K3Ou5SPl62/XmDGb9WY9rjMzrCjtmmZVZBIRh5+p3S04kEXRkP/FvOs7TRYjhngtatQciL2oEgX2Wgq6Rv4IJgOXdDUpctslJkLh57xQXhvdzCOTyrGj7V6qEzmhYm1mWFZPI8xkC8Ejkqd/mhZ4Lk2WinfkgSgWmSB7O54AqtzWDTPQVxSX8mA6g1c6k2/OqnQjR5WGkN25Mf3qebE5MeXjw44g/LJ0TuZcIIsidDs8yTet9cPVNEvSTJB3/k5isLjaq3MnbbOdZt2co9blVW3L+50/Axz5J8d0YmP9OGM0ZUkqtygvywDO2d/YlKa+tJ5LWjbI0AH4d8/hIDkrrZtvyVIf64oGP1Lb+8AwIhGA8l/pWpiycmV8yz/s41O9uXOJQa+qAPD4FqyLenvkGu5VP1Rqso1X7ZUTVx59UmgEA1zhLc5C9TKZJpJrpA16Kr3doluS7RpcJjs9NTQgtOxO0jOeS6/oiteXzc5KFsoZLRCAZvMg0yF3vOloofZOGTAlGmM+hy6TPZjleG4D8Ar42KyfcHJ8+jwf+dPeJevKK6ab7EMIbIxkxt8uM3npYn29UJiAnIgcM/WD4BtSOgebxryT7Ft9TjfpY3YhBIpgW7NcL/lLq1uzPHR+YXgrGg6T4Q/7XjlZbKVLj8fXN9awc27iT/n1a8JuSsMTp0G8lkUr5m8TfAfq3ikiUyawj/aXP/zFb8Vaa0SHtoERC6qgvQ8bTly2Bqg9HVgBOn68XPsBo6E0dsdGHipgjv9D37YDI6LlDdlwcV7wCs/tHe1gu53ecZZPpy2J2PPzYrTi/t9WHtd0T1dgNQPnrnpVczWhNr7BBlh7Grwd1NfawoQTxfd/pczZxXGien51OhLS9U5ATIEmbbnJxcNLJMTmZpg8gtKGaVbFjk6pTR1AdPXJaaPhVKgMvWYOj8rgmJiyKt9xxw+7LVUsFouZ0XRcaE2QUIB27LqVznh+71meJ2FoYIM5KvnIzje7YR4Yp9m2+F2GSGW4lRo+Tn9+Jr8p4jLc7qe24MqDSzlPqBHPgJoMFWUisBoFuXmwMYkOmsCMwVs8dre6K08IQJKsH/jclohWbHxdst94dWm6UqardI3g0GqjiAyeO7Op+5i5aSL+Q51ebeFa8lGUlKD5hmgO3hYkicwQY+7ZlWeE+PuGUmOBPQlpyJzahN7i8WnCIAmyzDUDHubisrCDw5uPUHvLxDmXVkkg0j3zwqFDMmiBzH1bdCVUolqekIMqaECfQ2tRIqsFH/pMAawOYtLQoh/pWKyX04UPm3voQsXdjqpNbLLIO2Lgm7zZbM/oPnZftTJgLf8FYmQ03DAcAPbsy/fVe6He8xjI0kZbYOFy+nLbC1uRDwlBlzflXWP1BuBII= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(376014)(36860700013)(82310400026)(1800799024);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Feb 2025 09:42:59.3213 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: a506aa78-a1ef-421c-11a8-08dd57dc4989 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CY4PEPF0000FCC1.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM4PR12MB6181 VC exception has an associated error code. Update the IDT handler for it. 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=1 from=10 to=14 HANDLERS has_error=0 from=15 to=16 HANDLERS has_error=1 from=17 to=17 - HANDLERS has_error=0 from=18 to=255 + HANDLERS has_error=0 from=18 to=28 + HANDLERS has_error=1 from=29 to=29 + HANDLERS has_error=0 from=30 to=255 .section .note.GNU-stack, "", %progbits From patchwork Fri Feb 28 09:30:03 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996028 Received: from NAM10-BN7-obe.outbound.protection.outlook.com (mail-bn7nam10on2057.outbound.protection.outlook.com [40.107.92.57]) (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 AF1AC1E492; Fri, 28 Feb 2025 09:45:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.92.57 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740735927; cv=fail; b=CB4QuwIw1RlqWrN02Uy3PlJUQ5aUk81YLjWUavCxiQBm/dxV0vfGqz/larU4COyPO62AErkzw2iqo77AYZ18soImijRmFHG2koalP12t75UDwgVBLzzu7+qmcoTXhSCzhfhFLVX1PmAAU6HVUSijToKi3BLPCU5nL91ajf1s7dA= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740735927; c=relaxed/simple; bh=Z5WdLbt7XycPv+uzfajCcIOl9dKJoZisAV4ANBbgHdo=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=bXah7l6W0Gm/Zkj2Y5nFG0gWX3SWg8zM6OZNSdxTG2YW3NJT7GNzXpVqJ2JVmf+Yf7kvShuNzLEqb7i3MkH0fgiHdLUGdzA7ye7W1mRfyvGUEsQowuyuVATxtrPg4gdFO76WAyYfe++x/FDu/yVy51T3+v8oVTanGTZD7adEIzc= 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=NT/4PDzf; arc=fail smtp.client-ip=40.107.92.57 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="NT/4PDzf" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=VHDL0psPlKRGAbgIFKY2UdAFlcLWVYiw8XkCVut6HUnXBNJ2K83u9aqck8ulLCPRQpHPCt/Tc3TNIQx9R1QL+H4RZa3BMaShIpZROG23sV+Ve33/7ZXwiyBJevDc4IyD1Y8pUZm+cjkHlXPrG9L9ESGFJt9S1yuRWvGNGSs3XswMp+UehxTOfFcN0V/kVNdl+YYyZcQvLxwlizXuHuhwu7U2vjrQFINrf+HSgPQAPmt3yRf+MktIuD2ost1FhjSQvQAmmFg2uW2sWqn/KlrMbNjguEYlu/Ly+mqvfds9na4tUUM2aPIGWb1liFYxClgRSKWeB2+8aCCe6MxfDZi6dA== 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=UnUNhU/+noMk0ff0i8Mqt5w/V4bpDcGrA3VGqDA/NYY=; b=vkAhAxShRxaI/3NdCfk6fswJYPKlZhW9rnCfiFpKJ5FDBc97z1lvKmsivvKqi4YrCXh5KlBtmAyz2D1hwN0v+OmP8w6kAmcN7WlunaY4pb1bF6tBBspHOB1M1pTj3DDscA1DHOA560sA8X1Jg61wxZ1ZjjSQ+ylJ13RQMbWJbT6OkJR2GHlJFI/4uJyiMyLJfUXvlRVYFweCy7GLGkTXOfxV2hxFCTSSKXebBt+i6u9SNyGCHPpHFotFP4/dUDjhUhIsfhdPaBYJLN6kN4znnXXqEaQvxo1GnlaaL+ERSTh7c4aC8aI73dN+osxWOA7QryznkNhkD7vDmMP3jQujMQ== 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=UnUNhU/+noMk0ff0i8Mqt5w/V4bpDcGrA3VGqDA/NYY=; b=NT/4PDzfsoPgUNITy8K1XusK+eiFnjGpi7V7FGaja4KGVp8yYrYc5QAUGpJunrZBVohwdGCGP+x7SL8+caFGWCAgTgeNLm3qORc0JUTVYwl7OHw9yjdMlLHd1ZddidDI/F5isy8r7BPdHWrG205FaiiE46wSJvXSHofFH9w84oQ= Received: from CY5PR13CA0061.namprd13.prod.outlook.com (2603:10b6:930:a::23) by SN7PR12MB7883.namprd12.prod.outlook.com (2603:10b6:806:32b::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8466.19; Fri, 28 Feb 2025 09:45:23 +0000 Received: from CY4PEPF0000FCC1.namprd03.prod.outlook.com (2603:10b6:930:a:cafe::5a) by CY5PR13CA0061.outlook.office365.com (2603:10b6:930:a::23) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8511.10 via Frontend Transport; Fri, 28 Feb 2025 09:45: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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by CY4PEPF0000FCC1.mail.protection.outlook.com (10.167.242.103) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 09:45:22 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:43:28 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 10/31] KVM: selftests: Add MSR VC handling support for SEV-ES VMs Date: Fri, 28 Feb 2025 15:00:03 +0530 Message-ID: <20250228093024.114983-11-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY4PEPF0000FCC1:EE_|SN7PR12MB7883:EE_ X-MS-Office365-Filtering-Correlation-Id: 84573893-577c-41f9-cb46-08dd57dc9f26 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700013|82310400026|376014|1800799024; X-Microsoft-Antispam-Message-Info: TV6J5tIIULGmfqtu4ejc0VFOhzM4jY7YdrxlzTPDFm/KT7sZYCXucQYf3KNDmcljf5Ek8luAltweLLdr8Wt9QO66JLOg/AUz81B1peFSoqCrDJ7ylBXTavBXR2Ftdb+VxVXdKilmSPhN6n+zP2uAM343NScxd5Mj4s1NKmSWG2tJ68VePCfh8+LH0gNnUmRBEOLHGWrYTDP/GD6Xo2GD3GjUlWvXFAXhTedsgXelfBCifC49767TQqH2kKLzZF0mA2+O+zxvfe+iXJhQvk/ZTXahL50njLUSN1DH21yNRNXo0SjrN59JoiLyArF47P168lgOyBT9qm0alNGgDFKUW7jWj9xScSDVMQIW8yYawmDeTMddE0FHHhZutcZ/EZkHRTDb5vYV7voV5uRtSXC5ki0hikuudNRAGFqbOKOY5RLroVkz0sCmMzAvjW5jOA4T7MXFtnQRKtlCsA5iUyCwEiQuuatwdLV8QUYLx3FXdTaZGAdDnwX65VUcWozPFC9U4wf19c1jclBY3TVP6DFl8fgTOQNBRVz4wrfAGbp7sQqG2OzsocqL7WG4y1J1vovyJYdIV0WLo35VydhETQG1KvZ5nxQo+oiZPbSUZa4jGtx2TRaXME21FaezUC60kFlrscrbbjvbsUir0Y2GebDFSF2NxmHcwaW9w8Xmr/nx4GBeY6pF2Csma0dw9Ic/TK5TxXUCyUunvYd0d5fY0KgpFdacgEN2bNlAvDFByicfvnvyBlYvs0IbD1GlRL9OjQs7Xegc/H6rLH7n7+dI8CI53rIjJstDGuBWcVQ26xtJM7HU0MKsJKCzmhot3pwCPsN9z2IAkgywCJ3hOVO10q9gAgq65gvdvvtSQeEnWP+A1eHvXUTUVJDJP7PjekaP11QDnJpwFIE3mYx0KZV4lLp+x+O1Rfe7obIH1TKFZcPubpPRNvwJtnHb1vxClaV+l2Wyi0wl9d60Kqa7B4+XwAy6W8ko8USmE7WZkrwnciRXe4nxrWlCGDECOjeWf5Zq9nRmXnO2APdmnuk7pUGtzLMHPOsxBiL9JaIHdhSC5ZQ0gVnxReOd/ITBuU1u4sgoOlo0xIOS9RYedkgJSoMj7UjXaI+6zS8q5lQMLONzXq5w05RThufQGRHOwv1paKfGWmMLByTfqTW+HMM1V73ZxXJPYkNLFFHW+9DrUff37N/PY2ke69UK4Pshd83r+o3wcDuKYOKXrVWcDRkQRerOQr5EsAwrpJ1Xq7hLhdWAUbYWwBKqqRIy477y47ll/nT1rJJvJUduaOPAkSV5ZQVLN6HvIfaQBALUM96aJ/eGBSOvi0nU6h6hAkCCVlD8mXqmglf2QfbJ1g5hFjzYcWzokbvCeLdhI12Mb3bnfJPFwwVncdcxn7NDskYJA310I18t1CTBaM4KvwNZo8YTm9ytYiw2/7NoYvLdxePds1f/N6FNglGvQ5mGrN7nk+PUQMsMfCi5NjQcXdYjs3djZ+KozJ7eP8cQvcQhBXRNt6kbw6KMrqU= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(36860700013)(82310400026)(376014)(1800799024);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Feb 2025 09:45:22.9457 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 84573893-577c-41f9-cb46-08dd57dc9f26 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CY4PEPF0000FCC1.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR12MB7883 Add #VC exception handling on rdmsr/wrmsr accesses for SEV-ES guests. In addition, add PV interface for direct msr read/write from SEV-ES guests without going through #VC exception path. 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 bd6ab3f38679..5556ee891260 100644 --- a/tools/testing/selftests/kvm/include/x86/sev.h +++ b/tools/testing/selftests/kvm/include/x86/sev.h @@ -153,4 +153,6 @@ bool is_sev_snp_enabled(void); void sev_es_ucall_port_write(uint32_t port, uint64_t data); +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/selftests/kvm/lib/x86/sev.c index 38813f60c252..ff8f02b83871 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) -#define SW_EXIT_CODE_IOIO 0x7b +#define SW_EXIT_CODE_IOIO 0x7b +#define SW_EXIT_CODE_MSR 0x7c struct ghcb_entry { struct ghcb ghcb; @@ -404,3 +405,83 @@ void sev_es_ucall_port_write(uint32_t port, uint64_t data) 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 = write ? 1 : 0; + struct ghcb *ghcb = &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 = ghcb->save.sw_exit_info_1 & 0xffffffff; + __GUEST_ASSERT(!ret, "%smsr failed, ret: %u", write ? "wr" : "rd", ret); + + if (!write) { + *low = ghcb->save.rax; + *high = 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 = ghcb_alloc(); + register_ghcb_page(entry->gpa); + + if (write) { + low = *data & ((1ULL << 32) - 1); + high = *data >> 32; + } + __sev_es_msr_rw(entry, msr, &low, &high, write); + + if (!write) + *data = 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 = 0x30 */ + write = (*((char *)regs->rip + 1) == 0x30); + + entry = 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 = regs->error_code; + + switch (exit_code) { + case SVM_EXIT_MSR: + sev_es_vc_msr_handler(regs); + /* rdmsr/wrmsr instruction size = 2 */ + regs->rip += 2; + break; + default: + __GUEST_ASSERT(0, "No VC handler\n"); + } +} From patchwork Fri Feb 28 09:30:04 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996045 Received: from NAM10-BN7-obe.outbound.protection.outlook.com (mail-bn7nam10on2079.outbound.protection.outlook.com [40.107.92.79]) (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 62BD41A254C; Fri, 28 Feb 2025 09:46:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.92.79 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740735968; cv=fail; b=TGFKsB7yF9mrx7KAZLIygxB2G00mr47fvsZsXxCTXM5D6KGLnWcZ/SDx6I+9JGJUWMCiGyeBjp7JIuxcWo1VzE9P0EkRcm4imKZJTm/f92h0hhQXjiB3BJqUWnTwodoH0FJCdfK8SQ+9fYIqT/HtmuMN5tgeTk4R4sgcv5GCvEg= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740735968; c=relaxed/simple; bh=0OKzUlXC6g3sJ76Gi0iBLTEuTWtq0Owg2m+pipRnxVA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ZPQ3OakhxiL1Woxh5zIquTykD9NGNdHqcXYuqzX2elsiy8MtvGk/4UnWvCgmfuuEHm0vBMuE76mEdgJqeiyG+MXI4qqzyS/FaM6YK3MnQTx1IE1ZgOgB7h4AWuJcfD3pwUi5SCMPRuFZnaBi1/ET5owh4t4kTHhFnhNY8BKLulk= 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=1jAnl7JP; arc=fail smtp.client-ip=40.107.92.79 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="1jAnl7JP" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=Yvh1J5V1MHJPcBnfvZaWl/7XY6t8qVEb0lGX5BovbvGa9uQtCYNkbALUKaolpqW+5O+rumJAqXil8IgjLzlj+zGFFRae5JjI9vAWHq7rXezI9im4sl0OyD3+e1BG9ZMJjYqqjjUpAjnAxn5oJXTjCEeAiHnrv3yQDNIKRaK1RK4ZF2olXr7k+JE+pBtPVi+LqPqYeguluL6iWMrskCOlp0FZe7k53ydnFm9VsWDzB6A4kuk1SAq/sHSLDsgaJu53VZW4C6uFVfEoPqVcO3scZlWK61/oZaNycIUpWVd9Tonco4hr+RLjT/SE3T2+VxwA/YeVm8szPfV9x1yaNF5JNA== 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=SK27t4v9cX9vnEPKXypfGSzep290BNlHFpCkQCsXYJA=; b=k7uZsm8NFDk35xf/HaUsJZYsThu74Y5tDbOT/KCwCW8Vnqt5BGbPNCTY5ugva0xgyCfoyhWPlfhd/LHo3+RB94I3wcRIa98xO/2gNKrs3gEslrfBNVgXklYuDqq69ifzB8Ezz1w1K/nuJWOOUkWenxQgP1LHu0iu8lY9MufHJNAeCt6nH1ifcoGbyQp5RTNAVktMy3GtOmjsAwuMEHbIWZ5vc7zZcnBKPBcl6S8G70fI9h9roQLJ+ekcUrvvx2lUeS7Pa62Z6bOWKtNXtRvOyy/W3dVhRvDQckyWXif6xQU2NujdXdho3VOaHMoxj7IORzhmeS9xw4NV4DdqG1ujgg== 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=SK27t4v9cX9vnEPKXypfGSzep290BNlHFpCkQCsXYJA=; b=1jAnl7JPuJsI3278J4PK46XYJDtDYJ09H+yz4pkqMs1o33UloxzRXmGQvSxnvQ7+q3F4gcA8o6dF+jq81oIWqBgOZTgSfWR9gHgoEA8CfypsvfzH2t5w816OxUojodl+Qsl/BH4Px4W9Dv2JCoTF8C6jo/duIRS/ecd51N9pW6M= Received: from CH0PR03CA0418.namprd03.prod.outlook.com (2603:10b6:610:11b::19) by IA0PR12MB7625.namprd12.prod.outlook.com (2603:10b6:208:439::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8489.18; Fri, 28 Feb 2025 09:46:04 +0000 Received: from CH3PEPF00000014.namprd21.prod.outlook.com (2603:10b6:610:11b:cafe::43) by CH0PR03CA0418.outlook.office365.com (2603:10b6:610:11b::19) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.21 via Frontend Transport; Fri, 28 Feb 2025 09:46: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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by CH3PEPF00000014.mail.protection.outlook.com (10.167.244.119) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8511.0 via Frontend Transport; Fri, 28 Feb 2025 09:46:03 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:44:52 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 11/31] KVM: selftests: Skip vm_is_gpa_protected() call for APIC MMIO base Date: Fri, 28 Feb 2025 15:00:04 +0530 Message-ID: <20250228093024.114983-12-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH3PEPF00000014:EE_|IA0PR12MB7625:EE_ X-MS-Office365-Filtering-Correlation-Id: 755c202c-37de-4788-33a5-08dd57dcb77b X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700013|82310400026|1800799024|376014; X-Microsoft-Antispam-Message-Info: 7YlUY17kna1PwAfyLke5HqiOyrEKCqM3jGNTRmaJJ1BpLts38RBfTNfan+CkEoEMjWxoMSLyXqPN4JEZrYniGWflYDIKz1zQ6x2ULKhol64HZ9N7cS5+itgmLQt6OM/7fwkeGqKo/DO16Mu+/JLa15oTkelrHXdnP04meeag/XSsVMbPocOUZrLoi5a3GAb8a/OvQzwFHND7NUi3y2a62ToUDjP6cPBLGEjNH3CMu93rNQ/1KtVUQU2688CDnqEsZvDUm1ptJkHc9/NTM1BLfry+ij6ov30yJvojhcqIpvlpmFI/tCHiyRvW8AbA6KRH84/uWJ23pkdwr/oD9E30lay55ZHzNQiOsqsNIaDw3Fh5VN96fCUK2+g5lmIEKv0sVVYOVSi2ZgezDLJqvqZMo1pc+RoiIZ0N+iZM17RudejrbWxxiGPkXVSE5+Kk4lUBzrWQPKYY0fczGR/T6C8sx9jJIFc2ad7Mp6rcwvGE07Wq7cBE1RN53iTi4cdzrBP7WZiWZ8bCZ9OBqBDvGWu05fztuieynB2W7DVJOQ3azdneRTJdBDpdKOFTau0lGfR9R81Xtg52lqKNK7JLDkgD5UbjTiv6h4N39+nnMSbXWVFnEYUmWo9fkeqQp066oHI03YuMljNhiP5kMb6zHXHu+ieF+5BspsL0I5Eg1E7FUiaOMjTgc7u3C4Z4bMf0Y8FzLc0XXnTeScx7tEbkV7OI6q3lj+ydCny1jl7vlYcX46kq7bKDlPzWU8/7G3sFobcuTJvjDbyechOu09I95b1Km3Wutb3iDOEDV/MciDPfPue+pNX/JLCMr5onbbfF+TJETFC/JHTXos5s9pVTQy5hrGsZAAOm/EW3Dmq89tcZOH3WPjxJDKTw+nYUIXRrFWPDvNVCpXgcb7rWv87w0HHhNgX8TM1E4Gn4F5WvQ6JCaiaonl167sOxqb59vVWODGKzHPIMIDIUFirIzt4YjUDZAshJlLwb54yEvk+VmBLe/N3SwCjOxIfpywK2MNYYjoQxn2v3x7xwYigoOTD4h7ZpNFKuLrRv2hqeviiOCMQNTXg2MISgrrkr1SjcWLYbntSxCxAfFmih8euWrxpkeTShufzBtopHSzOWt3wb7BMlHbBKuN3ezGKTVVuokLi4H48izi8XBRgHx9LGHQk9L07dh2hSPSP9pHRCeIZ4L6nBSX7WJdCUVSSHkMWKtDGhGfeSmaeg7+Ln2ZX8tzBGhJYz3zL+sxhrVnVxvvdMps0Q0n31+E5AnUP+RG4DxriXVZjWjxk0aa0HSH6qSjavJNcqhb1gEFMW9egy4ci+YUh9F+JZaJ1vwljXNuf9nXWnrL5sbv21f/ZJ+R3VvDg+D3V9vz2G9dAdaOGyou/VwOvPqCP2Y+88qF1GuEaNLZ2E8OV6txCfqC3ADxVScnB6JMirOxIzkftt+jmJZiUE9397eO3TSxMbefm5OZTWqRRIVpdLb1J6WAEZ4h5AjalI7dC80QUua1vTcVXiGBIpybTTW+o= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(36860700013)(82310400026)(1800799024)(376014);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Feb 2025 09:46:03.8579 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 755c202c-37de-4788-33a5-08dd57dcb77b 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CH3PEPF00000014.namprd21.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA0PR12MB7625 Skip vm_is_gpa_protected() call for APIC MMIO address in __virt_pg_map(). Without this change, the virt_pg_map() fails with below error for APIC MMIO address. No vm physical memory at 0xfee00000 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/testing/selftests/kvm/lib/x86/processor.c index 7129dfb652c4..197110ff1380 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" #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 = PTE_PRESENT_MASK | PTE_WRITABLE_MASK | (paddr & PHYSICAL_PAGE_MASK); + if (paddr == APIC_DEFAULT_GPA) { + *pte |= 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. From patchwork Fri Feb 28 09:30:05 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996046 Received: from NAM11-CO1-obe.outbound.protection.outlook.com (mail-co1nam11on2082.outbound.protection.outlook.com [40.107.220.82]) (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 69DA91DE4FA; Fri, 28 Feb 2025 09:46:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.220.82 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736008; cv=fail; b=UBrmpN54Uf7oePGhQIPfHUj3AblasghIlMQKb/mXsEszLlZnYF+ZH5mykLkPHW8Gvo3LklYm+sibt8R8a58vpYn6YDulD0vgoUtc0pV2+96c9dAMwAhUt8n3sy+Ew3ds1ybUvq09DZZBAPHUt/OCvUNX4Cpj3TVRAVqNmG4EfrM= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736008; c=relaxed/simple; bh=7jKfiSjLCBj0iBAE3iCsAQ2QI1WzdK5AL3lq+c5MP4A=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=UowRDPvDagbl4wsWanTly56OrDy2n2lCz7QOyIKRMGTqIlePeIM1uEs2hhN97S8b6pRwoSUl2XSLXNczv4pTWGpbMpX/cYwJ/KyolQtRvoufzeSCF3Cql418TBfHi7p9Ghqsau3KpGrdMkx6r/yOfPpeOx4GCIFQ/eTF4TGZn2Q= 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=2c/f4KSw; arc=fail smtp.client-ip=40.107.220.82 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="2c/f4KSw" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=QSJfZpEFtiS4OVqLwXhhT5+CmVniaRVUbgErsmb8Xc7Ml6tb2xMGx+BFpSFzNvUQAxHwlLld92pO1MmnDNaK8aLFfewVKwMd2DSVTTKuogrGpewbGN6qvTsDzVI1ezPmEO6+TMrNySpFi/5PQ5NR3EkGo5xKUFxiKYJKWueRV4NGTSoKxRcnXp2/H5lB2RmcoAgYpivwBeB9LzkR89miLVLUi5XqrVu/muM72cJVDGstrTbhoBXiNYNI//8NuWBnn8o1W65COuYlfWVx9Uu46RjQP+lEhj1PbMk8qKObmCnJNW/CCnAB0teLQP8gXbtRy7qcrVjmOlvGihoMITXlqA== 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=AglIH1KUHUlFPoDQIJ9Y1bIkzxC0+1exDhNS3ighivk=; b=Ea5YnPENEEVGyUL39sKQfnqW+Q1kRpZB5NGoA/IWzuHvtbhL/Xw7vPLse0kDGy40MbdKY2v0BWK9B8XXr1ZO7QjZq3BPBD5F/djWQbGT+x5vO7b8neta4EhworqZmjlSVJr/CGeqsriMNphUDxxUJblYlhrNZ671q+AURpaKFJvHnHZzDoIabua6YXmJKKZGklGDbDaQWHYuE+Ew8JASd3Lqdk2KvzwVBujQf8letex7YpSe4+J2rgcGArjl9LHtPOqZUkLLQH7EDdBI4gKxpmpyJ/AclRTiCDcQ4WRQidxqLt5Q8FOo4vXVJp9OrQkLM6LBRHKiOPCUU9eiZzW9Dg== 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=AglIH1KUHUlFPoDQIJ9Y1bIkzxC0+1exDhNS3ighivk=; b=2c/f4KSwWAny7w5iU4sPuS4+f/NDvn6soQQZ+JTp9J5WngooOxXl14RaDYiw7NbMiFdjKKhDAURZOGFYmXD4epu6d6y9Y6CdJakIK8Is8CXs8qJyONRvgENUHxyztT78b0qD6jjRckZjVp6IpSU/RDYhzZo91pJUO52s0prLqzo= Received: from BYAPR02CA0049.namprd02.prod.outlook.com (2603:10b6:a03:54::26) by MN0PR12MB6102.namprd12.prod.outlook.com (2603:10b6:208:3ca::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8466.21; Fri, 28 Feb 2025 09:46:40 +0000 Received: from CY4PEPF0000FCBE.namprd03.prod.outlook.com (2603:10b6:a03:54:cafe::32) by BYAPR02CA0049.outlook.office365.com (2603:10b6:a03:54::26) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.21 via Frontend Transport; Fri, 28 Feb 2025 09:46: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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by CY4PEPF0000FCBE.mail.protection.outlook.com (10.167.242.100) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 09:46:40 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:46:03 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 12/31] KVM: selftests: Add instruction decoding support Date: Fri, 28 Feb 2025 15:00:05 +0530 Message-ID: <20250228093024.114983-13-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY4PEPF0000FCBE:EE_|MN0PR12MB6102:EE_ X-MS-Office365-Filtering-Correlation-Id: b4726cd1-3726-406c-85c0-08dd57dccd2a X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700013|376014|1800799024|82310400026; X-Microsoft-Antispam-Message-Info: SzBF1dTJ5zwLl88pcmezx+FPKUxLkRIpuHEl0c+d19tOc2dEbRfnwEwZGAKC58HRzubTPSgxuNAdvAUyRZNBstH2dSzGvwRyCMSOW8pP3ZAupK8k51yWwpNvLIBIEiTS8LfdPapxsWadSjIwOh9mt9aCfAARFn13oxqgUE6bsd9jzm2Is0evjqub9+5gS30GS9m2eyYpk2YVWehpmMxEluoWgvEIqrqg68BqY8MGCFMhQZqSmckLcStaXAA4DaBtGLgT47DoS4TzMz8XNeAXb8dBbvxJ4UOW/YZYxisMsOzt3Pp26MP7PuhhJgrKcgN2ztkfVDL3TAgvcdbaARCRa8cDqJIBXMrIo0RhnYrrweHf5xWruVxm1zU/AiAW3uJN0IIbfz7jPqwuGxsJwxSOWw8s2KlSPv2CwZZm6JRbp+8TpeB1M7xufcFxxXVysAl/TBXH0qbMYQWGFGtAhDj5MJIVVYqo4CmJ40JJHeH9GZynopxv4uQkJdBbLjdqruNW3uqQ/D9FCwAkvEIA22dzsqGZYxXuE1sGvA4elojexS92HPRwMU7MxlRIX6+x8r2kFE3USS7wbcIaO0m+ObgA8CEky9TEDJ3lo1TTb+19FRnBI0Tu/Lq+O7fRqrLCJ+BH7cbnDo5N6avKBpW0+Mxsm4EXpzrRhgcwcaV/wBeiFf+9GGrEf4RRs6dU2ALhfhTve9zVnFFz3ZcMmaykDZuiP/Azc4UGKs4Wygjcyl9XA4z2Wr2H8qbh7vcpB2JvUI9aNLvEwluHfDEixWhu4ZiELjEEv/eB0zHBKdQgLxTcAS1fnhs2TpBVmmsZylveJItFUuRH7enwwiaoqStT6CTcIcW/MOONfAVb2D+G1e4CzdozGmVTjNuFo84Y66J1GhNf11ZwV4HDQwmdn1VAoS9GH5+25MTDJydLGWNufQL6VhC9m0H12MmgLfjofQh9o+WeNHFGy2CysI+4KEH0M/JzTg0yHM2q9D46bSnypIbXF33EMvoVaWCLCZGeVxp72oDh6F1zz1EMRXVsK2gcoQpZllQ4NVLGN7lOYOSDHPIOEAqZKmTLtQ7UjGIrEaAownmzbKsKJbdryiCbXS/5z7Lj2xr7to2CKSeHHor8kkwOBFlMXldKDGvSlSXgEkw2EZ5DA0kdWwxT7HgqUM1TBeiTAtW6o7QmxNxYe2FvmQGoc47SzPANY2+2XPTkP29zLSjRoMBdBCijPvji0FK5/fZ4xljo3rapfXmeq+RyJ1AisZPf+Qy2tazXoIJZly/K4YMtjlh+bke2PGjMy3OWYOQvjf0qBIZ2aUGQKFnx7rrhrVVqnmO4hl2yZaJhe2WpJCsJKTSEpC4DELdVDaH2HE9x8rHhEARY5DAcjD73zLDDzSfgs6Epzgam6Hbr6mnUhagMQTwVSdenntnJEjho5pq1DMvUtOSBlxIvtEQ1z1RwHVBGTqi+Fpm/js1/bR2i9d83W6OICSocptc/k1sEQt2NU1R+2nlrAdtP9yz5GFkSeS0= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(36860700013)(376014)(1800799024)(82310400026);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Feb 2025 09:46:40.1297 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: b4726cd1-3726-406c-85c0-08dd57dccd2a 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CY4PEPF0000FCBE.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN0PR12MB6102 Add instruction deconding support for MMIO instruction decoding in SEV-ES VC handler path. For ease of review, file insn-eval.c is a snapshot of the file from arch/x86/lib/. It will be updated in subsequent commits with the modifications to just support minimal instruction deconding. Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/.gitignore | 3 +- .../testing/selftests/kvm/lib/x86/insn-eval.c | 1670 +++++++++++++++++ 2 files changed, 1672 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/kvm/lib/x86/insn-eval.c diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/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/lib/x86/insn-eval.c b/tools/testing/selftests/kvm/lib/x86/insn-eval.c new file mode 100644 index 000000000000..98631c0e7a11 --- /dev/null +++ b/tools/testing/selftests/kvm/lib/x86/insn-eval.c @@ -0,0 +1,1670 @@ +/* + * Utility functions for x86 operand and address decoding + * + * Copyright (C) Intel Corporation 2017 + */ +#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 = 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 != 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 == 0xf2 || p == 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, if 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 = INAT_SEG_REG_DEFAULT; + int num_overrides = 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 = inat_get_opcode_attribute(p); + switch (attr) { + case INAT_MAKE_PREFIX(INAT_PFX_CS): + idx = INAT_SEG_REG_CS; + num_overrides++; + break; + case INAT_MAKE_PREFIX(INAT_PFX_SS): + idx = INAT_SEG_REG_SS; + num_overrides++; + break; + case INAT_MAKE_PREFIX(INAT_PFX_DS): + idx = INAT_SEG_REG_DS; + num_overrides++; + break; + case INAT_MAKE_PREFIX(INAT_PFX_ES): + idx = INAT_SEG_REG_ES; + num_overrides++; + break; + case INAT_MAKE_PREFIX(INAT_PFX_FS): + idx = INAT_SEG_REG_FS; + num_overrides++; + break; + case INAT_MAKE_PREFIX(INAT_PFX_GS): + idx = 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, determine if + * segment override prefixes can be used. Specifically, no overrides are allowed + * for rDI if used with a string instruction. + * + * Returns: + * + * True if segment override prefixes can be used with the register indicated + * in @regoff. False if otherwise. + */ +static bool check_seg_overrides(struct insn *insn, int regoff) +{ + if (regoff == offsetof(struct pt_regs, di) && is_string_insn(insn)) + return false; + + return true; +} + +/** + * resolve_default_seg() - resolve default segment register index for an operand + * @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 instruction + * operand register indicated by @off. Such index is resolved based on defaults + * described in the Intel Software Development Manual. + * + * Returns: + * + * If in protected mode, a constant identifying the segment register to use, + * 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, int 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 == 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, except + * 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 prefixes. + * + * d) If there are not segment override prefixes or they cannot be used, the + * default segment register associated with the operand register is used. + * + * 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, resolve + * 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 operations + * are done using helper functions. + * + * The operand register, @regoff, is represented as the offset from the base of + * pt_regs. + * + * As stated, the main use of this function is to determine the segment register + * index based on the instruction, its operands and prefixes. Hence, @insn + * must be valid. However, if @regoff indicates rIP, we don't need to inspect + * @insn at all as in this case CS is used in all cases. This case is checked + * 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 regoff) +{ + 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 == 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 = get_seg_reg_override_idx(insn); + if (idx < 0) + return idx; + + if (idx == 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 != INAT_SEG_REG_FS && + idx != INAT_SEG_REG_GS) + idx = 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 segment + * registers. In CONFIG_X86_32, the segment is obtained from either pt_regs 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 segment + * 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 = (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[] = { + 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 = ARRAY_SIZE(pt_regoff); + int regno = 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 -= 8; + + switch (type) { + case REG_TYPE_RM: + regno = X86_MODRM_RM(insn->modrm.value); + + /* + * ModRM.mod == 0 and ModRM.rm == 5 means a 32-bit displacement + * follows the ModRM byte. + */ + if (!X86_MODRM_MOD(insn->modrm.value) && regno == 5) + return -EDOM; + + if (X86_REX_B(insn->rex_prefix.value)) + regno += 8; + break; + + case REG_TYPE_REG: + regno = X86_MODRM_REG(insn->modrm.value); + + if (X86_REX_R(insn->rex_prefix.value)) + regno += 8; + break; + + case REG_TYPE_INDEX: + regno = X86_SIB_INDEX(insn->sib.value); + if (X86_REX_X(insn->rex_prefix.value)) + regno += 8; + + /* + * If ModRM.mod != 3 and SIB.index = 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) != 3 && regno == 4) + return -EDOM; + break; + + case REG_TYPE_BASE: + regno = X86_SIB_BASE(insn->sib.value); + /* + * If ModRM.mod is 0 and SIB.base == 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 == 5) + return -EDOM; + + if (X86_REX_B(insn->rex_prefix.value)) + regno += 8; + break; + + default: + pr_err_ratelimited("invalid register type: %d\n", type); + return -EINVAL; + } + + if (regno >= 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 = 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[] = { + 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[] = { + 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) == 3) { + *offs1 = insn_get_modrm_rm_off(insn, regs); + *offs2 = -EDOM; + return 0; + } + + *offs1 = regoff1[X86_MODRM_RM(insn->modrm.value)]; + *offs2 = 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) == 0) && + (X86_MODRM_RM(insn->modrm.value) == 6)) + *offs1 = -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 = {0, 0}; + unsigned long desc_base; + +#ifdef CONFIG_MODIFY_LDT_SYSCALL + if ((sel & SEGMENT_TI_MASK) == SEGMENT_LDT) { + bool success = false; + struct ldt_struct *ldt; + + /* Bits [15:3] contain the index of the desired entry. */ + sel >>= 3; + + mutex_lock(¤t->active_mm->context.lock); + ldt = current->active_mm->context.ldt; + if (ldt && sel < ldt->nr_entries) { + *out = ldt->entries[sel]; + success = true; + } + + mutex_unlock(¤t->active_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 = sel & ~(SEGMENT_RPL_MASK | SEGMENT_TI_MASK); + + if (desc_base > gdt_desc.size) + return false; + + *out = *(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 descriptor + * 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 = 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 == INAT_SEG_REG_FS) { + rdmsrl(MSR_FS_BASE, base); + } else if (seg_reg_idx == 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)) + rdmsrl(MSR_KERNEL_GS_BASE, base); + else + rdmsrl(MSR_GS_BASE, base); + } else { + base = 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. Thus, + * 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 = 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 = get_desc_limit(&desc); + if (desc.g) + limit = (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 from the + * selector contained in the CS register in regs. In protected mode, the default + * 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 both + * 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 = 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=0, CS.D=0. Address and operand size are + * both 16-bit. + */ + return INSN_CODE_SEG_PARAMS(2, 2); + case 1: /* + * Legacy mode. CS.L=0, CS.D=1. Address and operand size are + * both 32-bit. + */ + return INSN_CODE_SEG_PARAMS(4, 4); + case 2: /* + * IA-32e 64-bit mode. CS.L=1, CS.D=0. Address size is 64-bit; + * operand size is 32-bit. + */ + return INSN_CODE_SEG_PARAMS(4, 8); + case 3: /* Invalid setting. CS.L=1, CS.D=1 */ + 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 *regs) +{ + int offset; + + offset = 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 operand + * @regoff and, if any or allowed, override prefixes in @insn. This function is + * different from insn_get_seg_base() as the latter does not resolve the segment + * 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 = resolve_seg_reg(insn, regs, regoff); + if (seg_reg_idx < 0) + return seg_reg_idx; + + *base = insn_get_seg_base(regs, seg_reg_idx); + if (*base == -1L) + return -EINVAL; + + if (!limit) + return 0; + + *limit = 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 indicated by + * the ModRM byte. This function is to be used only with register addressing + * (i.e., ModRM.mod is 3). The effective address is saved in @eff_addr. The + * register operand, as an offset from the base of pt_regs, is saved in @regoff; + * 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 sizes + * 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 = insn_get_modrm(insn); + if (ret) + return ret; + + if (X86_MODRM_MOD(insn->modrm.value) != 3) + return -EINVAL; + + *regoff = 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 == 2) + *eff_addr = regs_get_register(regs, *regoff) & 0xffff; + else if (insn->addr_bytes == 4) + *eff_addr = regs_get_register(regs, *regoff) & 0xffffffff; + else /* 64-bit address */ + *eff_addr = 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. After + * identifying the registers involved in the register-indirect memory reference, + * its value is obtained from the operands in @regs. The computed address is + * stored @eff_addr. Also, the register operand that indicates the associated + * segment is stored in @regoff, this parameter can later be used to determine + * such segment. + * + * Returns: + * + * 0 on success. @eff_addr will have the referenced effective address. @regoff + * will have a register, as an offset from the base of pt_regs, that can be 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 != 8 && insn->addr_bytes != 4) + return -EINVAL; + + ret = insn_get_modrm(insn); + if (ret) + return ret; + + if (X86_MODRM_MOD(insn->modrm.value) > 2) + return -EINVAL; + + *regoff = 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 == -EDOM) { + if (any_64bit_mode(regs)) + tmp = regs->ip + insn->length; + else + tmp = 0; + } else if (*regoff < 0) { + return -EINVAL; + } else { + tmp = regs_get_register(regs, *regoff); + } + + if (insn->addr_bytes == 4) { + int addr32 = (int)(tmp & 0xffffffff) + insn->displacement.value; + + *eff_addr = addr32 & 0xffffffff; + } else { + *eff_addr = 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 @insn. + * After identifying the registers involved in the register-indirect memory + * reference, its value is obtained from the operands in @regs. The computed + * address is stored @eff_addr. Also, the register operand that indicates + * the associated segment is stored in @regoff, this parameter can later be used + * to determine such segment. + * + * Returns: + * + * 0 on success. @eff_addr will have the referenced effective address. @regoff + * will have a register, as an offset from the base of pt_regs, that can be 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 = 0, addr2 = 0, displacement; + + if (insn->addr_bytes != 2) + return -EINVAL; + + insn_get_modrm(insn); + + if (!insn->modrm.nbytes) + return -EINVAL; + + if (X86_MODRM_MOD(insn->modrm.value) > 2) + return -EINVAL; + + ret = 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 != -EDOM) + addr1 = regs_get_register(regs, addr_offset1) & 0xffff; + + if (addr_offset2 != -EDOM) + addr2 = regs_get_register(regs, addr_offset2) & 0xffff; + + displacement = insn->displacement.value & 0xffff; + *eff_addr = 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 = 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 segment + * @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 memory + * reference, its value is obtained from the operands in @regs. The computed + * 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_regs, + * 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 != 8 && insn->addr_bytes != 4) + return -EINVAL; + + ret = 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 = insn_get_sib(insn); + if (ret) + return ret; + + if (!insn->sib.nbytes) + return -EINVAL; + + *base_offset = get_reg_offset(insn, regs, REG_TYPE_BASE); + indx_offset = 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 == -EDOM) + base = 0; + else if (*base_offset < 0) + return -EINVAL; + else + base = regs_get_register(regs, *base_offset); + + if (indx_offset == -EDOM) + indx = 0; + else if (indx_offset < 0) + return -EINVAL; + else + indx = regs_get_register(regs, indx_offset); + + if (insn->addr_bytes == 4) { + int addr32, base32, idx32; + + base32 = base & 0xffffffff; + idx32 = indx & 0xffffffff; + + addr32 = base32 + idx32 * (1 << X86_SIB_SCALE(insn->sib.value)); + addr32 += insn->displacement.value; + + *eff_addr = addr32 & 0xffffffff; + } else { + *eff_addr = base + indx * (1 << X86_SIB_SCALE(insn->sib.value)); + *eff_addr += 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 memory + * address referred by the instruction's ModRM and displacement bytes. Also, the + * segment used as base is determined by either any segment override prefixes 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 *regs) +{ + unsigned long linear_addr = -1L, seg_base, seg_limit; + int ret, regoff; + short eff_addr; + long tmp; + + if (insn_get_displacement(insn)) + goto out; + + if (insn->addr_bytes != 2) + goto out; + + if (X86_MODRM_MOD(insn->modrm.value) == 3) { + ret = get_eff_addr_reg(insn, regs, ®off, &tmp); + if (ret) + goto out; + + eff_addr = tmp; + } else { + ret = get_eff_addr_modrm_16(insn, regs, ®off, &eff_addr); + if (ret) + goto out; + } + + ret = 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 = (unsigned long)(eff_addr & 0xffff) + seg_base; + + /* Limit linear address to 20 bits */ + if (v8086_mode(regs)) + linear_addr &= 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 protected + * 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 *regs) +{ + unsigned long linear_addr = -1L, seg_base, seg_limit; + int eff_addr, regoff; + long tmp; + int ret; + + if (insn->addr_bytes != 4) + goto out; + + if (X86_MODRM_MOD(insn->modrm.value) == 3) { + ret = get_eff_addr_reg(insn, regs, ®off, &tmp); + if (ret) + goto out; + + eff_addr = tmp; + + } else { + if (insn->sib.nbytes) { + ret = get_eff_addr_sib(insn, regs, ®off, &tmp); + if (ret) + goto out; + + eff_addr = tmp; + } else { + ret = get_eff_addr_modrm(insn, regs, ®off, &tmp); + if (ret) + goto out; + + eff_addr = tmp; + } + } + + ret = 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 = (unsigned long)(eff_addr & 0xffffffff) + seg_base; + + /* Limit linear address to 20 bits */ + if (v8086_mode(regs)) + linear_addr &= 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 *regs) +{ + return (void __user *)-1L; +} +#else +static void __user *get_addr_ref_64(struct insn *insn, struct pt_regs *regs) +{ + unsigned long linear_addr = -1L, seg_base; + int regoff, ret; + long eff_addr; + + if (insn->addr_bytes != 8) + goto out; + + if (X86_MODRM_MOD(insn->modrm.value) == 3) { + ret = get_eff_addr_reg(insn, regs, ®off, &eff_addr); + if (ret) + goto out; + + } else { + if (insn->sib.nbytes) { + ret = get_eff_addr_sib(insn, regs, ®off, &eff_addr); + if (ret) + goto out; + } else { + ret = get_eff_addr_modrm(insn, regs, ®off, &eff_addr); + if (ret) + goto out; + } + + } + + ret = get_seg_base_limit(insn, regs, regoff, &seg_base, NULL); + if (ret) + goto out; + + linear_addr = (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 = 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 = insn_get_seg_base(regs, INAT_SEG_REG_CS); + if (seg_base == -1L) + return -EINVAL; + } + + *ip = 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 bytes + * 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 calculated + */ +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 = 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-space 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 bytes + * 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 calculated. + */ +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 = __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 = insn_get_code_seg_params(regs); + if (seg_defs == -EINVAL) + return false; + + insn->addr_bytes = INSN_CODE_SEG_ADDR_SZ(seg_defs); + insn->opnd_bytes = 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 = INSN_MMIO_DECODE_FAILED; + + *bytes = 0; + + if (insn_get_opcode(insn)) + return INSN_MMIO_DECODE_FAILED; + + switch (insn->opcode.bytes[0]) { + case 0x88: /* MOV m8,r8 */ + *bytes = 1; + fallthrough; + case 0x89: /* MOV m16/m32/m64, r16/m32/m64 */ + if (!*bytes) + *bytes = insn->opnd_bytes; + type = INSN_MMIO_WRITE; + break; + + case 0xc6: /* MOV m8, imm8 */ + *bytes = 1; + fallthrough; + case 0xc7: /* MOV m16/m32/m64, imm16/imm32/imm64 */ + if (!*bytes) + *bytes = insn->opnd_bytes; + type = INSN_MMIO_WRITE_IMM; + break; + + case 0x8a: /* MOV r8, m8 */ + *bytes = 1; + fallthrough; + case 0x8b: /* MOV r16/r32/r64, m16/m32/m64 */ + if (!*bytes) + *bytes = insn->opnd_bytes; + type = INSN_MMIO_READ; + break; + + case 0xa4: /* MOVS m8, m8 */ + *bytes = 1; + fallthrough; + case 0xa5: /* MOVS m16/m32/m64, m16/m32/m64 */ + if (!*bytes) + *bytes = insn->opnd_bytes; + type = INSN_MMIO_MOVS; + break; + + case 0x0f: /* Two-byte instruction */ + switch (insn->opcode.bytes[1]) { + case 0xb6: /* MOVZX r16/r32/r64, m8 */ + *bytes = 1; + fallthrough; + case 0xb7: /* MOVZX r32/r64, m16 */ + if (!*bytes) + *bytes = 2; + type = INSN_MMIO_READ_ZERO_EXTEND; + break; + + case 0xbe: /* MOVSX r16/r32/r64, m8 */ + *bytes = 1; + fallthrough; + case 0xbf: /* MOVSX r32/r64, m16 */ + if (!*bytes) + *bytes = 2; + type = INSN_MMIO_READ_SIGN_EXTEND; + break; + } + break; + } + + return type; +} From patchwork Fri Feb 28 09:30:06 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996047 Received: from NAM11-CO1-obe.outbound.protection.outlook.com (mail-co1nam11on2086.outbound.protection.outlook.com [40.107.220.86]) (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 6006724A046; Fri, 28 Feb 2025 09:47:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.220.86 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736029; cv=fail; b=BFunhyhEPMLIRlbbeBeKaVvQmeb8CFDIEgCcIF+aI7pj9qHm9rDBJr4JTgQfvNQDHOxhXE68wgTLpxvhVrFxVKjIHfgvuUBRlexWIv361JqrU63W9+B1TXx9PqzcgwnzUYTVZv74bZlQyopp8nH673mWh2C8c10Zi9W08gQ9hxM= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736029; c=relaxed/simple; bh=FXVh/zuHDRHbPOa6+9mMlgbu3VuCcYOPqoExnVyUDik=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=UPub67H54YV43hIEiyGfGhd1ERDH98LQyPjEl1uvAzgPT1YYsUHzv1MWB4HSKvB3kKge6nk8DRdmjWrz+/NiQ7KiOL3+kWCWfjOgLsMGTOfh8VTc5wdzHA++eR6Qx0kLXByFcY3PKEQTXpwQsdPTjhyEkfl6Hs08NwaOsKHHycg= 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=gUDhlWRp; arc=fail smtp.client-ip=40.107.220.86 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="gUDhlWRp" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=pHwZIccdeAAlhsknP+KXG9gtHLxtYFOHdAk/h6XGoZHRKY0aaEUCqrf04A0wItrETW5fGIcpBEAV9UeYMGwvjwo9KlX+GbzMlNHnFZBKL4FOIMBBdqFJcsxtnTkiZHqpY5RAbrHZLPp4JnnWSZdjZ84y53dwSNqRrIAW5fyh4GU1iSzrXqtHs/XSi7P6d+xLZUh3v+KwKayB13G3L4ehX9QtGIa/JNN9TsK2uA9irKnSR+XZVyx/kRXs4dLhsR4JHyMDXW8ksAfaIufE0DzbsZy/i0yKoguNIOzPpO4KZL21BIskWERu0ScT5xiqa7kFJhufEm5kCQHKOzsuqfue6w== 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=U6vnjCrD/2UqBEd6FjHRpFaruWh9l1c8uXOm6CBKRdg=; b=KqIyjzOTdS+EQxsn/JKZBeReRVA65sU6Kny/495lxbFIbQvNSi39x3S8Vj8nDRPoRbQZKRYu+Ge1RsXbeojpSf2cXp2rkGgJ32QbVdT0LTwh24nx5W+b3P32WhbwK+//gXokz6HA2q9RjNCLof9/RW+7fuZLR9fln8+PHIsKqQ+Eh0oMLs6GSTCwqQGiuEOyzHoJ7koCX2X39C1SDjre5kl69deBRNBb7jxzr13jKC6UMROumGI1tKrOlW875esu7zQxMbqW67b0NBJxeP832VVpibQMsVIORDAUbCUKXzz2OOOCeTROMZCX9jTvFwR7nenQLtnJu0s2ZJ1BowWfCw== 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=U6vnjCrD/2UqBEd6FjHRpFaruWh9l1c8uXOm6CBKRdg=; b=gUDhlWRp8ruvspMgoyNc61KicS6P7WeQcEfTUbKAYG0cndhyyebTqLz06bvgGQ2vzPic0VDcUX7X51dt6bzdnwGQL9C9C4NsObg0U9oaPS145HkjtphhMgyOIbqr2rIXmWLLagrHdOqklxWeJyvUjjj0rY0p19bwMV1YfWSLjdQ= Received: from PH7PR17CA0020.namprd17.prod.outlook.com (2603:10b6:510:324::11) by IA1PR12MB6306.namprd12.prod.outlook.com (2603:10b6:208:3e6::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8466.20; Fri, 28 Feb 2025 09:46:59 +0000 Received: from CY4PEPF0000FCBF.namprd03.prod.outlook.com (2603:10b6:510:324:cafe::d5) by PH7PR17CA0020.outlook.office365.com (2603:10b6:510:324::11) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.23 via Frontend Transport; Fri, 28 Feb 2025 09:46: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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by CY4PEPF0000FCBF.mail.protection.outlook.com (10.167.242.101) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 09:46:58 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:46:52 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 13/31] KVM: selftests: Add instruction decoding support Date: Fri, 28 Feb 2025 15:00:06 +0530 Message-ID: <20250228093024.114983-14-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY4PEPF0000FCBF:EE_|IA1PR12MB6306:EE_ X-MS-Office365-Filtering-Correlation-Id: b2b244cb-e1e8-477a-729b-08dd57dcd865 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: K0UOuutW4lFWk9snXIwMb0cxqhUX34sdEKo8uOaWZLVjBWjTMmgGPWt6O985t92p3mgNueUjpshxNzoMJY5E1tGoZV+1d21tfYFY+mnVSkbbuYpYik5TY6OZd9p3auDRb5/9YiumO0gtPWy84MjM4Gzmat/iIWbLhzp/9TM5vmQgsq8vO4iDqofzyIV5eQ61M599xDIc9D41KPu5wLhaZ0jzX1CSf7T4jc8qbuPjlJlOwUxWSe8IBEpQWBFNWCePokxbCZhW2CEx0YYt/zSIH1FDw2HsjUou02f+//oWcB021t7EKat+PCPFgiVnYKPeyh+lZTSXTbxcx2lChm1fRcSutVZai03WJFAAH95mzpca9lFQtdRrZIMGl3DLbC8xsCXrh08+AdwwDeGf3z4L9B4b9QaoJE4VuUzR7WfLq+8lvgG5BlfzAPR4dGGIfz5TypneP3hO+J3yFxPvffwThvaEGRElecZW4ygElf3KzlVTROir2KvRDSNupFfkMYsQlIdZTW85vzLHemimS11XSKt6K1MrccVDHOzNcCZqkYzVXX/eMGQp6avekdexg/i4OTKP80KYYX+PEAGpRlwQc5zidMKHpI9vkgO14VBQF4rQXYTexa3cNod1/aY0cMgrJzJrT9MWl5nFeh3yOfvn3isXj1S9T5nrKyrPC5TTrksG1ZNPixCqQjQIPp4CFavWNu+BY4G5Rz7jHTgeiuyu1CGb1Ttne3uqZREspJCXpsBziuhm21LMyPhIEhZ+1+Rdu+UphndxEyV6BQNg5wA06xXzHXN5JF/pgIJ765VdXhhhU6I3PpqYd5MLdcRS1wgUrZMss31RP9UcqShmNEn2DgFclBNAnWZP2lGp16KbeHl5Ej34EjcrQDZSgeY5zHbslVU4uPkGYWiBrKzQivgbsaJHqN6O2YZ0rGTWEdPraHLYBU+xwseA7ba+TdnYr0shanTSEDQ3toECzOlmOHRNvDOa4MxzvmZBpGBImIcSZP31rkwUK6s4WcJqZsvqEphF/dF06lZ1ZWEEvZk6qonltj1CflWFCzgWGLu3ygBopu2jeMFcNQLShxQxQWEw14xJY4ddui9QcBY9FGbSFfDTmpsiW5UQgNHX6LXAMbvLmwm/EGS+pZM6bvb/7zxD1hy6RCs+t4ev+FVZpfYF2Fkx3lEdFrgJOpDSqTxzICLZDYXbCjSntHszfSQ+xx5d+wQH6r8X8A2ZiKHi9eTUB0Z2hoSHdu7tsZkneKg7d6Y1yiVfag3hWA25wdvUGC2lcAMYcYmAhvpC2YYi+B/xu6uxoTIitLY9nyDgtCBO7rdbFG++IcSOMYEeBHZcWFjh3l6/FbFK8JnGgnR7fEGmSEuoZqzyvbgPNG8Umb1UqpP3DYOR6rAupMUcLNoEzraSSTH7YQLK/Cf4GAg7FWecLw6xVmMRpnbQzjw/qrJLXS6yQwS9YpZ5gcAJbkf0RrA67BBVzVYwVKXsBm6oGymtOFSIuPFWSG1rIbrLh/nd3OzfwPA= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.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: 28 Feb 2025 09:46:58.9708 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: b2b244cb-e1e8-477a-729b-08dd57dcd865 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CY4PEPF0000FCBF.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA1PR12MB6306 Update insn-eval.c to prototype instruction decoding for MMIO VC exception exit. Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/Makefile.kvm | 12 + .../selftests/kvm/include/x86/ex_regs.h | 21 ++ .../selftests/kvm/include/x86/insn-eval.h | 48 ++++ .../selftests/kvm/include/x86/processor.h | 12 +- .../testing/selftests/kvm/lib/x86/insn-eval.c | 268 +++++++++++------- 5 files changed, 240 insertions(+), 121 deletions(-) create mode 100644 tools/testing/selftests/kvm/include/x86/ex_regs.h create mode 100644 tools/testing/selftests/kvm/include/x86/insn-eval.h diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm index b4894cb56861..5a67e79ae848 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -21,6 +21,7 @@ LIBKVM_STRING += lib/string_override.c LIBKVM_x86 += lib/x86/apic.c LIBKVM_x86 += lib/x86/handlers.S LIBKVM_x86 += lib/x86/hyperv.c +LIBKVM_x86 += lib/x86/insn-eval.c LIBKVM_x86 += lib/x86/memstress.c LIBKVM_x86 += lib/x86/pmu.c LIBKVM_x86 += lib/x86/processor.c @@ -238,6 +239,17 @@ ifeq ($(ARCH),x86) ifeq ($(shell echo "void foo(void) { }" | $(CC) -march=x86-64-v2 -x c - -c -o /dev/null 2>/dev/null; echo "$$?"),0) CFLAGS += -march=x86-64-v2 endif + +tools_lib_dir := $(top_srcdir)/tools/arch/x86/lib +inat_tables_script = $(top_srcdir)/tools/arch/x86/tools/gen-insn-attr-x86.awk +inat_tables_maps = $(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 += $(tools_lib_dir)/insn.c +LIBKVM_x86 += $(tools_lib_dir)/inat.c +EXTRA_CLEAN += $(tools_lib_dir)/inat-tables.c +EXTRA_CLEAN += $(tools_lib_dir)/insn.o +EXTRA_CLEAN += $(tools_lib_dir)/inat.o + endif ifeq ($(ARCH),arm64) tools_dir := $(top_srcdir)/tools diff --git a/tools/testing/selftests/kvm/include/x86/ex_regs.h b/tools/testing/selftests/kvm/include/x86/ex_regs.h new file mode 100644 index 000000000000..172cfbb0a2d0 --- /dev/null +++ b/tools/testing/selftests/kvm/include/x86/ex_regs.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2018, Google LLC. + */ + +#ifndef SELFTEST_KVM_EX_REGS_H +#define SELFTEST_KVM_EX_REG_H + +struct ex_regs { + uint64_t rax, rcx, rdx, rbx; + uint64_t rbp, rsi, rdi; + uint64_t r8, r9, r10, r11; + uint64_t r12, r13, r14, r15; + uint64_t vector; + uint64_t error_code; + uint64_t rip; + uint64_t cs; + uint64_t rflags; +}; + +#endif diff --git a/tools/testing/selftests/kvm/include/x86/insn-eval.h b/tools/testing/selftests/kvm/include/x86/insn-eval.h new file mode 100644 index 000000000000..0c7bad1c9215 --- /dev/null +++ b/tools/testing/selftests/kvm/include/x86/insn-eval.h @@ -0,0 +1,48 @@ +#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 "ex_regs.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)) + +int ex_regs_offset(struct ex_regs *regs, int regno); + +bool insn_has_rep_prefix(struct insn *insn); +void *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 *regs); +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 ex_regs *regs, + unsigned char buf[MAX_INSN_SIZE]); +bool insn_decode_from_regs(struct insn *insn, struct ex_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_WRITE_MOV_ABS, + INSN_MMIO_READ, + INSN_MMIO_READ_ZERO_EXTEND, + INSN_MMIO_READ_SIGN_EXTEND, + INSN_MMIO_MOVS, + INSN_MMIO_READ_MOV_ABS, +}; + +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/include/x86/processor.h b/tools/testing/selftests/kvm/include/x86/processor.h index 56029d07680a..3f9369644962 100644 --- a/tools/testing/selftests/kvm/include/x86/processor.h +++ b/tools/testing/selftests/kvm/include/x86/processor.h @@ -1145,17 +1145,7 @@ void kvm_get_cpu_address_width(unsigned int *pa_bits, unsigned int *va_bits); void kvm_init_vm_address_properties(struct kvm_vm *vm); bool vm_is_unrestricted_guest(struct kvm_vm *vm); -struct ex_regs { - uint64_t rax, rcx, rdx, rbx; - uint64_t rbp, rsi, rdi; - uint64_t r8, r9, r10, r11; - uint64_t r12, r13, r14, r15; - uint64_t vector; - uint64_t error_code; - uint64_t rip; - uint64_t cs; - uint64_t rflags; -}; +#include "ex_regs.h" struct idt_entry { uint16_t offset0; diff --git a/tools/testing/selftests/kvm/lib/x86/insn-eval.c b/tools/testing/selftests/kvm/lib/x86/insn-eval.c index 98631c0e7a11..efa4d3fde504 100644 --- a/tools/testing/selftests/kvm/lib/x86/insn-eval.c +++ b/tools/testing/selftests/kvm/lib/x86/insn-eval.c @@ -3,20 +3,29 @@ * * Copyright (C) Intel Corporation 2017 */ +#ifdef __KERNEL__ #include #include #include #include #include #include -#include -#include -#include #include #include +#else +#include +#include +#include +#include +#endif + +#include "kselftest.h" +#include "ucall_common.h" +#include +#include +#include "insn-eval.h" -#undef pr_fmt -#define pr_fmt(fmt) "insn: " fmt +#define CONFIG_X86_64 enum reg_type { REG_TYPE_RM = 0, @@ -140,7 +149,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, determine if * segment override prefixes can be used. Specifically, no overrides are allowed @@ -153,17 +162,22 @@ static int get_seg_reg_override_idx(struct insn *insn) */ static bool check_seg_overrides(struct insn *insn, int regoff) { - if (regoff == offsetof(struct pt_regs, di) && is_string_insn(insn)) + if (regoff == offsetof(struct ex_regs, rdi) && is_string_insn(insn)) return false; return true; } +static bool any_64bit_mode(struct ex_regs *regs) +{ + return true; +} + /** * resolve_default_seg() - resolve default segment register index for an operand * @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 instruction * operand register indicated by @off. Such index is resolved based on defaults @@ -176,10 +190,11 @@ 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, int off) +static int resolve_default_seg(struct insn *insn, struct ex_regs *regs, int off) { if (any_64bit_mode(regs)) return INAT_SEG_REG_IGNORE; +#ifndef CONFIG_X86_64 /* * Resolve the default segment register as described in Section 3.7.4 * of the Intel Software Development Manual Vol. 1: @@ -195,9 +210,9 @@ static int resolve_default_seg(struct insn *insn, struct pt_regs *regs, int off) */ switch (off) { - case offsetof(struct pt_regs, ax): - case offsetof(struct pt_regs, cx): - case offsetof(struct pt_regs, dx): + case offsetof(struct ex_regs, ax): + case offsetof(struct ex_regs, cx): + case offsetof(struct ex_regs, dx): /* Need insn to verify address size. */ if (insn->addr_bytes == 2) return -EINVAL; @@ -205,32 +220,34 @@ static int resolve_default_seg(struct insn *insn, struct pt_regs *regs, int off) fallthrough; case -EDOM: - case offsetof(struct pt_regs, bx): - case offsetof(struct pt_regs, si): + case offsetof(struct ex_regs, bx): + case offsetof(struct ex_regs, si): return INAT_SEG_REG_DS; - case offsetof(struct pt_regs, di): + case offsetof(struct ex_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): + case offsetof(struct ex_regs, bp): + case offsetof(struct ex_regs, sp): return INAT_SEG_REG_SS; - case offsetof(struct pt_regs, ip): + case offsetof(struct ex_regs, ip): return INAT_SEG_REG_CS; default: return -EINVAL; } +#endif + 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 + * @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. @@ -258,7 +275,7 @@ static int resolve_default_seg(struct insn *insn, struct pt_regs *regs, int off) * are done using helper functions. * * The operand register, @regoff, is represented as the offset from the base of - * pt_regs. + * ex_regs. * * As stated, the main use of this function is to determine the segment register * index based on the instruction, its operands and prefixes. Hence, @insn @@ -278,7 +295,7 @@ static int resolve_default_seg(struct insn *insn, struct pt_regs *regs, int off) * * -EINVAL in case of error. */ -static int resolve_seg_reg(struct insn *insn, struct pt_regs *regs, int regoff) +static int resolve_seg_reg(struct insn *insn, struct ex_regs *regs, int regoff) { int idx; @@ -288,7 +305,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 == offsetof(struct pt_regs, ip)) { + if (regoff == offsetof(struct ex_regs, rip)) { if (any_64bit_mode(regs)) return INAT_SEG_REG_IGNORE; else @@ -327,9 +344,9 @@ 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 segment - * registers. In CONFIG_X86_32, the segment is obtained from either pt_regs or + * registers. In CONFIG_X86_32, the segment is obtained from either ex_regs 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 + * from ex_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 segment * registers are ignored. * @@ -340,9 +357,9 @@ 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; + //unsigned short sel; #ifdef CONFIG_X86_64 switch (seg_reg_idx) { @@ -350,8 +367,9 @@ static short get_segment_selector(struct pt_regs *regs, int seg_reg_idx) return 0; case INAT_SEG_REG_CS: return (unsigned short)(regs->cs & 0xffff); +#if 0 case INAT_SEG_REG_SS: - return (unsigned short)(regs->ss & 0xffff); + return (unsigned short)(regs->cs & 0xffff); case INAT_SEG_REG_DS: savesegment(ds, sel); return sel; @@ -364,6 +382,7 @@ static short get_segment_selector(struct pt_regs *regs, int seg_reg_idx) case INAT_SEG_REG_GS: savesegment(gs, sel); return sel; +#endif default: return -EINVAL; } @@ -412,32 +431,32 @@ static short get_segment_selector(struct pt_regs *regs, int seg_reg_idx) } static const int pt_regoff[] = { - 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 ex_regs, rax), + offsetof(struct ex_regs, rcx), + offsetof(struct ex_regs, rdx), + offsetof(struct ex_regs, rbx), + offsetof(struct ex_regs, rbx), // ex_regs->sp not declared + offsetof(struct ex_regs, rbp), + offsetof(struct ex_regs, rsi), + offsetof(struct ex_regs, rdi), #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), + 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), #else - offsetof(struct pt_regs, ds), - offsetof(struct pt_regs, es), - offsetof(struct pt_regs, fs), - offsetof(struct pt_regs, gs), + offsetof(struct ex_regs, ds), + offsetof(struct ex_regs, es), + offsetof(struct ex_regs, fs), + offsetof(struct ex_regs, gs), #endif }; -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]; @@ -453,8 +472,10 @@ static int get_regno(struct insn *insn, enum reg_type type) * Don't possibly decode a 32-bit instructions as * reading a 64-bit-only register. */ +#if 0 if (IS_ENABLED(CONFIG_X86_64) && !insn->x86_64) nr_registers -= 8; +#endif switch (type) { case REG_TYPE_RM: @@ -508,18 +529,18 @@ static int get_regno(struct insn *insn, enum reg_type type) break; default: - pr_err_ratelimited("invalid register type: %d\n", type); + __GUEST_ASSERT(0, "invalid register type: %d\n", type); return -EINVAL; } if (regno >= nr_registers) { - WARN_ONCE(1, "decoded an instruction with an invalid register"); + __GUEST_ASSERT(0, "decoded an instruction with an invalid register"); return -EINVAL; } return regno; } -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 = get_regno(insn, type); @@ -527,7 +548,7 @@ static int get_reg_offset(struct insn *insn, struct pt_regs *regs, if (regno < 0) return regno; - return pt_regs_offset(regs, regno); + return ex_regs_offset(regs, regno); } /** @@ -537,7 +558,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 @@ -547,7 +568,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) { /* @@ -556,21 +577,21 @@ static int get_reg_offset_16(struct insn *insn, struct pt_regs *regs, * ModR/M Byte" of the Intel Software Development Manual. */ static const int regoff1[] = { - 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), }; static const int regoff2[] = { - 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, @@ -604,6 +625,7 @@ static int get_reg_offset_16(struct insn *insn, struct pt_regs *regs, return 0; } +#ifndef CONFIG_X86_64 /** * get_desc() - Obtain contents of a segment descriptor * @out: Segment descriptor contents on success @@ -660,6 +682,7 @@ static bool get_desc(struct desc_struct *out, unsigned short sel) *out = *(struct desc_struct *)(gdt_desc.address + desc_base); return true; } +#endif /** * insn_get_seg_base() - Obtain base address of segment descriptor. @@ -678,21 +701,23 @@ static bool get_desc(struct desc_struct *out, unsigned short sel) * * -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) { - struct desc_struct desc; + // struct desc_struct desc; short sel; sel = get_segment_selector(regs, seg_reg_idx); if (sel < 0) return -1L; +#ifndef CONFIG_X86_64 if (v8086_mode(regs)) /* * Base is simply the segment selector shifted 4 * bits to the right. */ return (unsigned long)(sel << 4); +#endif if (any_64bit_mode(regs)) { /* @@ -701,6 +726,7 @@ unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx) */ unsigned long base; +#ifndef CONFIG_X86_64 if (seg_reg_idx == INAT_SEG_REG_FS) { rdmsrl(MSR_FS_BASE, base); } else if (seg_reg_idx == INAT_SEG_REG_GS) { @@ -713,11 +739,15 @@ unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx) else rdmsrl(MSR_GS_BASE, base); } else { +#endif base = 0; +#ifndef CONFIG_X86_64 } +#endif return base; } +#ifndef CONFIG_X86_64 /* In protected mode the segment selector cannot be null. */ if (!sel) return -1L; @@ -726,6 +756,8 @@ unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx) return -1L; return get_desc_base(&desc); +#endif + return -1L; } /** @@ -745,9 +777,13 @@ unsigned long insn_get_seg_base(struct pt_regs *regs, int 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) { + if (any_64bit_mode(regs)) + return -1L; +#ifndef CONFIG_X86_64 struct desc_struct desc; + unsigned long limit; short sel; @@ -775,8 +811,11 @@ static unsigned long get_seg_limit(struct pt_regs *regs, int seg_reg_idx) limit = (limit << 12) + 0xfff; return limit; +#endif + return -1L; } +#ifndef CONFIG_X86_64 /** * insn_get_code_seg_params() - Obtain code segment parameters * @regs: Structure with register values as seen when entering kernel mode @@ -793,7 +832,7 @@ static unsigned long get_seg_limit(struct pt_regs *regs, int seg_reg_idx) * * -EINVAL on error. */ -int insn_get_code_seg_params(struct pt_regs *regs) +int insn_get_code_seg_params(struct ex_regs *regs) { struct desc_struct desc; short sel; @@ -834,11 +873,11 @@ int insn_get_code_seg_params(struct pt_regs *regs) */ return INSN_CODE_SEG_PARAMS(4, 8); case 3: /* Invalid setting. CS.L=1, CS.D=1 */ - fallthrough; default: return -EINVAL; } } +#endif /** * insn_get_modrm_rm_off() - Obtain register in r/m part of the ModRM byte @@ -848,11 +887,11 @@ int insn_get_code_seg_params(struct pt_regs *regs) * 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 + * register is obtained as an offset from the base of ex_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) +int insn_get_modrm_rm_off(struct insn *insn, struct ex_regs *regs) { return get_reg_offset(insn, regs, REG_TYPE_RM); } @@ -865,9 +904,9 @@ int insn_get_modrm_rm_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 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); } @@ -880,9 +919,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 *regs) +unsigned long *insn_get_modrm_reg_ptr(struct insn *insn, struct ex_regs *regs) { int offset; @@ -896,7 +935,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 * @@ -913,7 +952,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) { @@ -940,17 +979,23 @@ static int get_seg_base_limit(struct insn *insn, struct pt_regs *regs, return 0; } +static inline unsigned long regs_get_register(struct ex_regs *regs, + unsigned int offset) +{ + return *(unsigned long *)((unsigned long)regs + offset); +} + /** * 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 indicated by * the ModRM byte. This function is to be used only with register addressing * (i.e., ModRM.mod is 3). The effective address is saved in @eff_addr. The - * register operand, as an offset from the base of pt_regs, is saved in @regoff; + * register operand, as an offset from the base of ex_regs, is saved in @regoff; * 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 sizes * in x86. @@ -959,11 +1004,11 @@ static int get_seg_base_limit(struct insn *insn, struct 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; @@ -994,7 +1039,7 @@ static int get_eff_addr_reg(struct insn *insn, struct pt_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. After @@ -1007,12 +1052,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. @regoff - * will have a register, as an offset from the base of pt_regs, that can be used + * will have a register, as an offset from the base of ex_regs, that can be 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; @@ -1037,7 +1082,7 @@ static int get_eff_addr_modrm(struct insn *insn, struct pt_regs *regs, */ if (*regoff == -EDOM) { if (any_64bit_mode(regs)) - tmp = regs->ip + insn->length; + tmp = regs->rip + insn->length; else tmp = 0; } else if (*regoff < 0) { @@ -1061,7 +1106,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 @insn. @@ -1074,12 +1119,12 @@ static int get_eff_addr_modrm(struct insn *insn, struct pt_regs *regs, * Returns: * * 0 on success. @eff_addr will have the referenced effective address. @regoff - * will have a register, as an offset from the base of pt_regs, that can be used + * will have a register, as an offset from the base of ex_regs, that can be 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; @@ -1129,7 +1174,7 @@ static int get_eff_addr_modrm_16(struct insn *insn, struct 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 segment + * @base_offset: Obtained operand offset, in ex_regs, associated with segment * @eff_addr: Obtained effective address * * Obtain the effective address referenced by the SIB byte of @insn. After @@ -1142,12 +1187,12 @@ static int get_eff_addr_modrm_16(struct insn *insn, struct 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_regs, + * @base_offset will have a register, as an offset from the base of ex_regs, * 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; @@ -1231,7 +1276,7 @@ static int get_eff_addr_sib(struct insn *insn, struct pt_regs *regs, * * -1L on error. */ -static void __user *get_addr_ref_16(struct insn *insn, struct pt_regs *regs) +static void __user *get_addr_ref_16(struct insn *insn, struct ex_regs *regs) { unsigned long linear_addr = -1L, seg_base, seg_limit; int ret, regoff; @@ -1271,9 +1316,11 @@ static void __user *get_addr_ref_16(struct insn *insn, struct pt_regs *regs) linear_addr = (unsigned long)(eff_addr & 0xffff) + seg_base; +#ifndef CONFIG_X86_64 /* Limit linear address to 20 bits */ if (v8086_mode(regs)) linear_addr &= 0xfffff; +#endif out: return (void __user *)linear_addr; @@ -1295,7 +1342,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 *regs) +static void __user *get_addr_ref_32(struct insn *insn, struct ex_regs *regs) { unsigned long linear_addr = -1L, seg_base, seg_limit; int eff_addr, regoff; @@ -1346,12 +1393,14 @@ static void __user *get_addr_ref_32(struct insn *insn, struct pt_regs *regs) if (!any_64bit_mode(regs) && ((unsigned int)eff_addr > seg_limit)) goto out; +#ifndef CONFIG_X86_64 /* * 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; +#endif /* * Data type long could be 64 bits in size. Ensure that our 32-bit @@ -1361,8 +1410,10 @@ static void __user *get_addr_ref_32(struct insn *insn, struct pt_regs *regs) linear_addr = (unsigned long)(eff_addr & 0xffffffff) + seg_base; /* Limit linear address to 20 bits */ +#ifndef CONFIG_X86_64 if (v8086_mode(regs)) linear_addr &= 0xfffff; +#endif out: return (void __user *)linear_addr; @@ -1384,12 +1435,12 @@ static void __user *get_addr_ref_32(struct insn *insn, struct pt_regs *regs) * -1L on error. */ #ifndef CONFIG_X86_64 -static void __user *get_addr_ref_64(struct insn *insn, struct pt_regs *regs) +static void __user *get_addr_ref_64(struct insn *insn, struct ex_regs *regs) { return (void __user *)-1L; } #else -static void __user *get_addr_ref_64(struct insn *insn, struct pt_regs *regs) +static void __user *get_addr_ref_64(struct insn *insn, struct ex_regs *regs) { unsigned long linear_addr = -1L, seg_base; int regoff, ret; @@ -1442,7 +1493,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; @@ -1462,7 +1513,7 @@ void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs) } } -int insn_get_effective_ip(struct pt_regs *regs, unsigned long *ip) +int insn_get_effective_ip(struct ex_regs *regs, unsigned long *ip) { unsigned long seg_base = 0; @@ -1472,17 +1523,18 @@ int insn_get_effective_ip(struct pt_regs *regs, unsigned long *ip) * 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)) { + if (0) { //(!user_64bit_mode(regs)) { seg_base = insn_get_seg_base(regs, INAT_SEG_REG_CS); if (seg_base == -1L) return -EINVAL; } - *ip = seg_base + regs->ip; + *ip = seg_base + regs->rip; return 0; } +#if 0 /** * insn_fetch_from_user() - Copy instruction bytes from user-space memory * @regs: Structure with register values as seen when entering kernel mode @@ -1497,7 +1549,7 @@ int insn_get_effective_ip(struct pt_regs *regs, unsigned long *ip) * - 0 if nothing was copied. * - -EINVAL if the linear address of the instruction could not be calculated */ -int insn_fetch_from_user(struct pt_regs *regs, unsigned char buf[MAX_INSN_SIZE]) +int insn_fetch_from_user(struct ex_regs *regs, unsigned char buf[MAX_INSN_SIZE]) { unsigned long ip; int not_copied; @@ -1525,7 +1577,7 @@ int insn_fetch_from_user(struct pt_regs *regs, unsigned char buf[MAX_INSN_SIZE]) * - 0 if nothing was copied. * - -EINVAL if the linear address of the instruction could not be calculated. */ -int insn_fetch_from_user_inatomic(struct pt_regs *regs, unsigned char buf[MAX_INSN_SIZE]) +int insn_fetch_from_user_inatomic(struct ex_regs *regs, unsigned char buf[MAX_INSN_SIZE]) { unsigned long ip; int not_copied; @@ -1537,7 +1589,6 @@ int insn_fetch_from_user_inatomic(struct pt_regs *regs, unsigned char buf[MAX_IN return MAX_INSN_SIZE - not_copied; } - /** * insn_decode_from_regs() - Decode an instruction * @insn: Structure to store decoded instruction @@ -1552,12 +1603,12 @@ int insn_fetch_from_user_inatomic(struct pt_regs *regs, unsigned char buf[MAX_IN * * True if instruction was decoded, False otherwise. */ -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) { int seg_defs; - insn_init(insn, buf, buf_size, user_64bit_mode(regs)); + insn_init(insn, buf, buf_size, 1); //user_64bit_mode(regs)); /* * Override the default operand and address sizes with what is specified @@ -1584,6 +1635,7 @@ bool insn_decode_from_regs(struct insn *insn, struct pt_regs *regs, return true; } +#endif /** * insn_decode_mmio() - Decode a MMIO instruction @@ -1609,7 +1661,6 @@ enum insn_mmio_type insn_decode_mmio(struct insn *insn, int *bytes) switch (insn->opcode.bytes[0]) { case 0x88: /* MOV m8,r8 */ *bytes = 1; - fallthrough; case 0x89: /* MOV m16/m32/m64, r16/m32/m64 */ if (!*bytes) *bytes = insn->opnd_bytes; @@ -1618,7 +1669,6 @@ enum insn_mmio_type insn_decode_mmio(struct insn *insn, int *bytes) case 0xc6: /* MOV m8, imm8 */ *bytes = 1; - fallthrough; case 0xc7: /* MOV m16/m32/m64, imm16/imm32/imm64 */ if (!*bytes) *bytes = insn->opnd_bytes; @@ -1627,7 +1677,6 @@ enum insn_mmio_type insn_decode_mmio(struct insn *insn, int *bytes) case 0x8a: /* MOV r8, m8 */ *bytes = 1; - fallthrough; case 0x8b: /* MOV r16/r32/r64, m16/m32/m64 */ if (!*bytes) *bytes = insn->opnd_bytes; @@ -1636,7 +1685,6 @@ enum insn_mmio_type insn_decode_mmio(struct insn *insn, int *bytes) case 0xa4: /* MOVS m8, m8 */ *bytes = 1; - fallthrough; case 0xa5: /* MOVS m16/m32/m64, m16/m32/m64 */ if (!*bytes) *bytes = insn->opnd_bytes; From patchwork Fri Feb 28 09:30:07 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996048 Received: from NAM10-DM6-obe.outbound.protection.outlook.com (mail-dm6nam10on2079.outbound.protection.outlook.com [40.107.93.79]) (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 E532C258CE4; Fri, 28 Feb 2025 09:50:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.93.79 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736205; cv=fail; b=lUH0YKV97B3Y23GoGTC8OqR/0m9SAaDOwNnSp9FLmAJ1lxg4SDLzfxABUWB/nuW9MzFs6T6Z+ftxRgXDgXLIEmFnufouYVysPjEvFg/DpR6A0JnOrf08hk/S492obh6V/PVCtsH/oaRfZzCX7UIXiwED/Fx0sdKFN/aTTt3y+m0= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736205; c=relaxed/simple; bh=1JUK3obeublxvo4e/gV4GaEfKEXLpx15rEF7jOfDvV8=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=akB8DWfvHsREh5fOwAQU8RqMOEg+y1D3LA3RlddJIUzN3UU4m8XN8V5JGxDc1tT8gXanx4Itl/K0hbnsBQPjWHc4sWV90aDCgd/e1jc1kEc+/TphTV4bzknvpUww5M4cYnb8dcNzm5jhno24HKMxIIxFtrXDil0uHTTVGFyysdY= 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=g1/Nd44i; arc=fail smtp.client-ip=40.107.93.79 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="g1/Nd44i" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=oCvJQU6XtstMUHPcMiOA+e27gV/xc/3+as+M/0spG2Js5U5Dvz+Wpf7YkmgzIz6+kcCgmzeD2/1tzVnBLEACzsoct2Rgiifk/5FEm02cDiFtNLF0LojvcauF4su4IcFp1Cb6Gm7zsq7jSyRfA0baaajymL3KUjNKrkUnf/OgJTQcAoIO6EiVqUpQoYNFGhlnqM63Ne7/0tyWRJyJNqJsD0yBBPFlUfLa85wkQFKyw8Dexus9LDuU7rtt4Kovmdcjeg+OfyI+PnngjsoWRKphJ0FvZwPI+T9HEDBSW8+x9wIetK9IdqhVxnkZuMoXS7EiB/eoGhFYR4f6P3waTqieiA== 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=zSgv/mXuA4I9W+srFDajKf0GOwHiQGffypCIyRaXIeU=; b=m/ROfcSpqQcqqdnhHJfjfGWC9zzZYFSVL1Tu6FTltQGoNUswlbOJJoF6T/KAy4BRn2RV1C75SpCh2vRolRMlB5Mj5p5S37EbNxjDB87pXI2W/FleKl08lWZp3KUXJRO/i7/InSdJKZ3Udbqa0eJsdCG1gIWy2qtUlXAX7tB18Kq/0RvJo2+Jnz6IpFQ0royAU+w45wRNjD6CwTEFvdvRK1CnC0O6C64SIwDXaJjcTuaAXrV7xv/5NFyd4fGk49c5ZgTjdMHQEQr9X7+iL9dDrDUs9zmMwDlewBnXGRZy0bJN0YtNqo0kXESBuqBVKBScTBUDlCkqHS92fBcYubccLg== 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=zSgv/mXuA4I9W+srFDajKf0GOwHiQGffypCIyRaXIeU=; b=g1/Nd44i0IEY/8cIHWkHONJKu3GOExbLXdPN+2wTPGu7RsRZ3RV+Z061k0mfHO2i7NjfLHNA1VrE3eH2JpG6+nJzn7Bmisac13aTNFrzMKiU/NwdOYZJxxKS9045JdEWpAPAHJyCFbMq2Es+WhzhWajxdk9mkCKrA2VKIaMHP40= Received: from BY5PR16CA0028.namprd16.prod.outlook.com (2603:10b6:a03:1a0::41) by DS0PR12MB9421.namprd12.prod.outlook.com (2603:10b6:8:1a1::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8489.22; Fri, 28 Feb 2025 09:50:00 +0000 Received: from BY1PEPF0001AE16.namprd04.prod.outlook.com (2603:10b6:a03:1a0:cafe::eb) by BY5PR16CA0028.outlook.office365.com (2603:10b6:a03:1a0::41) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8466.21 via Frontend Transport; Fri, 28 Feb 2025 09:49: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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by BY1PEPF0001AE16.mail.protection.outlook.com (10.167.242.104) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 09:49:59 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:47:24 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 14/31] KVM: selftests: Add MMIO VC exception handling for SEV-ES guests Date: Fri, 28 Feb 2025 15:00:07 +0530 Message-ID: <20250228093024.114983-15-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BY1PEPF0001AE16:EE_|DS0PR12MB9421:EE_ X-MS-Office365-Filtering-Correlation-Id: b922af5f-93d7-4791-2afa-08dd57dd441e X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|82310400026|36860700013|376014; X-Microsoft-Antispam-Message-Info: hoAZH3RkTTzyJnr8sXZc5EXC0+1bu2w1LwgiPwgpRIOvMZo4gMCtoNLqmr/A8B/RkjPPnPFDNOPXDRSR0joJ6bFZB/FfWx7a+7nSxuAfraZ6Qld94g4ebC8X4ujNLE/KSOcn5gv8Bq/h3oRHdm9qwkEjGiOjpuJmThxjpYfl8npQakdRWao2o6P5a4R+Dk204/TG2k7NxdUjDe5Zy4+s4a8mu8aYWcI+4nPKyZfiyqnzu9MaiKLFGI+OweHiDiIiXSvWQ4QvMYg3dnhuq8gvJ/o7s7YSWxJZOZLf+Gn5yoWXifR4XMWsoR6//j8lTjMglPcsfKAr2ccblFkimUcSS1Pi5CI8ZAXSxhZg2tFEpb84vLFue+Q4PZXSCf/TWJs04cDUz4/An+7qyb0zak798sur2O+DdpCYMVDsyMxd9mcwOFXNtmjmnbMKesWdlRPNn29WHHnOTd+jmOQVhOs8Aqy3WV1hdBaW4T1APdsfIn4zJkv89enYnh85ga/NmTr8vxyji3noOMZKGNOgFAFflpiaMxS1DUYi1h+7tvxFzeN0vDL9VwoCtOzxGDJjhRhukB1dg0e9QkSjYCQvigDaVtJ+3X5pyoSPFM+0Xx+F1JG//xOjFvf02o1s3hrGpgWZgQSzgvJ/hOrDkLB2qsHJDJfCQ9JZ80bL6Q6scnHcpUW3LxAHH/M8d/TThrmGGR+8Our0HbFwuJ5SphSS1EgPllLkx5fY+ff+oYrdq07tqEXrPhCHEaolfvzqkkjUZBln+E8HDJcDQzRUd3ve+7tK0/Km2HyBO4tcW8VKUnGryF4gop7JmFBgOmJE8LlQdQwHPW/B7frnBb1uJ9yR7+roqTChwUvE4HvaTdKfu8/dnxCevprAfFbSLEMzXA/C3OVh7GMO90YExGDgcnLXwDI3jaqZfVNZVeMc25pNV9Om2okjIZgOdNxfLu3TfhhTlcHcg7TWkibeZQ4an6fFE++5l1A0zaFK/7Xl/drvcB7IvTeeZet+Yp04+k++cWcWyo3BsKCgjfOBcEEeQCkMyNydRWXVS9f+9XLwEsSw4IIX4TvL7nKm2qFwOCnzVjgxEjRunsd1xV9qQEJ6A1ZQqtgaR2lR3uqp2twbHTr76nTgd5DrJl9UCFSlLc8+XqXm+VbuOmVcbb0a0TNdRDbbAjim37MeeU10orx1DmGc9Ax/TsuFLOF2G4W9IQahquqUBROEKHq+ECGY83lOrIreUJ3MVlMJzcE0XBS4jsE8ShN2Mhtbe23XqrmpU7wP30TM5nLPT4MPMGbwC4gWdNteFivTE4whNmzwqjX9azIidjQF7t9tNc0Sdro00g2vDYdciX6FoHPPe3wxqVvSgZ9u9htUnF6FRyIkiFRkQcoiZu6/rB8J8TxLbdecXXNUJcxcO/zrzYOS0MfTfSfNx5uer52+eacmlghYUH0Ecvj6AmexkdiOWQXVeYDkpkBp9C+kLEBulIVU4V/X6G6VtlImGLWbXqPYoxx2EHBYeqHo6SPjZPg= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(82310400026)(36860700013)(376014);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Feb 2025 09:49:59.7133 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: b922af5f-93d7-4791-2afa-08dd57dd441e 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: BY1PEPF0001AE16.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS0PR12MB9421 Add MMIO VC exception handling support to allow xapic mmio access for SEV-ES guests. In addition, add a PV interface for xapic MMIO guest accesses from outside of VC exception handler context. Signed-off-by: Neeraj Upadhyay --- .../selftests/kvm/include/x86/ex_regs.h | 2 +- tools/testing/selftests/kvm/include/x86/sev.h | 1 + tools/testing/selftests/kvm/lib/x86/sev.c | 259 +++++++++++++++++- 3 files changed, 257 insertions(+), 5 deletions(-) diff --git a/tools/testing/selftests/kvm/include/x86/ex_regs.h b/tools/testing/selftests/kvm/include/x86/ex_regs.h index 172cfbb0a2d0..fd773b6614bc 100644 --- a/tools/testing/selftests/kvm/include/x86/ex_regs.h +++ b/tools/testing/selftests/kvm/include/x86/ex_regs.h @@ -4,7 +4,7 @@ */ #ifndef SELFTEST_KVM_EX_REGS_H -#define SELFTEST_KVM_EX_REG_H +#define SELFTEST_KVM_EX_REGS_H struct ex_regs { uint64_t rax, rcx, rdx, rbx; diff --git a/tools/testing/selftests/kvm/include/x86/sev.h b/tools/testing/selftests/kvm/include/x86/sev.h index 5556ee891260..3756805197c3 100644 --- a/tools/testing/selftests/kvm/include/x86/sev.h +++ b/tools/testing/selftests/kvm/include/x86/sev.h @@ -155,4 +155,5 @@ void sev_es_ucall_port_write(uint32_t port, uint64_t data); 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/selftests/kvm/lib/x86/sev.c index ff8f02b83871..16d6b21649d1 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 +#include "insn-eval.h" #include "sev.h" #include "linux/bitmap.h" #include "svm.h" @@ -14,6 +16,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 struct ghcb_entry { struct ghcb ghcb; @@ -362,10 +366,10 @@ static uint64_t setup_exitinfo1_portio(uint32_t port) #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) static void register_ghcb_page(uint64_t ghcb_gpa) { @@ -471,6 +475,250 @@ static void sev_es_vc_msr_handler(struct ex_regs *regs) ghcb_free(entry); } +static void __sev_es_hv_mmio_rw(struct ghcb_entry *entry, uint32_t *reg_gpa, + unsigned int bytes, bool write) +{ + uint64_t exitinfo1 = (uint64_t)reg_gpa; + struct ghcb *ghcb = &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_buffer)); + do_vmg_exit(entry->gpa); + ret = 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 = ghcb_alloc(); + ghcb = &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 = 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 = (uint8_t *)buf; + + switch (size) { + case 1: { + uint8_t *target = (uint8_t *)dst; + + memcpy(target, buffer, 1); + break; + } + case 2: { + uint16_t *target = (uint16_t *)dst; + + memcpy(target, buffer, 2); + break; + } + case 4: { + uint32_t *target = (uint32_t *)dst; + + memcpy(target, buffer, 4); + break; + } + case 8: { + uint64_t *target = (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 = (uint8_t *)src; + + memcpy(buf, s, 1); + break; + } + case 2: { + uint16_t *s = (uint16_t *)src; + + memcpy(buf, s, 1); + break; + } + case 4: { + uint32_t *s = (uint32_t *)src; + + memcpy(buf, s, 1); + break; + } + case 8: { + uint64_t *s = (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, unsigned int bytes) +{ + unsigned long ds_base, es_base; + unsigned char *src, *dst; + unsigned char buffer[8]; + int ret; + bool rep; + int off; + + ds_base = insn_get_seg_base(regs, INAT_SEG_REG_DS); + es_base = insn_get_seg_base(regs, INAT_SEG_REG_ES); + + if (ds_base == -1L || es_base == -1L) + return -1; + + src = ds_base + (unsigned char *)regs->rsi; + dst = es_base + (unsigned char *)regs->rdi; + + ret = vc_read_mem(regs, insn, src, buffer, bytes); + if (ret != 0) + return ret; + + ret = vc_write_mem(regs, insn, dst, buffer, bytes); + if (ret != 0) + return ret; + +#define X86_EFLAGS_DF (1UL << 10) + if (regs->rflags & X86_EFLAGS_DF) + off = -bytes; + else + off = bytes; + + regs->rsi += off; + regs->rdi += off; + + rep = insn_has_rep_prefix(insn); + if (rep) + regs->rcx -= 1; + + if (!rep || regs->rcx == 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 = insn_decode(&insn, buffer, MAX_INSN_SIZE, INSN_MODE_64); + + if (ret < 0) + __GUEST_ASSERT(0, "Instruction decode failed, ret: %d\n", ret); + + mmio = insn_decode_mmio(&insn, (int *)&bytes); + __GUEST_ASSERT(!(mmio == INSN_MMIO_DECODE_FAILED), " MMIO decode failed\n"); + + if (mmio != INSN_MMIO_WRITE_IMM && mmio != INSN_MMIO_MOVS) { + reg_data = insn_get_modrm_reg_ptr(&insn, regs); + __GUEST_ASSERT(reg_data, "insn_get_modrm_reg_ptr failed\n"); + } + + entry = ghcb_alloc(); + ghcb = &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 == 4) + *reg_data = 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 == 1) { + uint8_t *val = (uint8_t *)ghcb->shared_buffer; + + sign_byte = (*val & 0x80) ? 0xff : 0x00; + } else { + uint16_t *val = (uint16_t *)ghcb->shared_buffer; + + sign_byte = (*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 = vc_handle_mmio_movs(regs, &insn, bytes); + break; + default: + break; + } + + ghcb_free(entry); + regs->rip += insn.length; +} + void sev_es_vc_handler(struct ex_regs *regs) { uint64_t exit_code = regs->error_code; @@ -481,6 +729,9 @@ void sev_es_vc_handler(struct ex_regs *regs) /* rdmsr/wrmsr instruction size = 2 */ regs->rip += 2; break; + case SVM_EXIT_NPF: + sev_es_vc_mmio_handler(regs); + break; default: __GUEST_ASSERT(0, "No VC handler\n"); } From patchwork Fri Feb 28 09:30:08 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996049 Received: from NAM11-BN8-obe.outbound.protection.outlook.com (mail-bn8nam11on2086.outbound.protection.outlook.com [40.107.236.86]) (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 1765A1F9416; Fri, 28 Feb 2025 09:50:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.236.86 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736240; cv=fail; b=MBULEHVZjaqpeN16DWvCEqJYshJPAhnJoH2NqdrV+ANUWoNnK4xwMcJbECp+1Q5er6cDB2CIxj5J3Wx/Yx+A8lacidQpbSQFV/sNgUDpirH4PGOAA7pn2/cv1c9VsTANmRmAQkOXhEu2o8eASzN0Of7r0RWvmfEw4fHxdOK2Unc= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736240; c=relaxed/simple; bh=8vNTa7wxKYVDUbBMShkckl2o6YaP9kaNsQqrl0BpARE=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=DyTvfGpEdM63gCwPwlpn8y5GrZWE6+9tTkhEDf7WhE9IsSk2jBPgKHIEJ4u75zAnR94jiB1Z3P4wskPuB1KtPDoVxR7A0BnvQZGNvzRdP8fFfetU0rwBAd5EUR2mm2rct4OKn6Ht6txc9WXL59hK/aLKbbPiRuPZclpRTi+N87A= 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=dtvumz0Y; arc=fail smtp.client-ip=40.107.236.86 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="dtvumz0Y" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=M4zIhNQuzVcE60EguauWM9RBT/xBkQgvQzzs16ja2CrzlbmK8QEuGEEDY9Bnt89Zg+KifF5L7o979TeugztmeWYhWTcNUrISVoHJ02qpkIU4e6HUx9BX+ZFaARc5ZjaVk2hK9b+buBxjBlAg4kGe4wW1dS0qXW9nV/XRY1oSus1VjtxiuuLpcjOvWJ3Wh3uHrNkhSSNfj3CDjqgN0YHi7SHkpEcemXuuKMNrDs+wlHY1yjzsFYqW/NmWaZJs45JX2oym3Aly79lPoEOIRGjD5Tt2S99LKL1gkQCFpjn6XRcjuuYPDO2hHdam2FaUEgFNLcTeNr2SQJcopfdC6Yn4OA== 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=1cwiHMZ2gmDOaZW4CbDxLEcxXV9VqJTg/fuLd73gr3E=; b=r8OthB5jf6URpfYeGB18Fd91s16uyFE1ecy9+OB5esfgZ7PG169o+WSYeicPA3+xZxvkel98ALy/B+rBOsUxScdfAamOVAoUap1fuSs1whiuyzhrVHu5kX1WJjcTonT2qkQ4OC+GTJGPv/lOfYs97LmU+5vjvsl2yVaAG72z53m7PM/7PYZ5AIArCPSQO842igZQc+mggqbW9zC+1babollxAl2DHrcUEs36/XOt2uqaJOcmMXFUv05XhnRA0qQ+UqruAIurWR5jA54M4i9I7BY1tELFwPFGveUvFDqutLiioTb8F4BlhjqD2kDdlilozrAIHfeStmHzYL8A8ActgA== 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=1cwiHMZ2gmDOaZW4CbDxLEcxXV9VqJTg/fuLd73gr3E=; b=dtvumz0Yoqwv56mlqt9ERclT+V+XuV6L/cK9hPfUR0MgkP0fBJx8dnD/TI6ZrC1MbFOQisLMi1oBQsv2vhGd8PcNqwcBBjJENmj4Myt5NYxHQ8SA/ozcmBSJSL0czeDdafUKDEhSfH8LChZD1oyF0OPeq5Z2gPlUEjIpZFeJhW4= Received: from PH7P220CA0004.NAMP220.PROD.OUTLOOK.COM (2603:10b6:510:326::16) by SA0PR12MB4496.namprd12.prod.outlook.com (2603:10b6:806:9b::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8489.19; Fri, 28 Feb 2025 09:50:35 +0000 Received: from BY1PEPF0001AE1B.namprd04.prod.outlook.com (2603:10b6:510:326:cafe::56) by PH7P220CA0004.outlook.office365.com (2603:10b6:510:326::16) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.23 via Frontend Transport; Fri, 28 Feb 2025 09:50:34 +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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by BY1PEPF0001AE1B.mail.protection.outlook.com (10.167.242.103) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 09:50:34 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:49:37 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 15/31] KVM: selftests: Add instruction decoding for movabs instructions Date: Fri, 28 Feb 2025 15:00:08 +0530 Message-ID: <20250228093024.114983-16-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BY1PEPF0001AE1B:EE_|SA0PR12MB4496:EE_ X-MS-Office365-Filtering-Correlation-Id: 8cba5754-77e8-4f37-b4e6-08dd57dd58f5 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|376014|1800799024|36860700013; X-Microsoft-Antispam-Message-Info: 2XSS5bwDlVvz7Epyc59g3J25I04D09316ib1VsFye19n3QkLeyRTC5yiANmIrtu5DhP3p7p9LE3HyVeaHHV+on1HPEXkUO46VGv8FfrHHdJgwj1VxNjGfNUcf2zI0277tPL43jRv0RAS60VadDP99lHxkQaBisl3NOrLC/pCLJSjoi2kP1ZFtZVVapZ3R5MS9zGZSHecTy6cy+SFcAqPbnR5Nwo8cX6AzLY2eS2q4qfdOYVn+GNo5sGSZLRdp3UFBd/1mMlMhdNZRpAZuYAq2sQbrm4V6uZd4SiZMB/V/366hyRIo2ZN2lEyGMdFHCZtLF56wtl6qbfxeLp/lJPi55up6WXZM4Bh5F3D9gYzWmA2bbuKw3MBZBqzEb2LNlOv+enX/gCIVuHgSqFevkAx/nc0CCCKLDCL782dhemgzCsQydeFjGJNNtvBYA+CRTl5kr+mTyiREUaPaFejJgW/Q8+CJBLatDXVuCQxawZWcWeyQLYyYcZKuMxoMPxkN6lzqrScNVz/t/w+2nHWHpE3mJHwKGvjTLPudmrab87lTfuP7B1zL1AJAK1JeLU2aKtVojUBZWYPEa+m5u+KgCe7oIpDdQiYWLY56eCf0fcYwO4n0y6ZzMXmbDNh+ztQfg0bs86MtnvAePJKjvLUj5Ufci0VtbgSpKk6kQo0y3TwmFRcWud/wru0Bkn5oc8Yr2aDAG+8B71BjtinhYJ9VfGU0Sn7rMtO+SBJd4UpiRj1ckSY/Uwa/sbsPXmx0WLbMbheqGLBn5lYa8SXB4650oYoOVa/kvlo7w2eu8nUcwKsttwTDEUVXKTw324ieIwW2auHZZZc+sUZ8X2nc8+RGfrcUjMCyN2fZGB5xeNWlN3iJUc2Fj3kRZhQ2psjno/TYrgXjB2jsTiCH4YT93XgpAxyKc/xOR8eW+/XtsslSaYyRrlFD+2IjtOuroKCkHnAia/mWoOl/VdJzZYxJialJxqRCMAfXECfwfYXeEjXGgDubjzTmfxS+R9GrhWIlkrHFybt5UXFX/jw+c0nTkbCBBDPJwl4FRh50mPOY3BV4LIwqRNpxf5e9Gs5alqokdUlhMRN557KJILlqbe3BMKiqBrhv1oXaw/MCQdjEHxsigkMDHICqx3TVeDxtm1oEcuhk/VN2I1S/N2s5hukeHtTj4tYo5frEuftp3KnzGU8l+ZZvJzjHptgOfAH0quK4oyPqL6l0LJcpCXx2+X4epYciC6Ta5MP3lyQdXQ2N5gmH2HrePvR5UPE/ufd82kvAjviEYA6MrekryfyMixdl0kROK4dZb9gNwJREeFr9L/UmfwsCG4kgulUkTm3MvBkEzO+QCVvkW2whOOE5qXtVvfhXM+lZNpbUuV5AVl4eTaeCqWqSPIstuz6OaVVbT5TuYPTTtZDl2MnJBsrsKDovBJOM9H0A3CFDlFi7DTnvB0b27XFsuywO1hQRt6aB4LSMc/h01Jq36wNXaWHbFr9xPR+gGCXTvfIV00XLmm6RBtHEaQ1UTY= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(376014)(1800799024)(36860700013);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Feb 2025 09:50:34.6645 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 8cba5754-77e8-4f37-b4e6-08dd57dd58f5 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: BY1PEPF0001AE1B.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA0PR12MB4496 Certain xapic MMIO reads and writes get compiled into movabs instruction which uses rax as the register containing data and 8-byte address encoded as part of the instruction. Add support to decode these instructions. Signed-off-by: Neeraj Upadhyay --- .../testing/selftests/kvm/lib/x86/insn-eval.c | 8 +++++ tools/testing/selftests/kvm/lib/x86/sev.c | 35 ++++++++++++++----- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/tools/testing/selftests/kvm/lib/x86/insn-eval.c b/tools/testing/selftests/kvm/lib/x86/insn-eval.c index efa4d3fde504..60c8c7cf5658 100644 --- a/tools/testing/selftests/kvm/lib/x86/insn-eval.c +++ b/tools/testing/selftests/kvm/lib/x86/insn-eval.c @@ -1712,6 +1712,14 @@ enum insn_mmio_type insn_decode_mmio(struct insn *insn, int *bytes) break; } break; + case 0xa1: + type = INSN_MMIO_READ_MOV_ABS; + *bytes = insn->opnd_bytes; + break; + case 0xa3: + type = INSN_MMIO_WRITE_MOV_ABS; + *bytes = insn->opnd_bytes; + break; } return type; diff --git a/tools/testing/selftests/kvm/lib/x86/sev.c b/tools/testing/selftests/kvm/lib/x86/sev.c index 16d6b21649d1..24aaa75ec450 100644 --- a/tools/testing/selftests/kvm/lib/x86/sev.c +++ b/tools/testing/selftests/kvm/lib/x86/sev.c @@ -517,9 +517,11 @@ void sev_es_pv_mmio_rw(uint32_t *reg_gpa, uint32_t *data, bool write) } 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 = insn_get_addr_ref(insn, regs); + if (!ref) + ref = insn_get_addr_ref(insn, regs); register_ghcb_page(entry->gpa); __sev_es_hv_mmio_rw(entry, ref, bytes, !read); @@ -648,11 +650,12 @@ 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 long *reg_data = NULL; unsigned int bytes; struct ghcb *ghcb; uint8_t sign_byte; struct insn insn; + void *abs_ref; int ret; memcpy(buffer, (uint8_t *)regs->rip, MAX_INSN_SIZE); @@ -664,7 +667,9 @@ static void sev_es_vc_mmio_handler(struct ex_regs *regs) mmio = insn_decode_mmio(&insn, (int *)&bytes); __GUEST_ASSERT(!(mmio == INSN_MMIO_DECODE_FAILED), " MMIO decode failed\n"); - if (mmio != INSN_MMIO_WRITE_IMM && mmio != INSN_MMIO_MOVS) { + if (mmio == INSN_MMIO_WRITE_MOV_ABS || mmio == INSN_MMIO_READ_MOV_ABS) { + reg_data = ®s->rax; + } else if (mmio != INSN_MMIO_WRITE_IMM && mmio != INSN_MMIO_MOVS) { reg_data = insn_get_modrm_reg_ptr(&insn, regs); __GUEST_ASSERT(reg_data, "insn_get_modrm_reg_ptr failed\n"); } @@ -675,25 +680,37 @@ static void sev_es_vc_mmio_handler(struct ex_regs *regs) 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 = (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 == 4) + *reg_data = 0; + memcpy(reg_data, ghcb->shared_buffer, bytes); + break; + case INSN_MMIO_READ_MOV_ABS: + abs_ref = (void *)*(uint64_t *)((char *)regs->rip + 1); + do_mmio(entry, regs, &insn, bytes, true, abs_ref); if (bytes == 4) *reg_data = 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 == 1) { uint8_t *val = (uint8_t *)ghcb->shared_buffer; From patchwork Fri Feb 28 09:30:09 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996050 Received: from NAM10-BN7-obe.outbound.protection.outlook.com (mail-bn7nam10on2064.outbound.protection.outlook.com [40.107.92.64]) (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 15E96257AEC; Fri, 28 Feb 2025 09:50:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.92.64 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736259; cv=fail; b=MCGKkfWcVYDtSV6R7xenhxFKpdr+95YPODTGDocMmU64RmsKmGgcZfKMc6Ips7oLQ+NwMYfe5ATV9jSr1LCCb9xu3IrEPR3GtglZcT03smy/aOL35StQI/zoGOHLdeNT/sPu2xcNjB8qvzr2nSemjgpNLzLJRMKBuA9ocRdQKEo= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736259; c=relaxed/simple; bh=XMTTZtqo8L7DM5SGkAgl9ijrT6nzq8Inz+uzBlBW6Jk=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=odCfpjnbjbUHuUUOk1s9VuqPzqwkssH2sy6B1W12VhO2x8ndq8JFp5GRecLJZvR4YEDXnqjbmQmYrzZQxeFPt7OhX21uAJ2ZqVRIUO1WWWnDLYUDIwg0Ijikv8DFFifT/HmyOFOqYNKKT6gqFBXoblBD1u5MUvPO5aWLH3AJ9Zc= 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=uuPA7uMn; arc=fail smtp.client-ip=40.107.92.64 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="uuPA7uMn" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=bI3MYHLIFKlYkt/8W1mx7F5FWNqGwdkCyL6o2uWS06v8wER/0l18hfoeYjVFuTlsIBynnBsDZK0uHpr3wBxKem+FjlovmZJE+B2Wve1Eb9CTv8ME7LeaYb1STrvh3ereqaRM9OzJM9cXvU+8wr8FMH4JkBGzZgveJItbGTRFWSfRbYhuhLSrjaOb95htTQF6tchnr29KujQDXNrMTv0WVwAgyyK9YuDxvs/8a3F5QVruwlrIO76x1xL0OcXElF85TeppRxUhzzTQQMszL8Cc1vXEihx7Yqyq/awtS6HiOcnB5hdXltGpgnFDwS57K9nfd3QZO4qJwRy7t/YOlBQhBw== 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=ongzqT3ft0yi878ilh4B8gyyQ4FtiAWT5kAGVHhaVf4=; b=tux9k9B7vfviA1xgDftTlPq6liBga39IEVh+EOlpahvzvHkdNbSXc8uQwOSWPfA4/jlaWYhdArrkMaukEUkCkHIMEcGVKCGloVrGnPIZFrS1vHkWV/2OTElsO5HKPTE4Veg+MimEGU97ResNOBKcgkf4VEsn15YcT3Q1wR32zBwAJNzfitSwLI1sGKJ2KDi3oHObMEwrMI9oBd6kYGO0O57ulxmvmB7xBK2G5qf8HELoZKx56WCpUBHERyd5OUAkzU5ZioUiMTjhJ3O42DLNAJKZScHi4fYRU0K7mdinEa7mjOoceMl0E7LTE5Ki/+L5wfkjLU0iVZbLNzDxD5u9wg== 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=ongzqT3ft0yi878ilh4B8gyyQ4FtiAWT5kAGVHhaVf4=; b=uuPA7uMnlJ6OiH6kAQLRciZXcPKFQA6eU2XJue/olzTOwg9tfFkqIgJRzImxZrG7axC89LHSsL0lTVm3OmRNJ62VOPN8GTaX6cjtHFYcRSjJfovOasnIhT4aD1sIZYTL+//r72SYjWsvGWyjIqnX4uerzccOsSafSdoDFaOfnJM= Received: from SJ0PR05CA0151.namprd05.prod.outlook.com (2603:10b6:a03:339::6) by PH7PR12MB8795.namprd12.prod.outlook.com (2603:10b6:510:275::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8489.21; Fri, 28 Feb 2025 09:50:50 +0000 Received: from BY1PEPF0001AE1C.namprd04.prod.outlook.com (2603:10b6:a03:339:cafe::df) by SJ0PR05CA0151.outlook.office365.com (2603:10b6:a03:339::6) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.20 via Frontend Transport; Fri, 28 Feb 2025 09:50:50 +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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by BY1PEPF0001AE1C.mail.protection.outlook.com (10.167.242.105) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 09:50:50 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:50:33 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 16/31] KVM: selftests: Add SEV guests support in xapic_state_test Date: Fri, 28 Feb 2025 15:00:09 +0530 Message-ID: <20250228093024.114983-17-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BY1PEPF0001AE1C:EE_|PH7PR12MB8795:EE_ X-MS-Office365-Filtering-Correlation-Id: ca125e08-6bc3-4582-ebc3-08dd57dd626b 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: ED5Y8Eas5203BNgDbELCHqcj1q8IGBZbYXShe753M3gRBuqfR6QAxVMUavcY+QlNovZi6K2X1jlPT7V1fHlFvbF2V6MulEGRKu8vC+L+FbAWKemHeExn7qLRKTYsHO/JRHQ+WKyorUbduv13oSY8mYb5RbJAtYupuamqR9z7wzcKLUodTNn371Ky+LeO3xGoxZItppOBFu5RoWfcY+qcOYAfhcOD9PblzECYSJZOdoo62pyCUVOpGwn1MTgLxtSid/X4gB2hftMs1CzfXuf8sHhMABYvTkFDAyMowzpyInn3UBm3X2C5az1lNvwKm7Jk5LO/KS2gG8RcU5tLqEgbjuTwAOXIIO4Enf0USKNVt5bc8D5fqjWRi95TdL4cxuQ0GrSdqK9gNH02IrKRL9lNtlioMp0c0b7FanHSOfjFdzr8RqIix7tDKhBENfGS7U2dIDeRMVvIn8xddqokbolr6TyC5l3OiN+RziTUX0NIJaP8qaUt1JpksMZdkgwL94v6V0UTNCSCq1LHLiENX64x8tzGTOMtBampINTjdPzhgKfhCZ1du+dO8s+PpFwA6bobYBRnDRbSPpDwO4//NOYMiKYeE4Bo0+JAYitCmWKHDouOY7EsW2Xxufsq3w1Oztw0dGt4eMGbSBnaGjG1TuJpvrE8QsAtGQfDIKwP3fu3cWQaBB9CDkavMddAz/zDwyoeR3cl7AH414HXEk0/YMkOpinGbQk+Zbs71IwDg4LROk0AZVPQhdPa5y0tIWNu/W9AVAQNtpSny4RomRlkhGeDa5Ym8ab7W1OFUIj/UhmMzm7vl9FUzawcIyrwQTJHqcRDZkUHhYEMRbIT8Vy8sl4pG3cTrYhsCOmDARHP/ZYgd7W8sSlLLNssg0HwZuEmmQBZc61Q/+aPDxYhNM/Jc0EYmI6f1nvplnf2ydBwZPR1W+SoV+cxEQSby8PYM2rJMpNUDhupEmILGK5FA7QnlTKI7/Y1BtGnKdHy4f0vePWF2j9PAKCbQr6wenzRVHOpUncyd29QODaHiFKkD3jdm+OXeE/eh20CJZelZqwk6zeEdhKny31N8vodvKKbjteVyIHON0L7Ii50GmrDw5sk+FhC6O2+CrdScLlxcFhWrHqqx6AgIKNhVYcZwf7jSjyalOFFgJ0RRv7wrhtZkAsSF29Z4bBqCjXqrSqaEdJ4LN8JDQDqiexSb158EO9NJCu3rCJiV5Y7dqHU0g0p9aiiFxxS8dP/wetNJ0x/6jPUCqbsa7+2AScxa9sINfDqKYw661zeSu2sYDW1jbU8AuoejksXhk6BdeLDflOjwa+DtyKTo3xF4b5LAHoOOB1beD3uOtQambozzJB6qyEtq2dbbtWKR7rcW5GKp1u2svYwZij6CzLPyofeIja7Wh2AkCwNDqP7PhqVYGk970QWV2D8K6cjFEPUcmmIoX/cT9GMBhYAQkAqPmWQuKheZzxlQ1vnW94V92z7Uu8KPt+nXm0TSJRbdTSxkBYkE5AoNVda5tkSvYQ= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.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: 28 Feb 2025 09:50:50.6169 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: ca125e08-6bc3-4582-ebc3-08dd57dd626b 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: BY1PEPF0001AE1C.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR12MB8795 Now with xapic/x2apic acceses being supported for SEV-ES and SNP guests, add support for testing these VMs in xapic_state_test. 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/testing/selftests/kvm/x86/xapic_state_test.c index 88bcca188799..efbc98f04d45 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" struct xapic_vcpu { struct kvm_vcpu *vcpu; @@ -160,6 +161,27 @@ static void __test_apic_id(struct kvm_vcpu *vcpu, uint64_t apic_base) expected, apic_id); } +static inline bool is_sev_vm_type(int type) +{ + return type == KVM_X86_SEV_VM || + type == KVM_X86_SEV_ES_VM || + type == 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 userspace * stuffs MSR_IA32_APICBASE. Setting the APIC_ID when x2APIC is enabled and @@ -168,16 +190,22 @@ static void __test_apic_id(struct kvm_vcpu *vcpu, uint64_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 = 3; struct kvm_vcpu *vcpus[NR_VCPUS]; uint64_t apic_base; struct kvm_vm *vm; int i; + struct vm_shape shape = { + .mode = VM_MODE_DEFAULT, + .type = vm_type, + }; - vm = vm_create_with_vcpus(NR_VCPUS, NULL, vcpus); + vm = __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); for (i = 0; i < NR_VCPUS; i++) { apic_base = vcpu_get_msr(vcpus[i], MSR_IA32_APICBASE); @@ -195,15 +223,21 @@ static void test_apic_id(void) kvm_vm_free(vm); } -static void test_x2apic_id(void) +static void test_x2apic_id(int vm_type) { struct kvm_lapic_state lapic = {}; struct kvm_vcpu *vcpu; struct kvm_vm *vm; int i; + bool is_sev = is_sev_vm_type(vm_type); - vm = vm_create_with_one_vcpu(&vcpu, NULL); + if (is_sev) + vm = vm_sev_create_with_one_vcpu(vm_type, NULL, &vcpu); + else + vm = vm_create_with_one_vcpu(&vcpu, NULL); vcpu_set_msr(vcpu, MSR_IA32_APICBASE, MSR_IA32_APICBASE_ENABLE | X2APIC_ENABLE); + if (is_sev) + vm_sev_launch(vm, get_sev_policy(vm_type), NULL); /* * 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); } +void get_cmdline_args(int argc, char *argv[], int *vm_type) +{ + for (;;) { + int opt = getopt(argc, argv, "t:"); + + if (opt == -1) + break; + switch (opt) { + case 't': + *vm_type = 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: -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 = { @@ -229,8 +303,24 @@ int main(int argc, char *argv[]) .is_x2apic = true, }; struct kvm_vm *vm; + int vm_type = KVM_X86_DEFAULT_VM; + bool is_sev; + + get_cmdline_args(argc, argv, &vm_type); + is_sev = is_sev_vm_type(vm_type); + + if (is_sev) + vm = vm_sev_create_with_one_vcpu(vm_type, x2apic_guest_code, + &x.vcpu); + else + vm = 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); - vm = vm_create_with_one_vcpu(&x.vcpu, x2apic_guest_code); test_icr(&x); kvm_vm_free(vm); @@ -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 = vm_create_with_one_vcpu(&x.vcpu, xapic_guest_code); + if (is_sev) + vm = vm_sev_create_with_one_vcpu(vm_type, xapic_guest_code, + &x.vcpu); + else + vm = 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 = false; /* @@ -254,9 +352,12 @@ int main(int argc, char *argv[]) vcpu_clear_cpuid_feature(x.vcpu, X86_FEATURE_X2APIC); 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); - test_apic_id(); - test_x2apic_id(); + test_apic_id(vm_type); + test_x2apic_id(vm_type); } From patchwork Fri Feb 28 09:30:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996065 Received: from NAM10-MW2-obe.outbound.protection.outlook.com (mail-mw2nam10on2068.outbound.protection.outlook.com [40.107.94.68]) (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 54796258CE0; Fri, 28 Feb 2025 09:51:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.94.68 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736266; cv=fail; b=e6wU1sYJGBHpWDuu6xiM0tiF/hPI6K0IJitka1AgdEEJ8GVExdvuEVaX17ch0IKa3qQu9uUa7GK0nl+IlVTPuDVU3WrKRTqv5sQkj7pH+deRuHsiQSvMYM5fDOPSL976GM8WF9ytxVFYqvmoFtZlDwShOhlkDs/gVvmzurUShfU= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736266; c=relaxed/simple; bh=QBtNHo/AJUxZvu70ioVNSxJDjpRuUCJ/omCnFfV4XBw=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=DH6NQ64ABzseAa7uiYHE4/vHWGLoipEuP518XHJRpGx6mjeYJZSw0ZY44148WFxtim9BokLvkPSPDAmUiOQUl92nP7qscoGDccx/ckVs4sTvHnfMt27FKRhhcQoATAV+/LQxfzitYHcteBbQ8JLQcL5fpQoDDWWj8aY/6oKLeYk= 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=aw1q50wh; arc=fail smtp.client-ip=40.107.94.68 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="aw1q50wh" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=p2v4VFxwwnaDxgu08q1+cTIJuoXjdPS+bwha1z3cuGRUdk8wUEsknHdpOl9uuyGLDuKSi/mTryqWpLktXNtjmyQvoyj9oxQM0fXw+5XVWSVDdllA9WCq9T+uBznhCJTdcDDDqxmyB1KaJZI6Oq6qNWvb0ocXrdouZ38ay2GDP2dH7pSp8wFfECQyXNiwyDIzbpOrHX537fBoMtEFIhT7z5dqUw4Uv2sjHbCkkqh0nnT961Lz/eO2+cIKNAjUTYB4xI2l4aXT5dUjKBqmG0Z3xI2qBMGH+OgWHM4ExwoxCscT+OyCfn2u1hANXzDLqApAbHK4lkqD7F82LnyPm8EERA== 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=6Ovrz/Y1TMf2j7ub+EyEFa8yzDBCM7g7YBp4FOMhr/4=; b=Edrjo/65H3ShV3y10iEoczKkEinCx7BsOWN51oFUQNkSbyzfiqt/juve+TD0PsbBLcVaP9FdoAsSDTTzxe0DKXiwlQ/knFDZIpH4m6I1nQ8ZTm9eBRFanqZQrpjZd0MnlrxcjcC+QbCJnCAG4/dUJ2KK/Pj0v519H2fRmnKkOZg0/XINsf5/OuG5INc/SwMjvhiR/Le2NUBw5pmADAbYN1QizbPwkzjY6rgYby5Od2Bz1RpLZpYMeBdtVmuAz5Rax9/o48kFLU3pbIFdYGzJ4xInilHAoanoWsckjDBZXHf1A4zX/FJbptN/X9SkZup//wcHgRQRa8sD1wp1ZIFjtg== 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=6Ovrz/Y1TMf2j7ub+EyEFa8yzDBCM7g7YBp4FOMhr/4=; b=aw1q50whlt6pRsj2N/yM/de7zKhqVAAN2UZswb8a7roYVVBIyYBcNxJgfyppCm53mSSn2/Qk+bdxpYxlUG/X2J4bNHIMSr7B9YovapE/2ALqHkIxEW918CjIApY3b+ZS4Pvs7cfk2IjDGqu89MZLONbT+DPv3IlNUuWslVF/Ifg= Received: from SJ0PR03CA0045.namprd03.prod.outlook.com (2603:10b6:a03:33e::20) by DS0PR12MB6413.namprd12.prod.outlook.com (2603:10b6:8:ce::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8466.26; Fri, 28 Feb 2025 09:51:01 +0000 Received: from BY1PEPF0001AE1B.namprd04.prod.outlook.com (2603:10b6:a03:33e:cafe::9b) by SJ0PR03CA0045.outlook.office365.com (2603:10b6:a03:33e::20) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.22 via Frontend Transport; Fri, 28 Feb 2025 09:51: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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by BY1PEPF0001AE1B.mail.protection.outlook.com (10.167.242.103) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 09:51:01 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:50:56 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 17/31] KVM: selftests: Add x2apic mode testing in xapic_ipi_test Date: Fri, 28 Feb 2025 15:00:10 +0530 Message-ID: <20250228093024.114983-18-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BY1PEPF0001AE1B:EE_|DS0PR12MB6413:EE_ X-MS-Office365-Filtering-Correlation-Id: df880718-8102-435a-c28c-08dd57dd68af 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: scH60mIGFPrD4X08jGOlLGTxrotIbrpQ3VLdCB6gxSk+6JYiQiPeHSnS9LYI7+XzR+1G/mY8ul/Tk1mElJPsOgiT1w4VULq3g3fT6wqKLXqwmgzo4aN7hafNgx61OKA3GR0XYrQheztijyOav+ZhjFNraOt79IoNUUdCSDWHaXYUXdgx7QVU8bgGtdbwloIvQM+axmC+ZJrOzCFc0nLX0oBiyhgKucY5tTI09E0xqMoIOtNkJGHylbiatc11efIDeGc2wMxLBHv1knmsD2CN7hwcPJkdZqrNnV9CsKY2PjSOxH6t8ku5g0yGBb17hhWdWmFh9yhDceYB6dMacbl27Se3esR6vPWVqRPmxERmhxKaAHNF1aug9d49/tSNTJoNH5ThRUqfPimkm3hw7DbtcDqW0EDn8k05m073Syrd7ARW3PLwRZJvPo+xZ/hXJky9EJLSZmmU5hXL3voCKNQNZGtVmhtyr2y1SRpX1ic0iw0zca7q103Msx/3d1xR7OnX/O5L+jrpRtAQtreSyNTdeGDT1vFh0tXdSzPyeeHnij5m0LBuFeDiVdSymikgOZ6ElwahK5asMqNbCJT3WxCif4GPIaYXrf3F4qBUUkXm3qjk/P1YMytEWbaqjiIY1LKZQHm83MWpRLOqb/AQVcZqSYszMyeO/XIu2brsc8X+J8rpqq8G/IAzb76scoA7bvrnYdEKWVjq55Pot0pcq4A7BsI09fhK+D+WjzPIPChJUJXOLjYVrQ+x/DVFZ3/4P+JB7xIYVTRtmIf6kCW5Zc5cdSahB0TABDIh0uXZYnB2d3hV6BDhYlu6S05urcNlXltAjMNHisKiPUOR0iQScL7bXdzBItueVmJRPPXDKoLnFfhaIAIxOPVJNG4+RVXyQ3kc2BbCrmtD1n1h2r82Zi4qntNiBuKARMWIgRPTOiQyXwVBKw52ArVnFSmoAvFmxWHY1eCCAWBG8sXLs9J5An/xSBTBNx7qoqGyDF4ZybMm08ntzfyWJao0Fr7xv/veFrmKnwO2uUZ9QQsFCaR/swqqOKhfyktZVNIn1ScMzvlxcWMZQbB2bRxHWjvqzIthUzzLkdv0qyGspujTsKbKHaOJjrKX6m+HTBhvtMbDe3sE7bMaJ3L66jyNuCi6SX51AbCz8g/VmzNVl4eYrOQWAshA70K/8ITihHNgCOItkU5UL53hJONSqactY2aSBb3Va1oQB0XqhBvavvetsdbvkNPp9aRFnLaQrGo3XmK/AjY1OrmGt4a4fPlZL6ec9VgG1lBNSGpoB4b+cu6Jr99+DQNTIFVTf+tZI/BQR8B0omLjE4t0aUcN7s1u4Im8rKRAGdtaVImT+1Jo3nxFcguV1YxeAkjPZpmzSClJpI3UhxCNMRo9l9aZZEsC+Z8VS6jC+CtOvG8E/MNKdDeqc0INQ5F4B/1+ZM9iSE3MsgZWwhlbQbG4gvVXdh1HoU2ZfLinJjQKf9xdP/PY8Z9fob1Cx6q1Q23ejVOhGBkfvIUz306a/e4= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.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: 28 Feb 2025 09:51:01.0497 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: df880718-8102-435a-c28c-08dd57dd68af 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: BY1PEPF0001AE1B.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS0PR12MB6413 Add support for testing x2apic mode in xapic_ipi_test. This allows extending the test in future to support VMs which only work in x2apic mode such as Secure AVIC enabled VMs. 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/testing/selftests/kvm/x86/xapic_ipi_test.c index a76078a08ff8..024514089766 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; +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(); - data->halter_apic_id = GET_APIC_ID_FIELD(xapic_read_reg(APIC_ID)); - data->halter_lvr = xapic_read_reg(APIC_LVR); + data->halter_apic_id = GET_APIC_ID_FIELD(apic_read_reg(APIC_ID)); + data->halter_lvr = apic_read_reg(APIC_LVR); /* * Loop forever HLTing and recording halts & wakes. Disable interrupts @@ -103,8 +126,8 @@ static void halter_guest_code(struct test_data_page *data) * TPR and PPR for diagnostic purposes in case the test fails. */ for (;;) { - data->halter_tpr = xapic_read_reg(APIC_TASKPRI); - data->halter_ppr = xapic_read_reg(APIC_PROCPRI); + data->halter_tpr = apic_read_reg(APIC_TASKPRI); + data->halter_ppr = apic_read_reg(APIC_PROCPRI); data->hlt_count++; asm volatile("sti; hlt; cli"); data->wake_count++; @@ -119,7 +142,7 @@ static void halter_guest_code(struct test_data_page *data) static void guest_ipi_handler(struct ex_regs *regs) { ipis_rcvd++; - xapic_write_reg(APIC_EOI, 77); + apic_write_reg(APIC_EOI, 77); } static void sender_guest_code(struct test_data_page *data) @@ -132,7 +155,7 @@ static void sender_guest_code(struct test_data_page *data) uint64_t tsc_start; verify_apic_base_addr(); - xapic_enable(); + apic_enable(); /* * Init interrupt command register for sending IPIs @@ -159,8 +182,12 @@ static void sender_guest_code(struct test_data_page *data) * 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++; /* @@ -356,10 +383,10 @@ void do_migrations(struct test_data_page *data, int run_secs, int delay_usecs, } 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 = getopt(argc, argv, "s:d:m"); + int opt = getopt(argc, argv, "s:d:v:me:"); if (opt == -1) break; @@ -373,13 +400,18 @@ void get_cmdline_args(int argc, char *argv[], int *run_secs, case 'd': *delay_usecs = parse_size(optarg); break; + case 'e': + *x2apic = parse_size(optarg) == 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); } } @@ -400,7 +432,10 @@ int main(int argc, char *argv[]) struct kvm_vm *vm; uint64_t *pipis_rcvd; - get_cmdline_args(argc, argv, &run_secs, &migrate, &delay_usecs); + get_cmdline_args(argc, argv, &run_secs, &migrate, &delay_usecs, &x2apic); + if (x2apic) + migrate = 0; + if (run_secs <= 0) run_secs = DEFAULT_RUN_SECS; if (delay_usecs <= 0) @@ -410,7 +445,9 @@ int main(int argc, char *argv[]) vm_install_exception_handler(vm, IPI_VECTOR, guest_ipi_handler); - 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); params[1].vcpu = vm_vcpu_add(vm, 1, sender_guest_code); From patchwork Fri Feb 28 09:30:11 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996067 Received: from NAM12-BN8-obe.outbound.protection.outlook.com (mail-bn8nam12on2075.outbound.protection.outlook.com [40.107.237.75]) (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 3F64B25A2B3; Fri, 28 Feb 2025 09:52:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.237.75 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736327; cv=fail; b=tdC/pUJL2QYKnsoQso2bXVFLYk2KKzAaJkZPXyDnm9ZjFxxgg8wmduWxetyaK59onXaNdu76vv7UpkCE+kam4foTFoiOXt9kdcSWqUDkSM/lxzZV4gRifI9oXF1xBHjaoZigQS3AOzTgoJ0FkzvYwehJYVuPvSIvqPizyKCmgVQ= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736327; c=relaxed/simple; bh=byXX1hCFSvdZ8+GlqrxiBIpdijbztrBNOf9CgVFjjPw=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=llGBwJPwxqy0Y3m4Eg7GVB86Gw/7g0rvnS0f3OSVqFVt7o4+B4uHlhcD2/nNJV1qxbFx+qDGw2/4Y1HzpnjftS1Dgo/BWlltEnzrWPQqxPhgYxs2hlIyUKA5gJWbJyLH1qZ4D5ctYwy4+fQhIgor0UHido5m5kO1iFGRsbUKXTE= 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=F6kRq+lI; arc=fail smtp.client-ip=40.107.237.75 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="F6kRq+lI" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=pn3OPr7hZXChLylgFEU77xYBWlyXz3ivCpGnCWHUOqUR9HrEjsMBYAwZu451b034SRDQDqeQp28spmzjA7o93g8Cap/wvrukZrF+z0tai12W4oHsfY7C3+8kQs1CpYAhkkRoJUigdzeClPfGnVj7iA2hZjZeV3BqMxLqf9Wk8BveVQHLttiL+iyd06FDAnrB8g7ch0ghRq5iJb8ZVU3TD7TdyIRcqMwi49pY0Z2VW1lO8E479kkbFoweLc2CAqyoABpafMSUru5uulyXSBjYNPjCTQq8P7nHB4Bc/hEzFVtvQFGCoqTx5ez9CoG8wIP/+ZSOpUo2ywISH0fG18OHSA== 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=oxsUGVbbPU9BDJOQXUr8QwQ4iQLDKX4Op/gU2WbUsHA=; b=xq6rFxrhjgVhlst0tTq9ra0+V6wZlEI0zraTXI4viTdZhhZTO/PwzaqUkKyow2YE3S4fxhrq27JRbp1NsVnVyXTcaIpd+EUUAxfz91NKNgCAY0E/uGpKRYK0/UEKgcui77ZR2hL7zIOwbNgjs9bzaL9dHQWFpveLZZIz03iSVuFM4Yb26V8+GCHWO9OUrkBAvktaHTSKsLplYPglwuvB/f+Xr8l4nG5hcvkRJz2hkbZgwc8AWq+0DZsZROJLUcTtkN7gzv6T0wyTzshnuux1lt0cd0e+GWWIKf0UDRG1JFp1cKavhAxaB5xhouJSAqQ5oM5C8Xmxivvxx0XHIEinvA== 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=oxsUGVbbPU9BDJOQXUr8QwQ4iQLDKX4Op/gU2WbUsHA=; b=F6kRq+lIPI675shdK6mTX4nYBO28fpKF0s+CPDJ1eW0DXlGlphzd1FNdWy/zrEejtsrwwR+M1jZ8XGiWprMHT7xxyOw1Cglr34LxBgkkxN0Eb9DSimT7A7atVXl3/mXcmOC4dI3l2PEDt5OuovEnqayKOxQvYi8Fdc15BTdvVEo= Received: from BYAPR01CA0061.prod.exchangelabs.com (2603:10b6:a03:94::38) by LV8PR12MB9112.namprd12.prod.outlook.com (2603:10b6:408:184::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8489.23; Fri, 28 Feb 2025 09:52:01 +0000 Received: from BY1PEPF0001AE18.namprd04.prod.outlook.com (2603:10b6:a03:94:cafe::7c) by BYAPR01CA0061.outlook.office365.com (2603:10b6:a03:94::38) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.23 via Frontend Transport; Fri, 28 Feb 2025 09:52:00 +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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by BY1PEPF0001AE18.mail.protection.outlook.com (10.167.242.100) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 09:52:00 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:51:27 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 18/31] KVM: selftests: Add SEV VM support in xapic_ipi_test Date: Fri, 28 Feb 2025 15:00:11 +0530 Message-ID: <20250228093024.114983-19-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BY1PEPF0001AE18:EE_|LV8PR12MB9112:EE_ X-MS-Office365-Filtering-Correlation-Id: 8c8e252d-abc8-47c7-eeb6-08dd57dd8c37 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|36860700013|1800799024|82310400026; X-Microsoft-Antispam-Message-Info: 3e+XUTutKhT/0JtTVX9hjZsaKyUJtEE5ySLr0EGOQjAyG/lxY5EzgRpnUWsK579E5+j9iV3E51w3XtjFZkOvmgo0deZJiPqzIPuiJfx6JY/5tewkXVjIMhFpIwxPYid4SmNjtuW7tLsVPMYyfIerJjWad4kWHiKqN3JND6cOJVX0mZ3yMMC6Vobk6hxADcfPKFhvxLVuUKjUUTxooTDNY3jFZAVAGSiLYJsuAraqvRJ8TChpjW1+bZIXTMY9rAxs9bk+eB/zcMvxmGJdoJNrcgYQ7bXjpG8su61Cr+clOQbkp925qrgkhD2L6Df/YhUTJ7LVFNEHWcrA3CL0btWzHIwZ88BLbMVeqzp9Tme9+R6CWfqZQJVL+/0nQGubAHkrvDbkCw8z0A9zZP/6mDYZLUj3fdD4W2iZZAOBSnO1Gz2pTN4hFHxxgjwdiVt+A6T4Fc7hbUcCs2n1WnMqG/WbDuwMZprZudDu98KC+sywVa9IqIVmRHkDnNoKtrNaZvDU03aJ1/VbGAnw3EVaUpzCjjQnMg0mL8W3jsfHSJvw8N0LZ7rj8WLcdyUhtZKzSH0q5ok1gKsLLxztEw2q8voozobm6V1s+OzqYp42pve2Ob5+YLGtlx2LqVlMOYjuPb1GC60ECqMuJaAEgQwoFd0cBbe+Umg3NzklGsyysuHQOo82Vp2KOXp0dPIZIeUJqdSieWa7xMpqMsSKKUIa4eIenlb4LpXxbuZeDuqLUPMUnIIQxf6Zyr4uF0J9eG7UK/uyhVnpIrmn3rTMpJqaabwICTKkg6IUtxSdLm/keZr6ZAGFGT+K+MUzMrZCa+JMZqMNdBFL22mUpW2Fb45d9rx0e7eUG/M7ja6l0x9O8rFwDZJwqrQq3MTCbIMz1uYUjtXruQlQqVQMfvzwmBLXkll/KovPFzVI7S8/cCZaVbvA7emgMTSwK9ql//mZfLNPVpXp0LhlElvpvXf2yO3zve4vf8hNL4eGBh08rZd4Ta5A0BFhFD4jjA5O3D5UkqIRiJeNPeYnbIR1ppohKzt2zOF9GIPwTNDLh6tgsfHOCPeOBck9PEPxNComjYHZ6qUYCXLSsbpc6b8X0vj+geJJf06UK85sw2y67ssn7i4Gjpkeyzq3Tp6v1oYqQBC3ifo/UDUQptxgxsqfss2YX+58fyqZ0RTTTsCzPMq+OD3U+IJvKffBoPJG/MugqWmMI/z4/QAgEy9pFB39FMmgY4ZDERBh3AU7UH8deFFNaoMHumsfHIrp2OsAMnbtEYCFpVqj56y14TgKMfpU4AtEh4RsuV7kBKbVys+O6SyND8+QXnn2yiwxEhIa+oVpeDe99+oYaf1EXDOy+3uwdzqW3IuW/ahh1Hm7FKZxGCNxKI6UBH+771nRmPW3N1xKbxk1GTq3FTTWuRYf1OvPRwaEvraTDhDjNjAygWU0Nei4/2BXa06et0jvOAk0FjEyMNC0b9UojvN6BbSvTjhhOjLGcmzut5qc1C9yZWhYzyLsCwme5wQD8i8= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(376014)(36860700013)(1800799024)(82310400026);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Feb 2025 09:52:00.6780 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 8c8e252d-abc8-47c7-eeb6-08dd57dd8c37 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: BY1PEPF0001AE18.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: LV8PR12MB9112 Add support to test SEV VMs - SEV, SEV-ES, SEV-SNP in both xapic and x2apic modes. Convert the stats page to a shared page so that it is accesible from host. 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 bd963ff49bf0..a160e1ac7cbc 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -609,6 +609,7 @@ 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); +vm_vaddr_t vm_vaddr_alloc_page_shared(struct kvm_vm *vm); 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/selftests/kvm/lib/kvm_util.c index 4f3240976f6c..34e586d4fec4 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -1500,6 +1500,25 @@ vm_vaddr_t vm_vaddr_alloc_page(struct kvm_vm *vm) return vm_vaddr_alloc_pages(vm, 1); } +/* + * 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 within 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/testing/selftests/kvm/x86/xapic_ipi_test.c index 024514089766..3a54d828dc69 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" /* 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 the IPI * arrived at the destination */ -static volatile uint64_t ipis_rcvd; +static volatile uint64_t *ipis_rcvd; static bool x2apic; @@ -93,6 +94,7 @@ struct test_data_page { * to determine whether APIC access exits are working. */ uint32_t halter_lvr; + uint64_t ipis_rcvd; }; struct thread_params { @@ -141,7 +143,7 @@ static void halter_guest_code(struct test_data_page *data) */ static void guest_ipi_handler(struct ex_regs *regs) { - ipis_rcvd++; + (*ipis_rcvd)++; apic_write_reg(APIC_EOI, 77); } @@ -175,7 +177,7 @@ static void sender_guest_code(struct test_data_page *data) last_wake_count = data->wake_count; last_hlt_count = data->hlt_count; - last_ipis_rcvd_count = ipis_rcvd; + last_ipis_rcvd_count = *ipis_rcvd; for (;;) { /* * Send IPI to halter vCPU. @@ -200,19 +202,19 @@ static void sender_guest_code(struct test_data_page *data) */ tsc_start = rdtsc(); while (rdtsc() - tsc_start < 2000000000) { - if ((ipis_rcvd != last_ipis_rcvd_count) && + if ((*ipis_rcvd != last_ipis_rcvd_count) && (data->wake_count != last_wake_count) && (data->hlt_count != last_hlt_count)) break; } - GUEST_ASSERT((ipis_rcvd != last_ipis_rcvd_count) && + GUEST_ASSERT((*ipis_rcvd != last_ipis_rcvd_count) && (data->wake_count != last_wake_count) && (data->hlt_count != last_hlt_count)); last_wake_count = data->wake_count; last_hlt_count = data->hlt_count; - last_ipis_rcvd_count = ipis_rcvd; + last_ipis_rcvd_count = *ipis_rcvd; } } @@ -383,10 +385,10 @@ void do_migrations(struct test_data_page *data, int run_secs, int delay_usecs, } 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 = getopt(argc, argv, "s:d:v:me:"); + int opt = getopt(argc, argv, "s:d:v:me:t:"); if (opt == -1) break; @@ -403,6 +405,25 @@ void get_cmdline_args(int argc, char *argv[], int *run_secs, case 'e': *x2apic = parse_size(optarg) == 1; break; + case 't': + *vm_type = 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" @@ -411,12 +432,39 @@ void get_cmdline_args(int argc, char *argv[], int *run_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); } } } +static inline bool is_sev_vm_type(int type) +{ + return type == KVM_X86_SEV_VM || + type == KVM_X86_SEV_ES_VM || + type == 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; @@ -431,8 +479,13 @@ int main(int argc, char *argv[]) struct thread_params params[2]; struct kvm_vm *vm; uint64_t *pipis_rcvd; + int vm_type = KVM_X86_DEFAULT_VM; + bool is_sev; + + get_cmdline_args(argc, argv, &run_secs, &migrate, &delay_usecs, + &x2apic, &vm_type); + is_sev = is_sev_vm_type(vm_type); - get_cmdline_args(argc, argv, &run_secs, &migrate, &delay_usecs, &x2apic); if (x2apic) migrate = 0; @@ -441,9 +494,15 @@ int main(int argc, char *argv[]) if (delay_usecs <= 0) delay_usecs = DEFAULT_DELAY_USECS; - vm = vm_create_with_one_vcpu(¶ms[0].vcpu, halter_guest_code); + if (is_sev) + vm = vm_sev_create_with_one_vcpu(vm_type, halter_guest_code, + ¶ms[0].vcpu); + else + vm = vm_create_with_one_vcpu(¶ms[0].vcpu, halter_guest_code); 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); sync_global_to_guest(vm, x2apic); if (!x2apic) @@ -451,8 +510,10 @@ int main(int argc, char *argv[]) params[1].vcpu = vm_vcpu_add(vm, 1, sender_guest_code); - test_data_page_vaddr = vm_vaddr_alloc_page(vm); + test_data_page_vaddr = vm_vaddr_alloc_page_shared(vm); data = 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 = data; params[1].data = data; @@ -460,10 +521,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); - pipis_rcvd = (uint64_t *)addr_gva2hva(vm, (uint64_t)&ipis_rcvd); + ipis_rcvd = &((struct test_data_page *)test_data_page_vaddr)->ipis_rcvd; + sync_global_to_guest(vm, ipis_rcvd); + pipis_rcvd = (uint64_t *)addr_gva2hva(vm, (uint64_t)ipis_rcvd); params[0].pipis_rcvd = pipis_rcvd; params[1].pipis_rcvd = pipis_rcvd; + 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 = pthread_create(&threads[0], NULL, vcpu_thread, ¶ms[0]); TEST_ASSERT(r == 0, From patchwork Fri Feb 28 09:30:12 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996068 Received: from NAM10-DM6-obe.outbound.protection.outlook.com (mail-dm6nam10on2060.outbound.protection.outlook.com [40.107.93.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 46AC52580CE; Fri, 28 Feb 2025 09:52:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.93.60 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736343; cv=fail; b=PnY09qBA8LTV8EHNhvfD9QL6ntje8z5BfBhoWDcGFiCozZ3Ilh0ZZKeG3QNOdZQuSYKwim5xjtxzdkoz0zOEB98T4d+AKL1rAnxznr/KCUc0FYLVpRWmnyjn8E2IOmrkbsHZJrkShdIyP0/xREvmsYNE3maMpxlwTFkLwB3RJPA= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736343; c=relaxed/simple; bh=LSEJyd7RiklyOKaxcJ/MrPG3wKoulWwh+ZAn6WLuwt8=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=lulTSydn7ORp4i2KT5+17QKCDuCoW7oAfUgqaWnvQiol/K+e+P6biKsvC0xWgA6xMCPK9J009KywohwkVFlyXqu2K2W8dhETwNzzB96pw8PsHVuQHaWzfJ5BAcfsVncVobBhd5Ftl3GMCuW8Rk+/bF0oniQ/wRihV7e6U6AlibM= 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=3AsQ1EWG; arc=fail smtp.client-ip=40.107.93.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="3AsQ1EWG" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=r+UYOqeBnoXU+ujLEMzhHRxWm2TbPtQU33OwzArp8ACe502esH6kqQfEiI62TPhb5amvzKeMxDmEvZkbqWfijybX0t6QyodQEWCNee2KZVx54gyUKAGihQZjNVRJWfcDTc4Fw3hk83ttRwPxaDT28XQwb6thUtPjHm6fps1kW/nMY8gPjDRGNP8UCQES32lddp/kSoMtynfGhmyHo/rqAosXSJz21zgTA8XgxzpOh7i8LmM392bw1dpxedmGZ1wQ44t6Bn/h+WnZ5XScv86RwSnv8YqSKT45G9Olz4d4hZcSg5aqKo/49Op3ENkHtL7dKpvfqX0xSowcAPvS7D7qiw== 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=FlVIfj3eavVfdhwaV8diMiha5/TX7z4HTfxyRreuYJI=; b=cCjINs4z1u4zT2DmbOKtdc1vqSdqCJfAI18T1CxrkSfFgZmkA9tDg55suNSzt3StaPTUYtrsqDU5qcXlDkHCmWg8lpqPOhvxE30laKhn9s8tN0xRizqWUYDa6TQu5Fue6mwQApimm1z4Ax086Go5pBEKWqZe8mlkorkeymSANHTbqC00z6F35VZ3nnre2+Z62kjfIFdAh807XHQvRPoker9X+WGavkTfV5yu6LPk/3gPKLXi7hGveGFVt/JK9NFK/x/Zfc6Q84w0dkhcFcsBt+Tn3U3DGqifZ85S0FU4BBCMyysgQupaXCAO8ZmHaLcFQfIKOUrfUqr9pd1Ou7eqmg== 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=FlVIfj3eavVfdhwaV8diMiha5/TX7z4HTfxyRreuYJI=; b=3AsQ1EWGmUd7Okj+X5qPzuN9BV6cHyVVzPTR+2G8FYstfOeNiU5TPJCLQWjBwrEzNz4H+YuAIkOk4yc7wUl2YB3hz5FY/pA8sszoTJmPeZ5l4yE9a57eFNkWSmIpva+eReGhF8DaaMlhgilgVioD0Bpivq/ZUCW61cq9+XDL2FY= Received: from MW4PR04CA0187.namprd04.prod.outlook.com (2603:10b6:303:86::12) by SJ5PPF75EAF8F39.namprd12.prod.outlook.com (2603:10b6:a0f:fc02::999) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8466.21; Fri, 28 Feb 2025 09:52:16 +0000 Received: from BY1PEPF0001AE19.namprd04.prod.outlook.com (2603:10b6:303:86:cafe::4b) by MW4PR04CA0187.outlook.office365.com (2603:10b6:303:86::12) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.21 via Frontend Transport; Fri, 28 Feb 2025 09:52:16 +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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by BY1PEPF0001AE19.mail.protection.outlook.com (10.167.242.101) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 09:52:16 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:52:11 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 19/31] KVM: selftests: Add Secure AVIC lib Date: Fri, 28 Feb 2025 15:00:12 +0530 Message-ID: <20250228093024.114983-20-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BY1PEPF0001AE19:EE_|SJ5PPF75EAF8F39:EE_ X-MS-Office365-Filtering-Correlation-Id: b8c5d7e1-d587-4c3c-f286-08dd57dd9566 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|36860700013|82310400026|1800799024; X-Microsoft-Antispam-Message-Info: DDfxNycqnHJ+wpYtZZoYE7ozrkiDHdmI1s/64qmIslSwak/IsHJ0UDPBPu9KvYn3aZhCSMMYb4AXZiy7jtUndkxPfKqhb/8Fud72NV9i7GM5vqOkPxfzbZQChqfFI8ExbTc+9n4iknOqJmwLDPD85GGCD4tGwTGnl+MuJNdcP6rmCCumGcEwHTnm+BREe+bV4FBRBfk34baRy43e3t+xNp0Z/j/VRfeyFNFzr8phNBteKRsV23UMRPtslO53X56k2d+BamWCO71C2PX1ghKP7kc0y8tvObworQon36O1KLQlqHlew9UYPSRyPAJ8YH00y1M/OLiZUKKdY+fCHyEsG6xuNzajVwKiyUqd/CWJsPxLPx1T0I/N5s8AaA9TxudTsklNg/KYd341vLvo0WuLucbePIKih/AuUUBtZb54CPd0FJFcC0C5eyMrXtP8ILxUM9r+ZYmUHNJVVkDN+4D6FLPHnqsEmu5lm2ERn8sVMAuftHgw80vtvNbH9b5Yu3ml3cVyuLyYrKS0/RVSkJdwjp1vOYdkdl/KNtYQkKjnqk94+rZckNSXP8NmVpunCmKGlROU1b+46cq68sDSSLEjUQE3q9tDvaGcgfPLUnlps2HnCxuAghosal18/N7LYOIMHbWPhdKUbdXVGVgEMYXhAiIfEinsSSFKqAPpCro+evtCKnYQirSNky7QPX8CEvp5YxswL9q6K5KPjgYDJ/ErLSy4JDrW7AXrBUSjVEH1bejZjB1jEnxD7+Ff3w2xzCKw2ARTKYtw+Eb+prTqv0mszlLZNkytFONLzLqacdKYHGm0aphUaP1hAyYDq/k6jsurfHD0mNKztrEiDfc6dn8tpex1yTayqHs6kd2fqepFNf9BjLKizGQuZ/p5blK/lOhnKQ8zkmrtgWaYFPZlUyRTe9Px/UCJ7XGNiMvMdPcD4UrL5pZH2+YrcoomeUxXIlHVbTuhbBt8va0seqPdMaS6XlIbrUzFsHQRtlht8Gl/EhLKJ3F00blWtgf37NJaCbmtvTLKlXODYWE4S2gO3QKN9MARJIY3nAJHLvxj4X1oqdUBsHSbuKttcZlMFtUffRskCwExAu5IKihNspabHxhVc0tLU8p8iw1SGopwU4uYVVL5ur7J8w0P4CNCH4kbcrabGf6u8OsaQjV1af8GMLeohKibAkmTQfZeUXKk8pHYxspVxghEM1rks1lqPCStLEHqzN8K/KJ/NzaLX/p2x5ZAiJCWnzi1MDh6f2K0pNS1VP5o2pt8hgpcbkMiNlHZ9rNeYdzVn2KE7/wDz4/TYt4ptlc0XEo7YiqqgX+cScDlHjj11e9y2hkyt8ODjEkGqDL0VFnpVdqBL0BsGySesdLjlK5DauIILJoR3uLhLE1stkHlaP73cbHBcqOWjk5wbHI6xfLatjLYC1Gwha8W2Z6Y2Fc4ZeS6b6B4oV6CG+3hZbeGuHQYaZs0dIBlnr+tRY+UiajaOaMm0MrItotGcBuniHTThnZb7e93CIs1FEB4Czw= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(376014)(36860700013)(82310400026)(1800799024);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Feb 2025 09:52:16.0856 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: b8c5d7e1-d587-4c3c-f286-08dd57dd9566 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: BY1PEPF0001AE19.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ5PPF75EAF8F39 Add Secure AVIC lib which provides apis to enable Secure AVIC for a vCPU. In addition, add guest APIC backing page initialization support and helper functions to access APIC regs from guest APIC backing page and from hv. 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 | 206 ++++++++++++++++++ tools/testing/selftests/kvm/lib/x86/sev.c | 15 ++ 7 files changed, 255 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/selftests/kvm/Makefile.kvm index 5a67e79ae848..50bd78e03d9f 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -25,6 +25,7 @@ LIBKVM_x86 += lib/x86/insn-eval.c LIBKVM_x86 += lib/x86/memstress.c LIBKVM_x86 += lib/x86/pmu.c LIBKVM_x86 += lib/x86/processor.c +LIBKVM_x86 += lib/x86/savic.c LIBKVM_x86 += lib/x86/sev.c LIBKVM_x86 += lib/x86/svm.c LIBKVM_x86 += 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/testing/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, uint64_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) +#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/testing/selftests/kvm/lib/x86/processor.c index 197110ff1380..2d6105b1f610 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) int kvm_arch_vm_additional_pages_required(struct vm_shape shape, uint64_t page_size) { - if (shape.type == KVM_X86_SEV_ES_VM || - shape.type == KVM_X86_SNP_VM) + if (shape.type == KVM_X86_SEV_ES_VM) return ghcb_nr_pages_required(page_size); + if (shape.type == KVM_X86_SNP_VM) + return ghcb_nr_pages_required(page_size) + + savic_nr_pages_required(page_size); + return 0; } diff --git a/tools/testing/selftests/kvm/lib/x86/savic.c b/tools/testing/selftests/kvm/lib/x86/savic.c new file mode 100644 index 000000000000..f4a765b6040a --- /dev/null +++ b/tools/testing/selftests/kvm/lib/x86/savic.c @@ -0,0 +1,206 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * Copyright (C) 2024 Advanced Micro Devices, Inc. + * + */ + +#include "apic.h" +#include "kvm_util.h" +#include "sev.h" +#include "ex_regs.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; +} __attribute__((__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 = align_up(sizeof(struct guest_apic_pages), + vm_guest_mode_params[vm->mode].page_size); + + vaddr = vm_vaddr_alloc(vm, sz, KVM_UTIL_MIN_VADDR); + + g_pages = (struct guest_apic_pages *)addr_gva2hva(vm, vaddr); + memset(g_pages, 0, sz); + + for (i = 0; i < KVM_MAX_VCPUS; ++i) { + entry = &g_pages->guest_apic_page[i]; + entry->hva = (uint64_t)entry; + entry->gpa = (uint64_t)addr_hva2gpa(vm, &entry->apic_page); + } + + apic_page_pool = (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 = 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 |= 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, uint64_t val) +{ + *(volatile uint64_t *)((uint64_t)apic_page + reg) = 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, uint32_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 = savic_hv_read_reg(APIC_LVR); + savic_write_reg(apic_page, APIC_LVR, regval); + + regval = savic_hv_read_reg(APIC_LDR); + savic_write_reg(apic_page, APIC_LDR, regval); + + for (i = LVT_THERMAL_MONITOR; i < APIC_MAX_NR_LVT_ENTRIES; i++) { + regval = savic_hv_read_reg(APIC_LVTx(i)); + savic_write_reg(apic_page, APIC_LVTx(i), regval); + } + + regval = savic_hv_read_reg(APIC_LVT0); + savic_write_reg(apic_page, APIC_LVT0, regval); + + regval = 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 = x2apic_read_reg(APIC_ID); + apic_page = &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 = rdmsr(MSR_AMD64_SECURE_AVIC_CONTROL); + exp_msr_val = 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 == 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/selftests/kvm/lib/x86/sev.c index 24aaa75ec450..518e30275960 100644 --- a/tools/testing/selftests/kvm/lib/x86/sev.c +++ b/tools/testing/selftests/kvm/lib/x86/sev.c @@ -307,12 +307,27 @@ struct kvm_vm *vm_sev_create_with_one_vcpu(uint32_t type, void *guest_code, return vm; } +static bool is_savic_enabled(void) +{ + u64 supported_vmsa_features; + int kvm_fd = 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 *measurement) { if (is_sev_es_vm(vm)) ghcb_init(vm); if (is_sev_snp_vm(vm)) { + if (is_savic_enabled()) + guest_apic_pages_init(vm); + vm_enable_cap(vm, KVM_CAP_EXIT_HYPERCALL, (1 << KVM_HC_MAP_GPA_RANGE)); snp_vm_launch_start(vm, policy); From patchwork Fri Feb 28 09:30:13 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996069 Received: from NAM12-BN8-obe.outbound.protection.outlook.com (mail-bn8nam12on2087.outbound.protection.outlook.com [40.107.237.87]) (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 AD89A2580CE; Fri, 28 Feb 2025 09:53:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.237.87 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736415; cv=fail; b=BxM/jahfVQOm52s1BGO7hFcywiIxaEqBN+4JiTgEJ7BgQEfXi/gZLVWI9M+qFEZNu8NMi+A9AhDuANrpnFDlS0t29CS7PpMc0ZZlWLoHSeXBnxlwyOEJo1cIgrjLeUL2X/xcQg7i7ytYU8rq8ukI5nuWlbYpoTmRoU8m2gf+n9A= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736415; c=relaxed/simple; bh=9nkeusDo+mnJavezRsOmXyKU9uVXIz32DGnKGaZDjr0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=J/rF3z/sENS5cgsEq3CHh2+wM85qdrgGW8MFklepkzc0qkiPIdGe1Ybu95Dq+jPIKT0+znDDuxPsqg5si6YEoSgottlXQaPU7O55MOMrvAvYcstVmUXB9J7mJ9jXZP5mHK6jcY2IWrq0x5gfwWCRwEMGVfcAN8G+yu7O/4AT4lc= 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=yHC+t9hI; arc=fail smtp.client-ip=40.107.237.87 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="yHC+t9hI" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=Vmd0SUy2ggJV/yHeLmEwCL+Ba9/JzjQ8YRIA7rHtZ2KtjCp1j2pjjulaCc7AgqZmgMxsix6QVj4qXwkpmwKUJuWabS3kHoTUL25bQ4mTubOKCGZuTAU+jpF8gSxHtbEPM8EJUdUbCKdzp5ZDwxFW54JDuGRQ2+ZLloBSZZdWEwbG70PIkQXX3Y1KPSirJkYFIRedyPzixnPnCXtGFwDoAN8sd1s+3GuEIwQ3tymVlW0JFk5twJKlMXJZ/fgP5aKb2pKQ+A4fSopWAroF17mKM3eZQTZ+PDDHyxixTOqFg0QRlFL/dx2jfuCYjZG1xAmSYrRLe4qWI1ubDPtTvqjOwg== 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=lenrXz8ZRl7sZ39Vx5ZAlgu1sD540YDxOqFepZm5rj0=; b=NY0Ex+n5YUoYUy9RR1jvjW2gBvEKEQQzQv4kWdduTgwWnBbh6YC9p64jq+qsdHhEMD1RAY+SN/jBWuVv42FB5p3cohWE/WeWgxrLHC0H5BiTioW8+Qxrb8wFnz60CKHE+XpW1Y58fLBintYo/5Ta5sVZ49dLh04l59sbOIU908QmrR7BjWc8fJphz9h/LveCSdhiYoOV1fkbGVQLQ2Qyh3TbILXQDUETfnBePTi9ZwXNGk59/PglQL2YAQQPZaJ5fSikZ4a1HdES/oSCUopf3zrLhqzy/eWLWTqg/EwhksHnYF4Pb5p5biM3audCJPJ/CCbBGLR9Y7l0ZOM/pf5rEg== 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=lenrXz8ZRl7sZ39Vx5ZAlgu1sD540YDxOqFepZm5rj0=; b=yHC+t9hIvsknN5ihwuQG86esGaQvLqp2TZ5ZrivGDSQTdA2he5K1TjeS4n1LAZSSlfnSOyDiP27fbkPoZnN+ehO+m+9xS4GzSH14YBkcu8tbNDf8uWXISc2nCf5DT4v2eRGrXO7h+E3DPvrvgMrPZ9IT3ZxJI+1BSCt5/OgiUsc= Received: from BYAPR07CA0034.namprd07.prod.outlook.com (2603:10b6:a02:bc::47) by SN7PR12MB8819.namprd12.prod.outlook.com (2603:10b6:806:32a::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8489.22; Fri, 28 Feb 2025 09:53:30 +0000 Received: from SJ1PEPF00001CEA.namprd03.prod.outlook.com (2603:10b6:a02:bc:cafe::76) by BYAPR07CA0034.outlook.office365.com (2603:10b6:a02:bc::47) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.21 via Frontend Transport; Fri, 28 Feb 2025 09:53: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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by SJ1PEPF00001CEA.mail.protection.outlook.com (10.167.242.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 09:53:29 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:52:33 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 20/31] KVM: selftests: Add unaccelerated APIC msrs #VC handling Date: Fri, 28 Feb 2025 15:00:13 +0530 Message-ID: <20250228093024.114983-21-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF00001CEA:EE_|SN7PR12MB8819:EE_ X-MS-Office365-Filtering-Correlation-Id: 22ae5257-5b41-47f4-f577-08dd57ddc166 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: O/okJ6659nih+OiBe/i/QKu7/GUWmx5nnkFcwGR4pG+Kq13TdYmTw89gzinZIDJiXfuSt1xPEv6FIFFYQ8lRvLeWBlHujuFddV7U3Xo2gAxUHVWJ5qg/wvNLDz4yjLGEwmvhpxTTMGxVeGRFsPCA2+KYNrE4Bdw1a7OIdy25hJhH0VcsChDUb8Azw/V6PYzIpXwBXIUO3miybfZ7fEsv7xuvFP6NFp26tv78xP4coQ72CfwR+ZpNchku8EoRxSefSL8oZYP/FokTXGdW+ImemTBr5gCjFBgnvB4Tqh1JicKP2sy0MGBCnhi9Ol/NFuAv9iE8gGvoG9iRRTggZAyi9BxHVIcYqPPhTk9RnwfvnYU/N7BfyHKKOV8a9f8GRUAQTowvD+Hhc/N0eb4KVTUAgtrmeFEsXfKsjQca2mYP/rZnRuIeUhG6KIgwauF0G2y0nI2o6juLLFZ42WMtE29vzRzE1YL1WcMD7R/H3zPdgO7fDnx9ZqQRLlPx5beu1degMbfviV6xTvjFMC8eXeR4S8zNuq3zx8e7l13h72VGWS6V3rqv89JtkXr157s7z82XiGJKP0YCsIaJK5CTQ8iXBiCayGFOiB6SOARELgdY+/z2tohD4WEntL/FBxY1trnjMz5jgBZeS+FJHvhBE83iMxRhA8SzeY+n7dP/AEiRSehN6byzaBpjHtU0plr7fDx6cGKbMDrHyrAIIw0kiapBSajlgHwCCAfmHujR1TWp3RDJLNUL+mTwWAItkmYU2DNi4Q3h2LqkOr/WUdZGhOfUP38LTj+YW3Xn4jA0XLOMlPjJM+L1VGHpJaa7MaErH6CD833ZQBmrtF1051IU0dPhIV10Gv5pSeJ12CDdani1VEeD5FWHdI8fLIqtPfCtFUE7fFRl1Q+eTNMFPvQNbb9Fw6IN0tBPwBIZLJqTCESfBEzVd/pqA9xqX0k+VBVmZ4UCzYnzupYduGsfS+Vx0wGNKExwCqRUpKMl0bSNQIGiytROx4iljFHnG4QBxhyHm1RikV4xBYUsXXzBNsih5PYunnf6uDyaOU1hU+3CVEY2K/2IJsE+MC41LKaHlBiboDR5N9Veflgle+2bmorc2VLn/fquJvm7+QCUwoe1qwYVOEvjFjHvKq2u6SpUHKup7Y8LDtYsIOO6pZ//JhMzpo9qlxZOE3N09ulqnEWKGa1a263B1DZK4CqSUGQ9HWCSiXwGwBWu66vizQmzGlkzQ2gO+dQFMQWOwTxy/nmyWdqAEmm5szW+p+RZXnMpRRmPweiE4Zt0RPRdJ93r88P0mOMzXoNCZC8OAKjbo9REP4VfrWbI0rm+F6G4+AfGBF/qeb6fylI1ZC53YHllPRs1LciyAV1aJ5WCwW+lGFsStsGb1711lLei9eje4jZaya7qxo76TMSg4URdvWjWkieUl/4xI9HkUry+qdvlFryBAQzkMfUbQmtcgGP30pB2fKJUUMyMa2mXwBOb2AK9ZjFqhizdTKdCEXoF+nEsNc176VlB+3w= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.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: 28 Feb 2025 09:53:29.9055 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 22ae5257-5b41-47f4-f577-08dd57ddc166 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF00001CEA.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR12MB8819 Add #VC exception handling support for unaccelerated msrs reads/writes for Secure AVIC guests. 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/testing/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/selftests/kvm/lib/x86/savic.c index f4a765b6040a..141d31637e51 100644 --- a/tools/testing/selftests/kvm/lib/x86/savic.c +++ b/tools/testing/selftests/kvm/lib/x86/savic.c @@ -42,6 +42,8 @@ enum lapic_lvt_entry { #define MSR_AMD64_SECURE_AVIC_EN_BIT 0 #define MSR_AMD64_SECURE_AVIC_ALLOWED_NMI_BIT 1 +#define SVM_EXIT_AVIC_UNACCELERATED_ACCESS 0x402 + /* * Initial pool of guest apic backing page. */ @@ -204,3 +206,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 = savic_hv_read_reg(reg); + break; + default: + __GUEST_ASSERT(0, "Unexpected unaccelerated read trap for reg: %x\n", reg); + } +} + +static void savic_unaccel_apic_msrs_write(struct guest_apic_page *apic_page, + 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_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, SPIV, IRR information is not propagated to hv. + */ + case APIC_LDR: + case APIC_TASKPRI: + case APIC_SPIV: + 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 = regs->rcx; + uint32_t reg = (msr - APIC_BASE_MSR) << 4; + struct guest_apic_page *apic_page; + uint64_t low = regs->rax; + uint64_t high = regs->rdx; + uint64_t val = 0; + + apic_page = &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 = *((uint8_t *)regs->rip - 1) == 0x30; + else + write = *((uint8_t *)regs->rip + 1) == 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 = val & ((1ULL << 32) - 1); + regs->rdx = val >> 32; + } + if (!savic_reg_access_is_trapped(reg)) + regs->rip += 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 = 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; + } +} From patchwork Fri Feb 28 09:30:14 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996070 Received: from NAM11-CO1-obe.outbound.protection.outlook.com (mail-co1nam11on2072.outbound.protection.outlook.com [40.107.220.72]) (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 12B7D257ACF; Fri, 28 Feb 2025 09:55:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.220.72 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736530; cv=fail; b=esfb9URdzazCuvny7fxNJM0J6klumyRncVsqvYcMGHPcqdhtZzJJ63S7IFoGXbTK022I5cDYmRwinkst76XoqxPOEFWGiFKFE6w+OHSoHq/tlrTWZeHJQE0UEtfIHrCdPlwuTrwuLi2pKZF5VQ7BUKIvyEcXBVfV5RySxRhyexs= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736530; c=relaxed/simple; bh=wpHD0Mu4qinyP7AAFWL8aHKoLabBnMlNH71cmU/rRlY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=T0/n1RgujljFAHnEUO4e0Vp8tVj15w5cOlGYPd8NJtNKd82mYOzBZOrZb3V9vRcbScPt91q+XHSuchVUsEDdJs8IZ9taaJ2as++SkKmK/OtuZ9ZyUlouum/S1G0vrQYhRiyApQpKPneHrKlNpZuUu0LEIFKTYApJalc4H88mGp0= 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=Ms3ZsgKy; arc=fail smtp.client-ip=40.107.220.72 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="Ms3ZsgKy" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=ITGtvrkQsaMFr2FkgOuDx0byAQr3ETUqx1by9J5MZfQLVDgiYqmMU46HBfia73uuhD/2VHDM8Tp0i3+BXHFsOTMEs+Yr+i2TzFAKSa0/1HjjCkG2cbCpdNtaWzwGKOTwvvNcvMpVve6HL+XGM6THbPR3VOqmX4NWfgssorfI2KL8ALVQxyZYya+VmrlW9SLFYlOkL4P3le1tEtGlkHdElZ/XDDnipeLdELZugFQmunsw+7S3gCJ9ma2dslvxcjjthPZfE367YqGnl0UQ4vpcnYh4r5iij6Wi3V8jHCy1G7nPDcoGZGf9/AZnxQdJeO8RLwDeE2K/UeRWTG5CNdZLQw== 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=pfJcPmZEJz//PTTP9F2bF9PjNUOFmBWMbhVU9Sal5U8=; b=mkMSnXEzJolN1dtf09svQqJXyTnGfTRrocfJPfvH08K6E/WLHdtkG27JbhOadtswt1kHP+Hnf4TwRJjXBHOMSl1vuqYzG1IghiixE0X74TjjTEsfRnblDHE3GJ5u5IImA5X6v4bclRuV0l9APpSVbTR4IVYmGWgeKy6NWyZztfxGMaT38C2TUNh4VW+ouRvI09Ly/cH/Is+D3t8ttZv07AmZhNUOJThNVxAeEuUHRD6e7siDj6aJFt4bijFxypf9oALp7pfXHuxp5Pf3N9AYCXLlygwAusVcmYCSlnX/KAT1x7VphtdQUYbAHHbYY3gZutvWEg2fkaoO2M5SBD4k6w== 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=pfJcPmZEJz//PTTP9F2bF9PjNUOFmBWMbhVU9Sal5U8=; b=Ms3ZsgKy/+gWbRg4R58rU9iBcLfvtYOr7andzO9kBaavU5ab9sXnOPUMiJzbi/oGYabYQXfan6/AL7nSvVV7zloYcSa/IKlQjOxiFZ979MJQSWOdDTOD6iiztrDkAvovSBkxKr7JqORwFliCX6Y7DlaUhnVGqyS57kNTqv63xIM= Received: from SJ0PR13CA0038.namprd13.prod.outlook.com (2603:10b6:a03:2c2::13) by CY5PR12MB6432.namprd12.prod.outlook.com (2603:10b6:930:38::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8489.22; Fri, 28 Feb 2025 09:55:26 +0000 Received: from SJ1PEPF00001CEA.namprd03.prod.outlook.com (2603:10b6:a03:2c2:cafe::31) by SJ0PR13CA0038.outlook.office365.com (2603:10b6:a03:2c2::13) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 09:55:25 +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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by SJ1PEPF00001CEA.mail.protection.outlook.com (10.167.242.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 09:55:25 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:53:52 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 21/31] KVM: selftests: Add IPI handling support for Secure AVIC Date: Fri, 28 Feb 2025 15:00:14 +0530 Message-ID: <20250228093024.114983-22-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF00001CEA:EE_|CY5PR12MB6432:EE_ X-MS-Office365-Filtering-Correlation-Id: d8dad154-6b2a-4239-ae3e-08dd57de066e 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: Qs/rcV0w1xkf5HTl8qyAslTBFDvfT3030Tw7RWlGcy30Uwm6sbNuah0O4vt7fwoLKXXYCaWQ1i6IdlhMe7yGVrJ9RX3KI05AmZe5UejnoedHN9vzJDpqTGSpkOlBmz9k5dhpbLtX87WZ+xnLdc7sziLk1zB0rWD+i2sy+AdlaljTf9ln+tyV1sNzrkSpkN9nBJEB4PFJRMU6jIzMkGw0R4dJX8kI8QjWdyA5Ot+xqTUx31hMCRWY00ZvlYc+SmbXyKgUba2H2aMxkL4L6R7b2osCN3EeePUfJWaRACqnZ8uoJyTXAb8B7Y5q6QjuiezBZTeESBh66GWl6DUYqx1zk6uAfxCPJrw3xpGXOry7qb7I+rK74XmJ7Bdz4wxPMdvKP/4Lv7KlZYcQ1ksKUktQ/cB0YepET87vUb283oRXj6aAh0UR44y8PF1oqPT2bi9UPC77/KK1U3aobNlXqLLc/PQFfL5iwDc+m7Ev7WLT2aWQqkq9t0y8IfwFFG87E85NNuobJKPPoMLxABtr2hcsaEbczWxqIcH5hVzFBZnL46B0bfre0JZtX4UoEFXglreGUiID43UKj72SyARF5rXJ8hQCW6QrxGABq2NwBtxa5PFZsbwQxA2Z66sJRQ/d20W5Box8gwsngOJR/GjkHmxyQz9hOOm15BqQsMxmdt3ZrAV+Cc32RF7DcGzAeGUlTuFef8ZEigfccU9y6h30laqSkmAO0C7MIyzqiO69K/VGOCytj1A7utPk9ekLwRKLkFVBol4veiZOGDkJtUCxfTHEmC5wA66ieT+mx8Z8CCVRiNhFUfEYb/Yu7OgHktKA3wMnUi+citByhl6Jm6gfZZpmPQeMUwl9pxueOlO6Z8j9fwF6pg9FQr+OAqFjn8Eow/v7fiJfQNIwOXpnaT0wcecFO6YjLzJeVcM8OFJv/0m4/rhKiv+bj4NefruKYLnwKMhtqW45B6jue0Nw0g+d5CXejSZu2KVFDdx8mSxaxKnDtm9tdrST+s2KmaA9467RraxE6024Q8kYFzaqwDlEgPLpfbnvmMavvy1vrASjkpOGatK7mtE6VvTwOzhZQty7L2Kcge55MKEzsnWaoRbn3l6hjf9hJCwO1z2L6ZUOrDK9F0SZwZOlJrL5j+BZIMWaHHUvG8LiTOkN3Xi+Xtsl9/Ei1sXsA8sYkrAK7zcks2WLAboPcN0Hxjuo0vpGxM769H1X9kBLMi9BM99semximPD67UPsvoS0kWXXXkQGurCTU9iImmMEJPS+tMEwodmaIu9sIheTzxvqstvRmkWb3Mv239cIY2iHwjwQMdjMNfWuhpQnLKzCTRcmCBfClAC77+bar92PJPHvexX9Yh9WIWEv0ekGHR2CjUShKBsZBTrfgnhXTq7x4WlTb+jazlxgJx+zWYrop4oAT2KOfcWL90caQYXfnYnc6p1JS7rggSdFBIjp4SX/s8tssVnNkec5rYFwAgj9mPGhMdS23ycvXFnUfPXn2I5CzvX+4Lyxddk50gE= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.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: 28 Feb 2025 09:55:25.7189 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: d8dad154-6b2a-4239-ae3e-08dd57de066e 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF00001CEA.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY5PR12MB6432 Add support for handling INCOMPLET_IPI #VC exception handling for Secure AVIC guests. This allows sending cross-vCPU IPI, using all destination shorthands (broadcast, fixed) and destination modes (logical/physical) between Secure AVIC enabled vCPUs. In addition, cross-vCPU NMI using APIC_ICR writes are supported. Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/lib/x86/savic.c | 112 ++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/tools/testing/selftests/kvm/lib/x86/savic.c b/tools/testing/selftests/kvm/lib/x86/savic.c index 141d31637e51..8259f7521e73 100644 --- a/tools/testing/selftests/kvm/lib/x86/savic.c +++ b/tools/testing/selftests/kvm/lib/x86/savic.c @@ -43,6 +43,12 @@ enum lapic_lvt_entry { #define MSR_AMD64_SECURE_AVIC_ALLOWED_NMI_BIT 1 #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 /* * Initial pool of guest apic backing page. @@ -336,6 +342,105 @@ static void handle_savic_unaccel_access(struct ex_regs *regs) } } +static void send_ipi(int cpu, int vector, bool nmi) +{ + struct guest_apic_page *apic_page; + + apic_page = &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(vector))); +} + +static bool is_cpu_present(int cpu) +{ + struct guest_apic_page *apic_page; + + if (cpu >= KVM_MAX_VCPUS) + return false; + + apic_page = &apic_page_pool->guest_apic_page[cpu]; + + return savic_read_reg(apic_page, APIC_ID) != 0; +} + +static void savic_send_ipi_all_but(int vector, bool nmi) +{ + int cpu; + int mycpu = x2apic_read_reg(APIC_ID); + + for (cpu = 0; cpu < KVM_MAX_VCPUS; cpu++) { + if (cpu == mycpu) + continue; + if (!(cpu == 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 = &apic_page_pool->guest_apic_page[dest_cpu]; + uint32_t ldr; + + if (logical) { + ldr = savic_read_reg(apic_page, APIC_LDR); + return ((ldr >> 16) == (dest >> 16)) && + (ldr & dest & 0xffff) != 0; + } else { + return dest == 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 = x2apic_read_reg(APIC_ID); + + for (cpu = 0; cpu < KVM_MAX_VCPUS; cpu++) { + if (cpu == mycpu) { + continue; + } + if (!(cpu == 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 = icr_data & APIC_DEST_ALLBUT; + int vector = icr_data & APIC_VECTOR_MASK; + bool logical = icr_data & APIC_DEST_LOGICAL; + bool nmi = (icr_data & APIC_DM_FIXED_MASK) == APIC_DM_NMI; + uint64_t self_icr_data = APIC_DEST_SELF | APIC_INT_ASSERT | vector; + + if (nmi) + self_icr_data |= 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 = regs->error_code; @@ -344,6 +449,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 = regs->rax | (regs->rdx << 32); + uint32_t reg = (regs->rcx - APIC_BASE_MSR) << 4; + + GUEST_ASSERT(reg == APIC_ICR); + savic_handle_icr_write(icr_data); + break; default: sev_es_vc_handler(regs); break; From patchwork Fri Feb 28 09:30:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996109 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (mail-dm6nam12on2041.outbound.protection.outlook.com [40.107.243.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 A33711C549E; Fri, 28 Feb 2025 09:58:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.243.41 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736684; cv=fail; b=OiDfd3g9z21lwRSFsF/kC/e0ATW9lqojl6FGvDz8qqwNkFrV04tDD0v0V8fZ0eIMu3D0xlcQRjqY4wYCbJQ8J4exjZUSCmULipckY04+aaSIZEGoX0a981x5SYU9iPwIpKozBd+HPyDkQlqxj/u0Jz/3C1GTBZXGAK7fla5KY+k= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736684; c=relaxed/simple; bh=D4naQEK05N1WoYO/35g+u8u0dlFcr5QuLifugNWOxhw=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=bBg2k7UP7A2j6fNwHEbTvsf2DGNdpUmJN42ykaSa3mR80ZpdouYE4oB0mhL353Y7VJSEjKCy8WxQAOuiktR9fxDjeWNP30qLJU6Nwu3qQd2TSRfPPewPWE/Az5bdO+J4Fj6duiXup4WEGQCwjAkCKHRqTfDgB5qW4uclYwiGbxQ= 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=wDjLqeix; arc=fail smtp.client-ip=40.107.243.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="wDjLqeix" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=SfL1UbxR92C99LMjZebmljTv9rDbJMwyBPt4PtVY56SKuChN12WDQQFpGFCRvGmJCFwRnEp1UAE6UNsu8xoBbV+YzM8nkIIljoeRKWoLBuRB05rwG2V2vnJzfiQLvzd/TSCFxIJWJAqyqZQePwOUM7lEVGWo0/1zieoVEWA3vo+Ia2Hl2GbbVBxzwGHMfP5ziSuftsYPSDCa0n/l83DSGbCuExSvdZ/QGputyw7VG5lj4gGKyT5bO8eHXWxG/MCIDNgNEO+P8U+oy+Yf5d2P4XTYjB7wHlwsEGJm8DV18UjB3tlWwe5O/rPaVfQbAN9nq61ewhk6iFb5MDaKa8z3iQ== 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=DVpOsls/JXexXlGl+j1UlPV4bV1c23yW/fdSSxCiuB0=; b=SjtCHUaQDZEydBejVLancqabtH1sTrEQpInjG/n4e7RtqiZKX9WoxSyERsLJ0d4hz7AkAp3M+7l0xsMSYrc8x/mf9vleWyBrWI7I3Yh9eN2dM4TddkgjrNntAnGrKFpKNXSE/NCMgw562MVKrjxe1TW88FmtvkdG1Q6xbNrwZseBcS34S8USx/Hb3qzHnrFe7SSXiqNGeZvY1jMlNnxrXyVJQFS4cwzbRVCbUc0ZAGpL3uzNfDl2DSniDvoivDiaFMWjIWvxw1vK1jvsxs4+2kryCxWTCtpLsWTxgE13++Ig+nP+R7FaprlQpxcCOdsMFtGzfY79nMNhBUwml8hz7w== 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=DVpOsls/JXexXlGl+j1UlPV4bV1c23yW/fdSSxCiuB0=; b=wDjLqeixQxokcHFFTZbanXTvCZod87VJnTOwgd4rPgqR62TP38RE4ANPd6qbvsIyVRbEyfEQ9m1hmBELdWVUKmxQEwl9T51+uzH2jeOyGU6qIcyOU7D1c0nwrB7P+KinoeWTwT49zD2NH0QBvcF0g5XnHvqxgg3FXhpTIVGyFXs= Received: from MW4PR03CA0230.namprd03.prod.outlook.com (2603:10b6:303:b9::25) by IA0PR12MB7578.namprd12.prod.outlook.com (2603:10b6:208:43d::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8489.23; Fri, 28 Feb 2025 09:57:58 +0000 Received: from MWH0EPF000A672F.namprd04.prod.outlook.com (2603:10b6:303:b9:cafe::d2) by MW4PR03CA0230.outlook.office365.com (2603:10b6:303:b9::25) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.21 via Frontend Transport; Fri, 28 Feb 2025 09:57:58 +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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by MWH0EPF000A672F.mail.protection.outlook.com (10.167.249.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 09:57:57 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:55:24 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 22/31] KVM: selftests: Add args param to kvm_arch_vm_post_create() Date: Fri, 28 Feb 2025 15:00:15 +0530 Message-ID: <20250228093024.114983-23-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: MWH0EPF000A672F:EE_|IA0PR12MB7578:EE_ X-MS-Office365-Filtering-Correlation-Id: 8ddc7f26-f68b-4163-34f5-08dd57de6131 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700013|82310400026|1800799024|376014; X-Microsoft-Antispam-Message-Info: W7VmRunEEVH0pQEdnxyzYQ1bPeLmuuqTHoOdZ/QshLwpToRQWs6z3cQT0YvE6ah4Rwxxvj9+cgVUac/svGwndWCgVzWdc3BeQTINAJU4SIQlDZ+SfIebXg1u6ihJT8EA+CSXhAoA83PxsjUVQKN4U0W8XD0lTx1YuAggXks9W/a03frPdBAgRCIHFSFo6y9w7jjRzNf9KVWv3WbQabJvjDygDglriv1snB7Eagswl293Rd50OJcQZHoBeM9yOW6xBIRnT+AuLc8OTaG2nVK4oAHtloaMgre4Bv3gDr3Ax/IUl3SDrZ+NFrryU1qhjs+m4LWPLR94/JI2wCvsoabo0DSq8UvlD9UFI5wPaQ9LN4S/RvDfOQTPK9w0bliFTg56YCYJ0WOmo/TcAOvjwh9RBUL8sq9gOpJhh5ktBRKj1ze1mmKs2BJWjy1lJheRonQK4/t0XjjWkEZYzJR0YM8OVmU2n0+zHBTgX+RE7rSrtAkEVHin/VSWElVd5JMRtg2rZM42lYOiKUd9cCSWADp5kfF4F3cIr3OVjWno5BSV9AI8NzVuC36kfV2B84/wN7Mczq/ilmOQ9z7nDkeadBkE6wIjs/f1oe67S7G2c2LRr5CggUfSOHkQh9hpuQofdmksl03bJeDBV34NoGPf6sJBqx9EjN+16WP/EUFlyLTHQnIRqOthhpvBfJbFEaum6lKLd8KJtmP7pAT3JdYUwUhb32yFl0dwxRnx1PpW0ptp3QhkbEpzg9u81zhzaHdA1jZmHt+1RhgKzOxTz6+t0nI1KoVxUijcasDU0SqH6O+Blx1Ngh5volHsqApLJEtOAZskSnW7xSEj9xuPKmdbxlWC9FJDUDMNSSAd1qa+tW8le20zYqFE5K9WfPtzXtUs7C4nZDOyQvxbAiJPUE7EOqMub06oIoaHl6rszkFLZg3cXAti7hROpFLfrBxKip98YN+XTKML2HRr5lcMMaAigCGM3TUr+Mti/qh0SOtmavNcvhEhB4zN5oF5c0HWRv7LaGMX2Fh8S2Y0zLMHpKocuAAEsQDroLqnDTdk/OHQ5atVaqh72qm/DzYv9/ejpIIfBLBzJwZLAoodhB6uh2qwZdTE2qW3++MnSI9XCfqNfsbToVJCtSUiwCJl57ghUlfiDwljBhpycO7EgsanRfOO0+/xK+vda4r2O72jGuNf6fOozAgESLPO36rW8F8ZOAykdVETo9L9Boj+zVuFIiq0vmClnijFN7Rj7Vw8fyBDZcVf1I6g6y+Spuux3i9X6yRLGPuYMPhH6einulqkfIREt2z5y+KAlWNQc5W9d9EmHJFun0yYkgHqD85S/sB3Hxvv045KaSDnpYnfpgkOGpgCE5abjdTjsV3z60Ou1eIUrZT9/4soPhbPOv6gZnwRjLnUQYL8uOu6VAy7EbqoyGQrGqPWMB3sTYGlS8Q/hrxsvM064Hh4gQBDf2bbWCdpbeIt52BFqlBPLJXFy0xcAEXv1mDyXPWTnhkaVN7ArQUSBBG0c+U= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(36860700013)(82310400026)(1800799024)(376014);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Feb 2025 09:57:57.9574 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 8ddc7f26-f68b-4163-34f5-08dd57de6131 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: MWH0EPF000A672F.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA0PR12MB7578 Add provision to pass custom args to kvm_arch_vm_post_create(). This will be used to pass sev init args (vmsa features) for SEV VMs. Signed-off-by: Neeraj Upadhyay --- .../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 +- 6 files changed, 62 insertions(+), 22 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h index a160e1ac7cbc..7f97bade5797 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -901,6 +901,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_vcpus, 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); static inline struct kvm_vm *vm_create_barebones(void) { @@ -925,6 +928,10 @@ static inline struct kvm_vm *vm_create(uint32_t nr_runnable_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[]); +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); static inline struct kvm_vm *vm_create_with_vcpus(uint32_t nr_vcpus, void *guest_code, @@ -1141,7 +1148,7 @@ static inline int __vm_disable_nx_huge_pages(struct kvm_vm *vm) */ void kvm_selftest_arch_init(void); -void kvm_arch_vm_post_create(struct kvm_vm *vm); +void kvm_arch_vm_post_create(struct kvm_vm *vm, void *args); bool vm_is_gpa_protected(struct kvm_vm *vm, vm_paddr_t paddr); diff --git a/tools/testing/selftests/kvm/include/x86/sev.h b/tools/testing/selftests/kvm/include/x86/sev.h index 3756805197c3..ffb5ded0a35a 100644 --- a/tools/testing/selftests/kvm/include/x86/sev.h +++ b/tools/testing/selftests/kvm/include/x86/sev.h @@ -52,6 +52,9 @@ void snp_vm_launch_start(struct kvm_vm *vm, uint64_t policy); void snp_vm_launch_update(struct kvm_vm *vm); void snp_vm_launch_finish(struct kvm_vm *vm); +struct kvm_vm *_vm_sev_create_with_one_vcpu(uint32_t type, void *guest_code, + 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 *measurement); diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index 34e586d4fec4..93b8e2ccc7b3 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -408,8 +408,8 @@ static uint64_t vm_nr_pages_required(struct vm_shape shape, return vm_adjust_num_guest_pages(shape.mode, nr_pages); } -struct kvm_vm *__vm_create(struct vm_shape shape, uint32_t nr_runnable_vcpus, - uint64_t nr_extra_pages) +static struct kvm_vm *___vm_create(struct vm_shape shape, uint32_t nr_runnable_vcpus, + uint64_t nr_extra_pages, void *args) { uint64_t nr_pages = vm_nr_pages_required(shape, nr_runnable_vcpus, nr_extra_pages); @@ -447,7 +447,37 @@ struct kvm_vm *__vm_create(struct vm_shape shape, uint32_t nr_runnable_vcpus, guest_rng = new_guest_random_state(guest_random_seed); sync_global_to_guest(vm, guest_rng); - 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_vcpus, + 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_runnable_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 = ___vm_create(shape, nr_vcpus, extra_mem_pages, args); + + for (i = 0; i < nr_vcpus; ++i) + vcpus[i] = vm_vcpu_add(vm, i, guest_code); return vm; } @@ -475,17 +505,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 = __vm_create(shape, nr_vcpus, extra_mem_pages); - - for (i = 0; i < nr_vcpus; ++i) - vcpus[i] = vm_vcpu_add(vm, i, guest_code); - - return vm; + return ___vm_create_with_vcpus(shape, nr_vcpus, extra_mem_pages, guest_code, + vcpus, NULL); } struct kvm_vm *__vm_create_shape_with_one_vcpu(struct vm_shape shape, @@ -2270,7 +2291,7 @@ void __vm_get_stat(struct kvm_vm *vm, const char *stat_name, uint64_t *data, } } -__weak void kvm_arch_vm_post_create(struct kvm_vm *vm) +__weak void kvm_arch_vm_post_create(struct kvm_vm *vm, void *args) { } diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testing/selftests/kvm/lib/x86/processor.c index 2d6105b1f610..09474be27986 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" #ifndef NUM_INTERRUPTS #define NUM_INTERRUPTS 256 @@ -631,7 +632,7 @@ void assert_on_unhandled_exception(struct kvm_vcpu *vcpu) REPORT_GUEST_ASSERT(uc); } -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; @@ -648,7 +649,8 @@ void kvm_arch_vm_post_create(struct kvm_vm *vm) if (is_sev_vm(vm)) { struct kvm_sev_init init = { 0 }; - 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); } r = __vm_ioctl(vm, KVM_GET_TSC_KHZ, NULL); diff --git a/tools/testing/selftests/kvm/lib/x86/sev.c b/tools/testing/selftests/kvm/lib/x86/sev.c index 518e30275960..7675950efe56 100644 --- a/tools/testing/selftests/kvm/lib/x86/sev.c +++ b/tools/testing/selftests/kvm/lib/x86/sev.c @@ -291,8 +291,9 @@ void snp_vm_launch_finish(struct kvm_vm *vm) vm_sev_ioctl(vm, KVM_SEV_SNP_LAUNCH_FINISH, &launch_finish); } -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_code, + struct kvm_vcpu **cpu, + void *init_args) { struct vm_shape shape = { .mode = VM_MODE_DEFAULT, @@ -301,7 +302,7 @@ struct kvm_vm *vm_sev_create_with_one_vcpu(uint32_t type, void *guest_code, struct kvm_vm *vm; struct kvm_vcpu *cpus[1]; - vm = __vm_create_with_vcpus(shape, 1, 0, guest_code, cpus); + vm = ___vm_create_with_vcpus(shape, 1, 0, guest_code, cpus, init_args); *cpu = cpus[0]; return vm; @@ -319,6 +320,12 @@ static bool is_savic_enabled(void) return supported_vmsa_features & BIT_ULL(SVM_FEAT_SECURE_AVIC); } +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 *measurement) { if (is_sev_es_vm(vm)) diff --git a/tools/testing/selftests/kvm/s390/cmma_test.c b/tools/testing/selftests/kvm/s390/cmma_test.c index e32dd59703a0..b6a3fa1d71aa 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 = memslot2region(vm, 0); ucall_init(vm, slot0->region.guest_phys_addr + slot0->region.memory_size); - kvm_arch_vm_post_create(vm); + kvm_arch_vm_post_create(vm, NULL); } static struct kvm_vm *create_vm_two_memslots(void) From patchwork Fri Feb 28 09:30:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996110 Received: from NAM02-SN1-obe.outbound.protection.outlook.com (mail-sn1nam02on2047.outbound.protection.outlook.com [40.107.96.47]) (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 9E1AB1C549E; Fri, 28 Feb 2025 09:58:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.96.47 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736733; cv=fail; b=u3DagAzw18oTkiioVdkgPOUL/zEjT1fu5kMdo5ONL32BM4Y2OTJI+ubIZTtLDxcZ0kAkhNkJ5G1VDp3ujKk6JHK7IvOd/g4dZYP9TiOTr95vtpkmBOT0k12vpfSeIWvmjEjFn15XBoZgM8QagKraRBn+6KtCu/2im0xZcTo2zgA= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736733; c=relaxed/simple; bh=X5AtZqwYNiN2IO1TDfOJihxa1Se4EYS5vBE54UoPrCk=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ZbWNLKsiFLplzRhZT69rRr5uwS5rFPuE06tThLX1k+L/clKxf8gv6roYn/hzGWug8Ei3YWKp7s7ZCl7t7FnenigR3sua6eZ+1eTN0TZ+y/GOdhLj+XUlvJpWmRuvkFw/MTmuLa1UEAkvIV7Lmm13yf0RPS4vux5ZMu+sFIQhCGk= 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=0i4vXZKk; arc=fail smtp.client-ip=40.107.96.47 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="0i4vXZKk" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=FvmAow1YxH0INgZXXRrSklYcxS7xGPjoYKblwMcYDnFxKTVb3W9A709PwltV7quGnkuq+dahuVPusjRECbsTDO5TEloJpHcJmgVeWG2IIFN86m9q2dfckHLekx/IFeyaQCyS40UMoj/FZpqAMmSNdCZIBVWc8TpCHWKODWh5qTiQ3+PJsFI3gxgf29tLpMZDX17ud8QiX0JYyk+ZuxV6YWtC/CXrfEQ8qkMCrA8Na1alzBBrNSZPkt/EqAmfy0y9vmUVUprfYSdum/3Tra0cONNTxofvtvzoW5JKcQEOLIvcKZA3MpZ3xsO/9qCZG2ib+VSL6iy9oPH69QzkefgcJg== 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=7U6QGD3k90AAUfGnLFNyGgKhdR73Mp/Q25y+ARP8ysM=; b=SV5aos21v+TiwiEqhu/Ejq4Qjc7o4z1gcqLFwtObb8TW0aQy5+GVLVX4O74mVanYiaObbUwXh4WVh6VQNehCnRW1l+yfgkxIFd9r9WLe7eUOqVsV0zPQVLgInPK/1qSYqoifqB5V+vjmquqfKf5586iqB+JJmeWLU49WD7A+5o5/5TDwMRel9V8WmHu70Dpr7eCjATcTj64rsmpUVO1BmaRrBAvRgGPByGfTdlQ4dl2GjYNQW8TUMuf8i5Ecdt8Hl6QmykmiIFOWfIW2nK6CgtEjR9SfV5/plU20R3SpxVJNhiMHzrTvlHRHRk93aE1uIDSR5MwXnIXasn+QqzLZYQ== 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=7U6QGD3k90AAUfGnLFNyGgKhdR73Mp/Q25y+ARP8ysM=; b=0i4vXZKkJ2eBKTSFVfx0mgden51RnZxPzPKO8jFtWfeyLwK6G+wIDjq2UvX9ir3vaOfe66+KoMp8ZBSbtBjnsM8VB3WnAXkUg+PoaIVZ8xkLai2SMENp+uSsDDpJ7GPgCn/m/CCuOobutcnFG4kFDhFvPT502PwxMqD7AKejvQ4= Received: from SA1PR03CA0005.namprd03.prod.outlook.com (2603:10b6:806:2d3::6) by PH8PR12MB7112.namprd12.prod.outlook.com (2603:10b6:510:22c::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8466.20; Fri, 28 Feb 2025 09:58:47 +0000 Received: from SA2PEPF00003AE7.namprd02.prod.outlook.com (2603:10b6:806:2d3:cafe::49) by SA1PR03CA0005.outlook.office365.com (2603:10b6:806:2d3::6) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.23 via Frontend Transport; Fri, 28 Feb 2025 09:58: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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by SA2PEPF00003AE7.mail.protection.outlook.com (10.167.248.7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 09:58:46 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:57:50 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 23/31] KVM: selftests: Add SAVIC GPA notification GHCB call Date: Fri, 28 Feb 2025 15:00:16 +0530 Message-ID: <20250228093024.114983-24-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SA2PEPF00003AE7:EE_|PH8PR12MB7112:EE_ X-MS-Office365-Filtering-Correlation-Id: 6a0aebf8-2303-4c25-f31c-08dd57de7e46 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700013|82310400026|1800799024|376014; X-Microsoft-Antispam-Message-Info: CIoRQgyVlx8tC9AU+N9P1jXA5yDabSbzAVAP9G3dfN30dr4vPRFbOk4XsWdoUYQdAtg7xAR+QMz7/hvS7OklCglxcxa8DvU9CJLPAUEsAlPrC4ert2BSamIQeM/OEcAJWe7/V7CRx1UMUWgD7zOY4+V6sVdw+2MCilK8XSOKAyeX+cVGXfImW7J/DceKfYrtNp/0A8G8yfQqCLofmLoyGeUnnPePW2lPnRw8eRqfLEwsBPINT870zShu4hPLpw9CuM/OFO1ENbaB5HZJNNXvaJQN/7hY8NLFGRN5s5nrsel3vcO4mtMQtuzd2Km5WW18FxLftKHP3hQPxHBOHHjHdtw4J7rqG9PKB2xXiY/h3ktjpPH3LeDgTdYgh7PMEJTsWM+R6WQPpFE7lxpLxIl/QOgbPukNkjHVSCAOvPmfeln3rgpDzV2k0cDpaHpPGLf/guv6ATp0ZbdGQHofHZ4o2dZr1Y9kZuJ8TMWspHEcO6hTK3EMLfQieSbrvYIJRAznvitjZGhFtQj5Z+BlTkHA3opXxKjfxrFx7eocnDZxcOc389TZM2uN3i/SNtXh6TR6IzgHZobAql1We36mG8cR19hRDpObMPZIpyrq9UCSZwM9qnOEPNTIN04Di0jpwimfOPZ0/PTQ8ye3pSpBSipFfK+aIJtpcJQwz4CHlo8Cen2KbFZI4htl2WjJFrd79HCQDG/UJ31hkt3OI9X4cHKRaVey89FrcmA5nqKTDgfZbgpQSF8CA8NNUdV+41qqgjyZPKyGTb+pLSQgTWFT6BHkXP1n1qg5bWORogDNogxpaR8s4CR20Mso3XfSQdGEMdrBPL1+aGJLIiaVF3c/886D4AcKQvfx9cFX3451fgUSPighmFxnqCLl3YnwfdKI7A6OgGpAncAmae6bjLVJooU3VzcIPZvMxYNv0qi0nn7kH0FzK/R5kn+VutQFA2YQXbgNdfwlduBBuYZaIp9FMfRCTfsAo/uK7qLpwVX0n4PS+k07nk2bwcUQgAi+OFV4l+LcmKzMQ6xVw32k9mALlK8dmj4ZcNgTAzpI6lPXOTQvhZJKGui3l2TbXNDvbVxMXV46YprwMH7dj7xsZjhBXhVY5AhFcomRyC13uenToIOQ7FPUAv7mQq/9yWyo7QemxtnnylflxzjJoh6+4m8Pd/G/GzMxapCDiYtH2HHA7NknYWFO6p5dR7wtq1aH7qHcWkDa0lwfGg4PvtwSA8VRgbdpM2mtiP5IijEFb0jmkAqk82UZnzdQnAMEPqckYW2pF0F1+oEAXrSTf27ayFd+Pa3k+EZzPSZeGTjAuNMBbgw7CgPAKTPYDCLEa/SFxXH1WLn86RbY+HUqIuvGijxjwpPbI0A2MaHpEGiEyTy7FEYxPEYayhmxeOZx4tyMOmrNgUKK1oQ9Q41KLJoPjWj9mkaqRB+Lh2pfgnFSs6n43ESEXSEgkZR2WEIfkAOtZzDuaDJPlJi/qsc/I+OKie47mIDsKEzJ1k2U4qfMLuLiilGxleg= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(36860700013)(82310400026)(1800799024)(376014);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Feb 2025 09:58:46.8476 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 6a0aebf8-2303-4c25-f31c-08dd57de7e46 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SA2PEPF00003AE7.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH8PR12MB7112 Add GHCB call to register Secure AVIC guest APIC backing page GPA with the hyperversior. This call ensures that guest APIC backing page is pinned in NPT while vCPU is running. 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 ffb5ded0a35a..81ee79f63b7f 100644 --- a/tools/testing/selftests/kvm/include/x86/sev.h +++ b/tools/testing/selftests/kvm/include/x86/sev.h @@ -159,4 +159,5 @@ void sev_es_ucall_port_write(uint32_t port, uint64_t data); 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/selftests/kvm/lib/x86/savic.c index 8259f7521e73..ae48978479bf 100644 --- a/tools/testing/selftests/kvm/lib/x86/savic.c +++ b/tools/testing/selftests/kvm/lib/x86/savic.c @@ -204,6 +204,7 @@ void savic_enable(void) apic_page = &apic_page_pool->guest_apic_page[apic_id]; 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 = rdmsr(MSR_AMD64_SECURE_AVIC_CONTROL); exp_msr_val = 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/selftests/kvm/lib/x86/sev.c index 7675950efe56..24a2a29a575b 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" #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 struct ghcb_entry { struct ghcb ghcb; @@ -775,3 +777,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 = ghcb_alloc(); + ghcb = &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 = ghcb->save.sw_exit_info_1 & 0xffffffff; + __GUEST_ASSERT(!ret, "Secure AVIC GPA notification failed, ret: %d", ret); + ghcb_free(entry); +} From patchwork Fri Feb 28 09:30:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996111 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (mail-dm6nam12on2061.outbound.protection.outlook.com [40.107.243.61]) (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 E9BEC25D215; Fri, 28 Feb 2025 10:00:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.243.61 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736837; cv=fail; b=lR7Nlnx9/IgqWtdnRipSpWtBQLLUnRoHLaskhzMVkTRHBHcWBMrXxSp2xV18P5JFuLb3rVXhVRuNRSt6DImugmvaghMPNeu5osdkTDBqrz9EnyTxjeT80wke6AaC4zP0LdIJ/5OHjmpJwfvul2N8Mv4wLrytZr+vmTZ5+KqLntM= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736837; c=relaxed/simple; bh=acyzADLyafEoCowuHUWwjAtsDLHSL5O46K5bItF/Uqc=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=dsuS0Rl6TedQORaFV0Pr+XsMmdSMCUkRryq224bCa1OJ7hOxvZBdDYmldUGPGetmlAKHadodBYxdX0KKRlE/K5/wMBa80jpF9rZB0deW+ef9SRU4FIuuChJMnrG5fYbhtsNhUsvE9+N0KxWOfGAi2DXKmrUPLRKlUFJuerCwuY8= 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=C7lFVwm8; arc=fail smtp.client-ip=40.107.243.61 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="C7lFVwm8" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=w8gsw0iL2/5eYV5IzcCn02tWMkOiTFgkfJ2nzKgxi0kvw/aco3nRO/SLoPp2IpEXikrlH/3x21tgNp5OdNedsif79UKu+zLetpHp/Y1CgJEjNghjYnTD9Ob1VHz98bzwmUpP28MIXKk2cdGYj7X7SJEWY66Ff+sc2AAvSx4p3geb5u4sh99N/YSOUF3vOJEhjneyH/tbXjpaeCuGcGTrGY9Rnq57Kc4TuDYihUvpO/uOty7lVpwWXnxdlGTJm0haUNX+oCHNV2I1B11BSQ142MEpP4i7Y8jaOKZHHk/k77NiPc81+uFtPaFIpiDcZ+aI1PdqDlR2sNFmvuDLj65X4w== 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=4pKE6RLaAWmEx0PGAQYTAZMsJhn2JgAgPrp4/QEuKMw=; b=BqtkcAGNSUQLOd400Qqx5xBGPw8HoKawhIDTk0XiBoMNWqiUYY8B7eBTRXx0mafPHQ7aWJ1ut1coN8QgjM5Q2m4enDSXpn6Bax/07HRG5ZJe1o07RZM2V32MPv7rkoI7WbgpgzuOm2wOQQRtrEnuBHOv55/v2ZLb/cxdC/fPyEU40hEjSMblXqe1/uSYG+Jx4YGgzvyV5v3mBW5uCO++7J9fgT48tzrH3rDvZp9pNN20n0BBdIhecYkb9a2pSruJGLpgEIaSomeLiun5ZG512H7yqu4GFMB+nPpsPRlx7FzwD0b2nCjZyr+lT3o+uTs2wb8QBAk2Pl7SwHxm7x+L4g== 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=4pKE6RLaAWmEx0PGAQYTAZMsJhn2JgAgPrp4/QEuKMw=; b=C7lFVwm8ihlRUYam23v8A2YGtSrG9tivwB1YLa4ijicPXqiyfiTVxp7MRKSaaL3VCHBpyK81nJV6+H/14NXn4KzYh09+5J6ZYgX69+mtucrEn2n9IHlKp8hkLYJlmK8A/lNyEd7n2gaeNr1VyPzxoGMc8iw4Ueue5SNGsorXp3Y= Received: from SN1PR12CA0069.namprd12.prod.outlook.com (2603:10b6:802:20::40) by CH0PR12MB8529.namprd12.prod.outlook.com (2603:10b6:610:18d::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8489.19; Fri, 28 Feb 2025 10:00:31 +0000 Received: from SA2PEPF00003AE9.namprd02.prod.outlook.com (2603:10b6:802:20:cafe::7c) by SN1PR12CA0069.outlook.office365.com (2603:10b6:802:20::40) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.21 via Frontend Transport; Fri, 28 Feb 2025 10:00: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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by SA2PEPF00003AE9.mail.protection.outlook.com (10.167.248.9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 10:00:30 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 03:59:26 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 24/31] KVM: selftests: Add Secure AVIC mode to xapic_ipi_test Date: Fri, 28 Feb 2025 15:00:17 +0530 Message-ID: <20250228093024.114983-25-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SA2PEPF00003AE9:EE_|CH0PR12MB8529:EE_ X-MS-Office365-Filtering-Correlation-Id: 845fbab7-6e5f-44ad-c154-08dd57debbf1 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|1800799024|82310400026|36860700013; X-Microsoft-Antispam-Message-Info: 9vE/gPOKdFN1aamhz8/D0G+ZvHCRrOy3ChbrIIFzl5qFsQyEKEz+l6IyJDJcOJdhL0DUI8zwWbrKMLsi5nBbJgpnIiTlNx6WMejEEzfbsKoNEoLSSCl3yBr8duLNpFvEJaY5UuA0flvGZz/LwTuPS8lHSRjSwxaBRDsNNWQhYzW/mAO4vQ+Reg3x4jJyQ+A5OrV/YYiZU97vwA0+nvGYGLtG40bXlvjR9eUkg8FqX1mGHlKavc3Kz/R+2dO2f1e4dDok2upOwFxUN4m89CJ1NawXeG+KYtJz2f4cVnpJt7fakA4Yl3DXs1SEd9BoUKfjIZvwuPAVtqO0BaCS/cd8ck7V10YPrggNWDFhxm49bWcuQJRv3t+DYRlgPWd1b3wWFBCI88rx0TAxzh2XoEmSxkvwzacVthNliOmrw/ClM0/EFlQtmAla1oWdXPcWQySb3XOkm2VGbhKzI4EVvHnmfVK9qHkWSIvrHrDqoVBBMFdWf8e34KBlUdU5vmFBAkEsVhgxsTXurUXjykA4IefSLUuOrgQswWmoOspjRzb1uVo01jPcoctQNEBYWzQrB3OvgPaFDJEMP8hAtW/0e9hu+b5dyolYA+NOVRxvpvO2TXk/XzELQ+Wr2nCT/pc/zglTe6I/dIFJjXnv/LKnJ9bbcT4HF1BTxlJT2sLVhtQ3aFsCBlx03EsloOnuCVmb4ZfciI4pfbLpB2rLyoXUuPKqXIfbv6//5wkIPpEorMU7cY9cqskB1UJ7kbsSoS12GV318F4Ow8DEuC2IPYaKEh2XMKVZBk15lVJJdK93WIpNtvR19a9Ed9veVczCmAlIyRHVPLYtkV4Ad90zEbp6YwlC3HI9d94li6iYMDN4KNsFSh+sIATh0jTYBE+ylno6Dv3mrKueSufdMgq9mST5aenNmTQ5QTJHHa68qsPJ/FcJnS0d2V0/ioAosmtgRYv+eDSJdiemp5mvUWxTf0jKaZ13jF/La1ZL1UqfIMdiNBedwWc09bQ1mBnY2f7VqU1mtZmqbPxkZtnGzVZNyL7ZsP94quhSmcKDe+LaCIgP0QBWWjMIDVOjziMb6ZrEseCpI9TkGT0k76d9ALTY5lFLDCk8yMGKYk4+4MIhY5e3TPstBt/HhNS3VqmC8ZLVC2nTuv6Xz31xUrP6BHvS5lWSkUfhOkLRAGYSOP7ZW6saQ1S9+gVuvATee3fIRAFuYTPNNl7GXZx+j7f/2QoEPN2LWCODphFS2rHKq5kxSfc7Ml6FDnWMxszJTKyacK+7YHKmMzxZj3OEB0DMrrLuM/mesI2z7vwFN66jS0rcyoqpTleGM1e1yyAUBibj7HLX7USEQrDN0Mk3bHMg5wGYCd/PpCqBoCrQc1OUsrdeI9irlANmr5L7CZwqi7BrzlgS4rpgHweLttyV3RtTsxu3F2dgDMiJcqSYfbg4XhkcbNnSD2wocxAxvx6BzXbkW7k90hdEbUyduKkMSSRYllGw8X1c8MR7cYAA56JkqJ6is65vrHM+fMs= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(376014)(1800799024)(82310400026)(36860700013);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Feb 2025 10:00:30.3236 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 845fbab7-6e5f-44ad-c154-08dd57debbf1 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SA2PEPF00003AE9.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH0PR12MB8529 Test cross-vCPU IPI for Secure AVIC guests using xapic_ipi_test. Add new "SAVIC" apic mode to the test for this. 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 | 70 ++++++++++++++----- 3 files changed, 55 insertions(+), 20 deletions(-) diff --git a/tools/arch/x86/include/asm/msr-index.h b/tools/arch/x86/include/asm/msr-index.h index 3ae84c3b8e6d..93f3ff9991cc 100644 --- a/tools/arch/x86/include/asm/msr-index.h +++ b/tools/arch/x86/include/asm/msr-index.h @@ -680,7 +680,9 @@ #define MSR_AMD64_SNP_VMSA_REG_PROT BIT_ULL(MSR_AMD64_SNP_VMSA_REG_PROT_BIT) #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_VIRT_SPEC_CTRL 0xc001011f diff --git a/tools/testing/selftests/kvm/include/x86/processor.h b/tools/testing/selftests/kvm/include/x86/processor.h index 3f9369644962..f09b18944c47 100644 --- a/tools/testing/selftests/kvm/include/x86/processor.h +++ b/tools/testing/selftests/kvm/include/x86/processor.h @@ -201,6 +201,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_SNP KVM_X86_CPU_FEATURE(0x8000001F, 0, EAX, 4) +#define X86_FEATURE_SECURE_AVIC KVM_X86_CPU_FEATURE(0x8000001F, 0, EAX, 26) /* * KVM defined paravirt features. diff --git a/tools/testing/selftests/kvm/x86/xapic_ipi_test.c b/tools/testing/selftests/kvm/x86/xapic_ipi_test.c index 3a54d828dc69..e11c7ded8b8a 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" /* Default running time for the test */ #define DEFAULT_RUN_SECS 3 @@ -45,30 +46,44 @@ */ #define IPI_VECTOR 0xa5 +enum apic_mode { + XAPIC, + X2APIC, + SAVIC, +}; + /* * Incremented in the IPI handler. Provides evidence to the sender that the IPI * arrived at the destination */ static volatile uint64_t *ipis_rcvd; -static bool x2apic; +static int apic_mode; 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; + } } static uint32_t apic_read_reg(unsigned int reg) { - return x2apic ? x2apic_read_reg(reg) : xapic_read_reg(reg); + return apic_mode != XAPIC ? x2apic_read_reg(reg) : xapic_read_reg(reg); } static void apic_write_reg(unsigned int reg, uint64_t val) { - if (x2apic) + if (apic_mode != XAPIC) x2apic_write_reg(reg, val); else xapic_write_reg(reg, (uint32_t)val); @@ -144,7 +159,7 @@ static void halter_guest_code(struct test_data_page *data) static void guest_ipi_handler(struct ex_regs *regs) { (*ipis_rcvd)++; - apic_write_reg(APIC_EOI, 77); + apic_write_reg(APIC_EOI, 0); } static void sender_guest_code(struct test_data_page *data) @@ -184,7 +199,7 @@ static void sender_guest_code(struct test_data_page *data) * First IPI can be sent unconditionally because halter vCPU * starts earlier. */ - if (!x2apic) { + if (apic_mode == XAPIC) { apic_write_reg(APIC_ICR2, icr2_val); apic_write_reg(APIC_ICR, icr_val); } else { @@ -385,10 +400,10 @@ void do_migrations(struct test_data_page *data, int run_secs, int delay_usecs, } 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 = getopt(argc, argv, "s:d:v:me:t:"); + int opt = getopt(argc, argv, "s:d:v:me:t:g"); if (opt == -1) break; @@ -403,7 +418,7 @@ void get_cmdline_args(int argc, char *argv[], int *run_secs, *delay_usecs = parse_size(optarg); break; case 'e': - *x2apic = parse_size(optarg) == 1; + *apic_mode = parse_size(optarg); break; case 't': *vm_type = parse_size(optarg); @@ -431,7 +446,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 AVIC" " Default is xAPIC.\n" "-t . Default is %d.\n" "Supported values:\n" @@ -483,10 +498,17 @@ int main(int argc, char *argv[]) bool is_sev; get_cmdline_args(argc, argv, &run_secs, &migrate, &delay_usecs, - &x2apic, &vm_type); + &apic_mode, &vm_type); + if (apic_mode == SAVIC) { + vm_type = KVM_X86_SNP_VM; + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SNP)); + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_IDLE_HLT)); + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SECURE_AVIC)); + } + is_sev = is_sev_vm_type(vm_type); - if (x2apic) + if (apic_mode != XAPIC) migrate = 0; if (run_secs <= 0) @@ -494,18 +516,28 @@ int main(int argc, char *argv[]) if (delay_usecs <= 0) delay_usecs = DEFAULT_DELAY_USECS; - if (is_sev) + if (apic_mode == SAVIC) { + struct kvm_sev_init args = { .vmsa_features = BIT_ULL(SVM_FEAT_SECURE_AVIC) | + BIT_ULL(SVM_FEAT_ALLOWED_SEV_FEATURES_VALID) + }; + + vm = _vm_sev_create_with_one_vcpu(vm_type, halter_guest_code, + ¶ms[0].vcpu, &args); + } else if (is_sev) { vm = vm_sev_create_with_one_vcpu(vm_type, halter_guest_code, ¶ms[0].vcpu); - else + } else { vm = vm_create_with_one_vcpu(¶ms[0].vcpu, halter_guest_code); + } vm_install_exception_handler(vm, IPI_VECTOR, guest_ipi_handler); - if (is_sev_es_vm(vm)) + if (apic_mode == 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); - sync_global_to_guest(vm, x2apic); - if (!x2apic) + sync_global_to_guest(vm, apic_mode); + if (apic_mode == XAPIC) virt_pg_map(vm, APIC_DEFAULT_GPA, APIC_DEFAULT_GPA); params[1].vcpu = vm_vcpu_add(vm, 1, sender_guest_code); From patchwork Fri Feb 28 09:30:18 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996136 Received: from NAM11-BN8-obe.outbound.protection.outlook.com (mail-bn8nam11on2050.outbound.protection.outlook.com [40.107.236.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 6C76625BAA3; Fri, 28 Feb 2025 10:02:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.236.50 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736960; cv=fail; b=Qj/oLYkoMga4RMTnV73mz0+Rkcvsa9jAd8HpfgA9ynvWdRCWEY0fGdIhisJlaleLsZUjhMMKC71jIdCWpbI1KOmocHs/OC8miJZxZgvreQ+YkgZoYVcB7JzIedtV2d27XGI5PWaRD6VdLUwHJSN1NOIBZbSo9Y1eyFSprz4oERA= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740736960; c=relaxed/simple; bh=wjTJm2vNvpkc0ZwJ+l8CyiYuDNczhAOIvhuXgCsCg2A=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=pKjusb4+1YtZlss2NcLtanta9T9ZuPtz3JKLWMmmIaV0QGA9AjrKOPlkyHNCOEzahSZi1aVJhvjm+sTzN1/S4BWmAv/1ePEmE9KZGxdrjOZ9nSYNbmgTfLcusZeL5szsb9PjEK4irbCHd/4NmyyxlyUGgELduQXy0BGjc+D1/Yo= 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=VPVcan9n; arc=fail smtp.client-ip=40.107.236.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="VPVcan9n" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=F9VL+00PgsVFz5qoIar5ddnCX1VH4mJlhD/dxs27aU0annJqsIqXL7YbZ3+P2oIoMJUb3l/uwndHnJm/WBJhV9IkYDRtcIOH0q8XDE9bDqK6znGjAHgB1G1OXf0QjugbUkxBsZh9Chqlzc1YWQiDlEoTxF5g14qjjFy5xVzqXIE/SXVXO0NNtLEPdB0i3dNULW12fZ1sg38XtUamfaEF9OMwsYldvwZ1IhmKaDJM17K65UA2n7Y2R3lzH7ZNZRQSANK/kHpRQeC9FlTngxGYZ5YuBvHJr+MHv/92b652Vs4Ki8/WGFjcCStaz2uHCcAaavrEwGKPjufxP9AgibIH6g== 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=d1kceKccxj4kvkEUhwgbjtbI6bLQhfpAC6ZvyHclM/Q=; b=GDfwvVeBFKMrdHbzpkg3nhK+1sFx6dvq9Z1v9ogaqpRVXhV2rUTXANavOss6mqnoSeXBhT5r1pk1BU9Gbno/JH5g/mILfBmRCgKamHMZ4hWHeUXPoIZAbvrM6ovcTEuBuz2yBv04A1nmuZJYaB/+rKvn9Dox29Cnd6Cly27yOPxxZa2wxv+E2Qqtnz8AfHypy93GxnEjgSzJqCdP5SOtdNQiuDkdfg18a74iwZ+bjPe/WHGkZTqVhlhqIcq6klarTppB8d+ahVIFDbgQC6+Hd6Ae2PHkTvtbOcWaQEB/m3R0Q8a7FLSe3i8d69gygYBiohy9bSlTgGGQdymW3pGxJw== 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=d1kceKccxj4kvkEUhwgbjtbI6bLQhfpAC6ZvyHclM/Q=; b=VPVcan9ntk0AEAp+a4cjO9ZyFm+OSNLg2dczxFXEAtFT8TCACEMxeOnNwz13DYCz1zc4VhsghjCPdywziKubySQ+bKjLW8VavG3H5OWDV+NPn6agtTq6E7UGdaKaLM6mqcYjmCsyw33aQEMh9DuF+r4gL8gK8mlZ3Wm4Hx9BcCY= Received: from SA9PR13CA0113.namprd13.prod.outlook.com (2603:10b6:806:24::28) by SA3PR12MB7973.namprd12.prod.outlook.com (2603:10b6:806:305::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8489.22; Fri, 28 Feb 2025 10:02:32 +0000 Received: from SA2PEPF00003AE5.namprd02.prod.outlook.com (2603:10b6:806:24:cafe::b4) by SA9PR13CA0113.outlook.office365.com (2603:10b6:806:24::28) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8511.10 via Frontend Transport; Fri, 28 Feb 2025 10:02:32 +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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by SA2PEPF00003AE5.mail.protection.outlook.com (10.167.248.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 10:02:32 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 04:01:00 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 25/31] KVM: selftests: Add Secure AVIC APIC regs test Date: Fri, 28 Feb 2025 15:00:18 +0530 Message-ID: <20250228093024.114983-26-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SA2PEPF00003AE5:EE_|SA3PR12MB7973:EE_ X-MS-Office365-Filtering-Correlation-Id: b15ac66d-8c3a-41fe-eb7b-08dd57df04d2 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|82310400026|36860700013|376014; X-Microsoft-Antispam-Message-Info: AW/lpnvOd20eqHR+O3QUFdB8qpyg+jzHQzkZb2sBZPS5BCPa7dYQUg6+Uw7JPKWF8brTsuE2A2/eh7NnNePQ06nziFI5umeaxF9M5xINbCYxYHB+WjSKSNLM5zCsZcAVM2Yi8KN3/VTRL2K+5g/OKR0Cj//ZbN+oBtySIkQau0VBm8AmhmE1MURYS3n2WatLYS3z8RDdqgKJGNGY2GxGI6PsbSxsT2WvEZ7iF2s7YK9XxMkk0nWyz+S3oQI2KhqJliZBzBmDVhvcrxRTqobJjoEBoA8D61sw0H9LJcvky8iK3Nx6UUWyCywtybv+5+bmXMDr4e193Nh0NB/KjqiZCF/eVMBb3HNZBnwCQ/ZpOCbtXhC/yTnYlaFy8uzHSiWdehUQ17JsssKI0zfKvOZN27uoSeZ9i/1YkDr3DVy3cR9TyEsA0ucJMMNDZbbftvsg0iryHDl+/Mpl6GrQKREFO8XqO/0+KIG5Ua16s8BSKeKnsjBM00h9eQaef8hdO0v6v7cdmVcjMHQw5uqcqIwkI5Rt4z0fNuOHxObn+q8d6B6CTnsgCw27A5kONthZ1M1fPyioaGPCUG2/w9bw+n3jElpNCdRhiOm6/Hr0natZg4F+SIPP16beqxqt1NimpaHk94nr4X72Al8WZXZgYm+YgzIczGCQuE7HlFQJcMdiNqPXCNBIWoEgwG7zc0CoL2fefHl9Z+IOG2lSeKLL3tLAschvLiq47gr01z7eZjvtW16BuHuUXU+DRLI+xRL+J03yaaDoob30O2L1DXAPUE8+vhZs6sbXZUMiELnvbbpBb8EwmW1GsSRLUurlaMHjAbtHJ2iM5SWc96YzzobvNKTBPlAfgb+rjneqXBdp+/uDYc86ksvXsvntLVHDOL8rmrupSCcIqcvupI4CrzDx8qnlnK45zIX73ITMUsQBZnlj1ad9l/SGm+4N/OGrhw1vQvy5Qr5tiNRhzZMkJMzu1cArRJmCwvw/5HlCHJbDvGHr7fvVq0dqGLZhLpHfqFY24gHeb1P3HBbm6gdLnM9dVe4/1zsHNCIuVE2vfGBq3FdUuUq+95viWtr4rhwNp+Dcj+fF4EdVSZXZeS6cHrEBrub8+FKv6nM7AW9cfotHyqj+/5EEBFxHaF2CpW85pBSWrVo5HNbrlucGucV7DKN24hTLGKNa9eJX/ovT9prKqORNKCMUs8QTuzTZgTqeiF783SElDtdzlfWnTpgAlerKiZj0cT9dGbeG5OwKWWaJTeaIBHXFQIex5NZqX5fRfbOECYI+zFWPGJDKT8vEE3cNEfRHTDpl5mQDq5hZ2NaUBPWDYQ31i5L41XtLt3eDpXnFo66zXpHzoPekOGFRc3g6V5erZlLtOD3WKVOPS2Nv7Ddp4CJa3GIdwhFnkU6XXEXXJKwSnk+1YLI1+1gO3kMfNpXudzINwMt8CnVbQxdSxg82nJJDGJ4WZvMvHrgEZ+OLxKSvPhztOFNiQg/zpIIS7g2U7oEARIZkrkWLdORdvn0izHc= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(82310400026)(36860700013)(376014);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Feb 2025 10:02:32.5797 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: b15ac66d-8c3a-41fe-eb7b-08dd57df04d2 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SA2PEPF00003AE5.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA3PR12MB7973 Add a APIC regs to verify APIC register updates at various stages in Secure AVIC guest's APIC enablement. In summary, do below validations: - Verify that the initial reset of APIC is xapic. - Values written by SAVIC guest in xapic mode are propagated to host APIC state. - APIC regs state updates by host are propagated to guest in x2apic mode. - In x2apic mode, APIC regs updates by SAVIC guest are propagated to host APIC state. - Post SAVIC enablement, init guest APIC backing page state is same as the host APIC regs state for unaccelerated registers. - Post SAVIC enablement, APIC updates done by guest are propagated to host for unaccelerated APIC registers. For accelerated APIC registers, updates are not propagated to host. Signed-off-by: Neeraj Upadhyay --- tools/testing/selftests/kvm/Makefile.kvm | 1 + .../testing/selftests/kvm/include/x86/savic.h | 1 + tools/testing/selftests/kvm/lib/x86/savic.c | 13 +- tools/testing/selftests/kvm/x86/savic_test.c | 462 ++++++++++++++++++ 4 files changed, 476 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/kvm/x86/savic_test.c diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm index 50bd78e03d9f..51338d1901e0 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -77,6 +77,7 @@ TEST_GEN_PROGS_x86 += x86/pmu_counters_test TEST_GEN_PROGS_x86 += x86/pmu_event_filter_test TEST_GEN_PROGS_x86 += x86/private_mem_conversions_test TEST_GEN_PROGS_x86 += x86/private_mem_kvm_exits_test +TEST_GEN_PROGS_x86 += x86/savic_test TEST_GEN_PROGS_x86 += x86/set_boot_cpu_id TEST_GEN_PROGS_x86 += x86/set_sregs_test TEST_GEN_PROGS_x86 += x86/smaller_maxphyaddr_emulation_test diff --git a/tools/testing/selftests/kvm/include/x86/savic.h b/tools/testing/selftests/kvm/include/x86/savic.h index 238d7450ab6e..cb432eb527b3 100644 --- a/tools/testing/selftests/kvm/include/x86/savic.h +++ b/tools/testing/selftests/kvm/include/x86/savic.h @@ -17,4 +17,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/selftests/kvm/lib/x86/savic.c index ae48978479bf..d4c9fcf835ad 100644 --- a/tools/testing/selftests/kvm/lib/x86/savic.c +++ b/tools/testing/selftests/kvm/lib/x86/savic.c @@ -105,6 +105,11 @@ void set_savic_control_msr(struct guest_apic_page *apic_page, bool enable, bool wrmsr(MSR_AMD64_SECURE_AVIC_CONTROL, val); } +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. * @@ -176,11 +181,17 @@ static void savic_init_backing_page(struct guest_apic_page *apic_page, uint32_t regval = savic_hv_read_reg(APIC_LDR); savic_write_reg(apic_page, APIC_LDR, regval); - for (i = LVT_THERMAL_MONITOR; i < APIC_MAX_NR_LVT_ENTRIES; i++) { + for (i = LVT_TIMER; i < APIC_MAX_NR_LVT_ENTRIES; i++) { regval = savic_hv_read_reg(APIC_LVTx(i)); savic_write_reg(apic_page, APIC_LVTx(i), regval); } + regval = savic_hv_read_reg(APIC_TMICT); + savic_write_reg(apic_page, APIC_TMICT, regval); + + regval = savic_hv_read_reg(APIC_TDCR); + savic_write_reg(apic_page, APIC_TDCR, regval); + regval = savic_hv_read_reg(APIC_LVT0); savic_write_reg(apic_page, APIC_LVT0, regval); diff --git a/tools/testing/selftests/kvm/x86/savic_test.c b/tools/testing/selftests/kvm/x86/savic_test.c new file mode 100644 index 000000000000..ca1d7352bc3e --- /dev/null +++ b/tools/testing/selftests/kvm/x86/savic_test.c @@ -0,0 +1,462 @@ +// 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 { + /* Reset state of APIC regs */ + SAVIC_TEST_STATE(RESET), + /* APIC regs state on X2apic enablement */ + SAVIC_TEST_STATE(X2APIC_ENABLE), + /* APIC regs state on Secure AVIC enablement */ + SAVIC_TEST_STATE(SAVIC_EN), +}; + +/* APIC reg values written by host. */ +enum savic_test_host_vals { + H_APIC_TASKPRI_VAL = 0x30, + H_APIC_LVTT_VAL = APIC_DM_FIXED | 0x30, + H_APIC_LVTTHMR_VAL = APIC_DM_FIXED | 0x31, + H_APIC_LVTPC_VAL = APIC_DM_FIXED | 0x32, + H_APIC_LVT0_VAL = APIC_DM_FIXED | 0x33, + H_APIC_LVT1_VAL = APIC_DM_FIXED | 0x34, + H_APIC_TMICT_VAL = 0x555555, + H_APIC_TDCR_VAL = 0x3, +}; + +/* APIC reg values written by guest. */ +enum savic_test_guest_vals { + G_APIC_TASKPRI_VAL = 0x40, + G_APIC_LVTT_VAL = APIC_DM_FIXED | 0x40, + G_APIC_LVTTHMR_VAL = APIC_DM_FIXED | 0x41, + G_APIC_LVTPC_VAL = APIC_DM_FIXED | 0x42, + G_APIC_LVT0_VAL = APIC_DM_FIXED | 0x43, + G_APIC_LVT1_VAL = APIC_DM_FIXED | 0x34, + G_APIC_TMICT_VAL = 0xaaaaaa, + G_APIC_TDCR_VAL = 0x1, +}; + +struct reg_ent { + char *regname; + uint32_t reg; + uint64_t val; +}; + +#define CREATE_H_REG_ENTRY(_reg) {\ + .regname = #_reg, \ + .reg = _reg, \ + .val = H_ ## _reg ## _VAL \ +} + +#define CREATE_G_REG_ENTRY(_reg) {\ + .regname = #_reg, \ + .reg = _reg, \ + .val = G_ ## _reg ## _VAL \ +} + +static struct reg_ent host_apic_regs[] = { + CREATE_H_REG_ENTRY(APIC_TASKPRI), + CREATE_H_REG_ENTRY(APIC_LVTT), + CREATE_H_REG_ENTRY(APIC_LVTTHMR), + CREATE_H_REG_ENTRY(APIC_LVTPC), + CREATE_H_REG_ENTRY(APIC_LVT0), + CREATE_H_REG_ENTRY(APIC_LVT1), + CREATE_H_REG_ENTRY(APIC_TMICT), + CREATE_H_REG_ENTRY(APIC_TDCR), +}; + +static struct reg_ent guest_apic_regs[] = { + CREATE_G_REG_ENTRY(APIC_TASKPRI), + CREATE_G_REG_ENTRY(APIC_LVTT), + CREATE_G_REG_ENTRY(APIC_LVTTHMR), + CREATE_G_REG_ENTRY(APIC_LVTPC), + CREATE_G_REG_ENTRY(APIC_LVT0), + CREATE_G_REG_ENTRY(APIC_LVT1), + CREATE_G_REG_ENTRY(APIC_TMICT), + CREATE_G_REG_ENTRY(APIC_TDCR), +}; + +/* Context which is doing testing of APIC regs values. */ +enum context { + CTXT_HOST, + CTXT_GUEST, +}; + +static struct kvm_lapic_state apic_state[NR_SAVIC_VCPUS]; + +/* + * Write APIC reg from host or guest context. + * + * @id : vCPU id (required only for host context). + * @reg : APIC reg offset. + * @ctxt : Context which is doing write operation. + * @val : New value to write to the reg. + * x2apic : x2apic is enabled. + */ +static void write_apic_reg(int id, uint32_t reg, enum context ctxt, + uint32_t val, bool x2apic) +{ + if (ctxt == CTXT_HOST) { + *(uint32_t *)&apic_state[id].regs[reg] = val; + } else { + if (x2apic) + x2apic_write_reg(reg, val); + else + xapic_write_reg(reg, val); + } +} + +/* + * Read APIC reg from host or guest context. + * + * @id : vCPU id (required only for host context). + * @reg : APIC reg offset. + * @ctxt : Context which is doing read operation. + * + * + * Returns APIC register value. + */ +static uint32_t read_apic_reg(int id, uint32_t reg, enum context ctxt, bool x2apic) +{ + if (ctxt == CTXT_HOST) + return *(uint32_t *)&apic_state[id].regs[reg]; + + if (x2apic) + return x2apic_read_reg(reg); + else + return xapic_read_reg(reg); +} + +/* + * Set test APIC regs values from host/guest context. + * + * @id : vCPU ID for which APIC state is set. + * @host : Test APIC regs data source values. + * @ctxt : Context from which this function is called. + * @x2apic : X2apic is enabled. + */ +static void set_apic_vals(int id, bool host, enum context ctxt, bool x2apic) +{ + struct reg_ent *reg_entries; + struct reg_ent ent; + int i; + + if (host) + reg_entries = host_apic_regs; + else + reg_entries = guest_apic_regs; + + if (ctxt == CTXT_HOST) + memset(&apic_state[id], 0, sizeof(apic_state[i])); + + for (i = 0; i < ARRAY_SIZE(host_apic_regs); i++) { + ent = reg_entries[i]; + write_apic_reg(id, ent.reg, ctxt, ent.val, x2apic); + } + + if (ctxt == CTXT_HOST) + vcpu_ioctl(vcpus[id], KVM_SET_LAPIC, &apic_state[id]); +} + +#define CTXT_ASSERT(ctxt, reg, exp, val) \ + do { \ + if (ctxt == CTXT_HOST) \ + TEST_ASSERT(exp == val, \ + "Unexpected %s %s val: 0x%x expected 0x%x\n", \ + "host", reg, val, exp); \ + else \ + __GUEST_ASSERT(exp == val, \ + "Unexpected %s %s val: 0x%x expected 0x%x\n", \ + "guest", reg, val, exp); \ + } while (0) + +/* + * Test APIC regs values from host/guest context. + * + * @id : vCPU ID for which values are tested. + * @host : Test APIC regs expected values data source. + * @ctxt : Context from which this function is called. + * @x2apic : X2apic is enabled. + * @savic : Secure AVIC is enabled. + */ +static void test_apic_vals(int id, bool host, enum context ctxt, bool x2apic, + bool savic) +{ + uint32_t exp_regval, regval; + struct reg_ent *reg_entries; + struct reg_ent ent; + char *regname; + uint32_t reg; + int i; + + if (host) + reg_entries = host_apic_regs; + else + reg_entries = guest_apic_regs; + + + if (ctxt == CTXT_HOST) + vcpu_ioctl(vcpus[id], KVM_GET_LAPIC, &apic_state[id]); + + for (i = 0; i < ARRAY_SIZE(host_apic_regs); i++) { + ent = reg_entries[i]; + reg = ent.reg; + /* APIC_TASKPRI is accelerated in guest and not synced in host APIC state. */ + if (savic && reg == APIC_TASKPRI) { + if (ctxt == CTXT_GUEST) + continue; + else + ent = host_apic_regs[i]; + } + regname = ent.regname; + exp_regval = ent.val; + regval = read_apic_reg(id, reg, ctxt, x2apic); + CTXT_ASSERT(ctxt, regname, exp_regval, regval); + } +} + +#define SAVIC_GUEST_SYNC(sync, func) ({\ + GUEST_SYNC(sync ## _START); \ + func(id); \ + GUEST_SYNC(sync ## _END); \ +}) + +static void savic_write_apic_regs(struct guest_apic_page *apage) +{ + struct reg_ent ent; + uint32_t regval; + uint32_t reg; + int i; + + for (i = 0; i < ARRAY_SIZE(guest_apic_regs); i++) { + ent = guest_apic_regs[i]; + reg = ent.reg; + regval = ent.val; + savic_write_reg(apage, reg, regval); + if (reg != APIC_TASKPRI) + savic_hv_write_reg(reg, regval); + } +} + +static void guest_test_and_set_apic_regs(int id, bool x2apic) +{ + /* + * On guest entry, APIC reg values read from guest context matches + * the previous values set by host. + */ + test_apic_vals(id, true, CTXT_GUEST, x2apic, false); + set_apic_vals(id, false, CTXT_GUEST, x2apic); + test_apic_vals(id, false, CTXT_GUEST, x2apic, false); +} + +static void guest_savic_start(int id) +{ + guest_test_and_set_apic_regs(id, false); +} + +static void guest_x2apic_enabled(int id) +{ + guest_test_and_set_apic_regs(id, true); +} + +static void guest_savic_enabled(int id) +{ + struct guest_apic_page *apage = get_guest_apic_page(); + + /* Host values are written to guest backing page */ + test_apic_vals(id, true, CTXT_GUEST, true, true); + /* Update host APIC regs with guest values */ + savic_write_apic_regs(apage); +} + +static void guest_code(int id) +{ + GUEST_ASSERT(rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SNP_SECURE_AVIC); + + SAVIC_GUEST_SYNC(RESET, guest_savic_start); + + x2apic_enable(); + + SAVIC_GUEST_SYNC(X2APIC_ENABLE, guest_x2apic_enabled); + + savic_enable(); + + SAVIC_GUEST_SYNC(SAVIC_EN, guest_savic_enabled); + + GUEST_DONE(); +} + +static void host_reset_s_test_apic_regs(struct kvm_vcpu *vcpu) +{ + /* Set and test APIC regs before guest entry. */ + set_apic_vals(vcpu->id, true, CTXT_HOST, false); + test_apic_vals(vcpu->id, true, CTXT_HOST, false, false); +} + +static void host_reset_s(int id) +{ + struct kvm_vcpu *vcpu = vcpus[id]; + uint64_t apic_base; + + apic_base = vcpu_get_msr(vcpu, MSR_IA32_APICBASE); + TEST_ASSERT(apic_base & MSR_IA32_APICBASE_ENABLE, + "APIC not in ENABLED state at vCPU RESET"); + TEST_ASSERT(!(apic_base & X2APIC_ENABLE), + "APIC not in xAPIC mode at vCPU RESET"); + host_reset_s_test_apic_regs(vcpu); +} + +static void host_reset_e(int id) +{ + /* On guest exit, APIC regs state must match guest values. */ + test_apic_vals(id, false, CTXT_HOST, false, false); + /* Reset the APIC regs to host values. */ + set_apic_vals(id, true, CTXT_HOST, false); +} + +static void host_x2apic_enabled_s(int id) +{ + struct kvm_vcpu *vcpu = vcpus[id]; + uint64_t apic_base; + + apic_base = vcpu_get_msr(vcpu, MSR_IA32_APICBASE); + TEST_ASSERT(apic_base & X2APIC_ENABLE, "APIC not in x2APIC mode"); + + /* + * On guest x2apic enablement, previous APIC regs values + * which were set by host are preserved. + */ + test_apic_vals(id, true, CTXT_HOST, true, false); + set_apic_vals(id, true, CTXT_HOST, true); + test_apic_vals(id, true, CTXT_HOST, true, false); +} + +static void host_x2apic_enabled_e(int id) +{ + /* + * In guest x2apic enabled mode, guest written states are propagated + * to host APIC state. + */ + test_apic_vals(id, false, CTXT_HOST, true, false); + set_apic_vals(id, true, CTXT_HOST, true); +} + +static void host_post_savic_en_start(int id) +{ + /* Host APIC regs before SAVIC enablement are not lost. */ + test_apic_vals(id, true, CTXT_HOST, true, true); + set_apic_vals(id, true, CTXT_HOST, true); +} + +static void host_post_savic_en_end(int id) +{ + /* + * LVTT and other emulated APIC regs are propagated to host APIC + * state by SAVIC guest. + */ + test_apic_vals(id, false, CTXT_HOST, true, true); +} + +static void host_test_savic(struct kvm_vm *vm, int id, enum savic_test_state test_state) +{ + switch (test_state) { + case RESET_START: + host_reset_s(id); + break; + case RESET_END: + host_reset_e(id); + break; + case X2APIC_ENABLE_START: + host_x2apic_enabled_s(id); + break; + case X2APIC_ENABLE_END: + host_x2apic_enabled_e(id); + break; + case SAVIC_EN_START: + host_post_savic_en_start(id); + break; + case SAVIC_EN_END: + host_post_savic_en_end(id); + break; + default: + break; + } +} + +static void *vcpu_thread(void *arg) +{ + struct kvm_vcpu *vcpu = (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: + host_test_savic(vcpu->vm, vcpu->id, uc.args[1]); + 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 = { .vmsa_features = BIT_ULL(SVM_FEAT_SECURE_AVIC) | + BIT_ULL(SVM_FEAT_ALLOWED_SEV_FEATURES_VALID) + }; + struct kvm_vm *vm; + int r; + + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SNP)); + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SECURE_AVIC)); + + vm = _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, sev_es_vc_handler); + vm_sev_launch(vm, snp_default_policy(), NULL); + + r = pthread_create(&threads[0], NULL, vcpu_thread, vcpus[0]); + TEST_ASSERT(r == 0, "pthread_create failed errno=%d", errno); + + pthread_join(threads[0], NULL); + + kvm_vm_free(vm); + + return 0; +} From patchwork Fri Feb 28 09:30:19 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996137 Received: from NAM10-MW2-obe.outbound.protection.outlook.com (mail-mw2nam10on2045.outbound.protection.outlook.com [40.107.94.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 64B7825D910; Fri, 28 Feb 2025 10:03:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.94.45 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740737019; cv=fail; b=prcGbZQuazhitsTeuOk/uoRjLfiBU3HUdp0iTV0adHoUEEz/cpfkr12RrhnUZNoHXC+Y7U6Zu/gsBjYcApHN+23DZehOUkPZc7DGPbRGj9mgcBUsWFUWMIOQF36tZVhc8jd7abvs+HXIlJPqOFEYuKW/HuDCY3cTqIjNfyswt/E= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740737019; c=relaxed/simple; bh=l2SdbOLx1UtR+zm0Y8CiXAS/lQGnBOdJx9qxeT7vIUE=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Kzz0IJAZsylc/lzOdJR5J1woWc2SMHsqHANWyn9ug6TJqX32rdALjbT0uzppN5zVcE+BbS08CTvB070PibLH4a3DlQf8KpJ2tn5iiHQdfV4wTfv8Q2rQAGNapt2WD6EGFwoe/ZMc9wXlLS2U8UcvE/2fSHceKLy5wDe6MIkZ4KU= 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=BTnbbg7s; arc=fail smtp.client-ip=40.107.94.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="BTnbbg7s" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=VlyLkSYe2XAhendbFXve+MENOTJ598sb7PlrEsrdgiaj/HnXx5my8KwqjysORyDAHhTbdiEeJ/RxypCAVTfFQDVCJyAXoT2PZBrZ8jQ28uqou2AIltCuhqd5iNDAa4YmpSmZoOYmpU81dOyJLBrzsbICC57ay1DjAc8+2urDEKu3yiGHQ0TUNk+9gGh/zHpbASwoY8+vjNPrVuWtcyeVnW/9wvRH+uq/yS4RYGebs5RjESB90+L/RPnENE9BxBa6VAYzTm3fCV12WNC/pWaZivCZvUgdu7VOHrKfHlTfSikMaAATWFdpWPdDJEfqdg8g+LU7YiDDAvtYIUkH6gKRjA== 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=sTAPrOe17RYinZ4WPSCZP78vnTnClburp1yunSCm6Wk=; b=FDn7BuxYGkOvdG1woLfgtQs0FnSyQDb+C0XSLsptsEQv+FIbDtkzJ6RiIe2Z3e/RuOomwcQF3hfWgQ3eORil1dtNcik78Irv03q5l3e0JJttky2aC63BPqXdMrE7LNxtLetTRXNSERQ23xfv6Di5J30tuYf/9Ke1mTeoZhfjmlHBS/VXEI3BvhOxHkSb/he/dh9U9vydihkHEGEUruCqx+Nlq2kAN8PlmGYe4S81Uxr+EA72qygpeyOYWPETxZ007nlWO10edMeFlP36DPKaIHgEjxHM3MDMNiuXhA2ILPo6KDV6IpFQogoLRXKnZEpRsvogoMnYJTY8MYaXG+pYoA== 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=sTAPrOe17RYinZ4WPSCZP78vnTnClburp1yunSCm6Wk=; b=BTnbbg7sQEpNSD+ZOa/aqXJ3wg3MYRgCdsRanQjEAQNI+nO8SIb1aENqXLlA8uEO+MaHKZad4YAj8TfJZl6CPYJ/Ts8Q9gEDHMNSYhj26rDtcN4MUDXs5vwT78PfIgSZILMro6t/2RBFAXTcnsEMqk+5ZiKYd9qJMf692yOqFZs= Received: from MW2PR16CA0046.namprd16.prod.outlook.com (2603:10b6:907:1::23) by CY5PR12MB6084.namprd12.prod.outlook.com (2603:10b6:930:28::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8489.19; Fri, 28 Feb 2025 10:03:33 +0000 Received: from SJ5PEPF000001D7.namprd05.prod.outlook.com (2603:10b6:907:1:cafe::b) by MW2PR16CA0046.outlook.office365.com (2603:10b6:907:1::23) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.21 via Frontend Transport; Fri, 28 Feb 2025 10:03: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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.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_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 10:03:32 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 04:02:59 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 26/31] KVM: selftests: Add test to verify APIC MSR accesses for SAVIC guest Date: Fri, 28 Feb 2025 15:00:19 +0530 Message-ID: <20250228093024.114983-27-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001D7:EE_|CY5PR12MB6084:EE_ X-MS-Office365-Filtering-Correlation-Id: 2efda854-17bc-4997-3d01-08dd57df28be 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: aAHUZQ2q46hRoDJECgTH5HrhprTHwqwiFs2fsBiOetQp9gCBK8JQ7YUMJUpQEUrdqrU4WE1HglHMFyBSejIG4U6RJdNgzdN8jDeUADP0wmyJbcyJbYIXkfJvN3zvkKTO0HmCLo8S0siySmPsXKbDYnnlFt8ah+MTwu34MC+KonOvYG/f0iabbE0ZZfMj8wYfuqaKhVMpTpMGxUm1AvP/3OrY8n32bdRqCd4iudXBsIph9bHKPmAMeQVVGkGFGGbn0k0KkH6kXZykhxjcphQJuE+6r7KkhdXQxDBhvXbkaRX0neV2xu/LclM9BnWNpU+039Tx3e9897Uv9agHvi/7VZRkJ3bfVrvsIjcHHusW8zQ6R9QezQgdWeUtQPDrOHyGjZvHylDNUZc2b91ZGx1/bwk0ylMXu13AlzLidGz8pTWuHWoSmroru//j3VjEAX0y9H8SiMu+iI6h+90aRw9OoZVUNFKkuBxYydnP49DKgwDloK8lSWGYf2oVYytdESrt+idhE2sRWNRplVUgN9S+GvsDudoAY9GdXUMb8uKLD4Do8HFiEIQbWWug5YpRYZ4h8U59GJoCeT/tjhs2Cncx7mSoh+67b2nbCyfEqgMBDGMC3ewBlB8rHF2HZuH5zXU2gyqYuwbKk7ztFpXDHLnCWPwuvm29g/Fd/3LB+xN/KAY/fpU1qW/EbsutTU8vkBKb14tdJGISetkKxI0jVoZckofA59nCeXPqKEUWLVk3PtQG84NO4FbHYpLFrPH/cbc5c2Z4WhYHZltjXrgjBJDEdSpSwwpZ5zbe3dYpwp9FRJ7ek0dKO6lkZ3ICDaHo377Yck35cZ8muL/IL0D152PCUg8ThlANuAfhCAkW61I6V6cf7JRMI6yak3rcVyeENzxbmiPzgC+JFW0yGovh9myE+bqQaI0QC0JlKz9Ku4rgSWdeItZMv5TnNlKzOZ5Qfa/WcUGGvi0VFz9IE8c4RjABCJ6PaEGoExbM6bPzWl9DRirX2j7kpkyIra4keeBK7NZRT3FbVhbUVhTGpupMrB+uf1e9/f4vYJZrttZvAg1iBHgE9P2m6oNz0nNqA6PXJ0Wnh9L6La55qIETFJgjvm8HedXme49/H1V789U72nBkvXFvpm2/heAwgogWaQScb6kyB6ZZjWiTv2UUyab33dO8JLvihWOhXq/5qtD8Nun+Zvdjm1NtAZLA5GuY7r4lfwzivVNqVlQDbepuzGuRGBw/S6k+yMHn+DrdNhP0KFbyT4MOwQ19/ieZ8p/CExXyotD5xV9pMBRsB91VzNt4qpwL7IZVn57Xo1mV45wTy8Gyi5lT5rC6O1eeXC/dh5GmUhe4vVFQGE4lCG9tUGb6BUZFe1GPy8eg16LBGXdnq6nNmZLYuMAHMP4Vp2q412wCsyd++CtHhgz42SByWHZUfvdW59nTE0kzf8aWzw080oFNl/B0685PICM9yRIMk2uLXueg4z8EzTUNxqzni/cFTy4vc6CEHX5U6lIdgQEnMNgx9/0= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.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: 28 Feb 2025 10:03:32.7639 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 2efda854-17bc-4997-3d01-08dd57df28be 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=[SATLEXMB04.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: CY5PR12MB6084 Extend SAVIC test to verify APIC MSR accesses in SAVIC enabled mode. Verify the behavior of reads and writes using rdmsr/wrmsr for various APIC registers. In addition, test whether wrmsr based writes are propagated to guest backing page. Signed-off-by: Neeraj Upadhyay --- .../testing/selftests/kvm/include/x86/apic.h | 1 + .../testing/selftests/kvm/include/x86/savic.h | 3 + tools/testing/selftests/kvm/lib/x86/savic.c | 7 +- tools/testing/selftests/kvm/x86/savic_test.c | 192 +++++++++++++++++- 4 files changed, 198 insertions(+), 5 deletions(-) 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/testing/selftests/kvm/include/x86/savic.h index cb432eb527b3..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 +#define APIC_REG_OFF(VEC) (VEC / 32 * 16) +#define APIC_VEC_POS(VEC) (VEC % 32) + struct guest_apic_page; void guest_apic_pages_init(struct kvm_vm *vm); diff --git a/tools/testing/selftests/kvm/lib/x86/savic.c b/tools/testing/selftests/kvm/lib/x86/savic.c index d4c9fcf835ad..c637e486b6e8 100644 --- a/tools/testing/selftests/kvm/lib/x86/savic.c +++ b/tools/testing/selftests/kvm/lib/x86/savic.c @@ -9,6 +9,7 @@ #include "kvm_util.h" #include "sev.h" #include "ex_regs.h" +#include "savic.h" struct apic_page { u8 apic_regs[PAGE_SIZE]; @@ -45,9 +46,6 @@ enum lapic_lvt_entry { #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 /* @@ -363,7 +361,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(vector))); + savic_write_reg(apic_page, APIC_IRR + APIC_REG_OFF(vector), + BIT(APIC_VEC_POS(vector))); } static bool is_cpu_present(int cpu) diff --git a/tools/testing/selftests/kvm/x86/savic_test.c b/tools/testing/selftests/kvm/x86/savic_test.c index ca1d7352bc3e..8cba7a81bce2 100644 --- a/tools/testing/selftests/kvm/x86/savic_test.c +++ b/tools/testing/selftests/kvm/x86/savic_test.c @@ -29,6 +29,7 @@ enum savic_test_state { SAVIC_TEST_STATE(X2APIC_ENABLE), /* APIC regs state on Secure AVIC enablement */ SAVIC_TEST_STATE(SAVIC_EN), + SAVIC_TEST_STATE(SAVIC_APIC_MSR_ACCESSES), }; /* APIC reg values written by host. */ @@ -288,6 +289,193 @@ static void guest_savic_enabled(int id) savic_write_apic_regs(apage); } +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 = APIC_BASE_MSR + (reg >> 4); + + switch (reg) { + case APIC_EOI: + uint8_t fault = rdmsr_safe(msr, &val); + + __GUEST_ASSERT(fault == GP_VECTOR, + "Wanted #GP on RDMSR(%x) = %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, uint32_t reg, + uint64_t val, char *regname) +{ + uint64_t hval, gval, gval2; + + if (savic_wrmsr(reg, val) == -1) { + savic_write_reg(apage, reg, val); + /* + * Write using PV interface if wrmsr fails. Skip for + * regs which trigger GP + */ + if (reg != APIC_LVR && reg != APIC_TMR && reg != APIC_IRR) + savic_hv_write_reg(reg, val); + } + + gval = savic_read_reg(apage, reg); + gval2 = savic_rdmsr(reg); + hval = savic_hv_read_reg(reg); + __GUEST_ASSERT(gval == val, "Unexpected Guest %s 0x%lx, expected val:0x%lx\n", + regname, gval, val); + __GUEST_ASSERT(gval == 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: + __GUEST_ASSERT(hval == gval, "Guest 0x%lx host 0x%lx %s mismatch\n", + gval, hval, regname); + break; + case APIC_TASKPRI: + case APIC_SPIV: + case APIC_ICR: + case APIC_TMR: + case APIC_IRR: + __GUEST_ASSERT(hval != gval, "Guest 0x%lx host 0x%lx reg: %x %s must not 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 = get_guest_apic_page(); + uint64_t val, hval; + uint32_t reg; + int vec; + int i; + uint32_t lvt_regs[] = { + APIC_LVTT, APIC_LVTTHMR, APIC_LVTPC, + APIC_LVT0, APIC_LVT1, APIC_LVTERR + }; + + reg = APIC_LVR; + val = 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 = APIC_TASKPRI; + val = 0x30; + /* Write new TASKPRI to host using PV interface. */ + savic_hv_write_reg(reg, val); + val = 0x40; + /* TASKPRI is accelerated and state is not up-to-date in host. */ + guest_verify_host_guest_reg(apage, reg, val, "APIC_TASKPRI"); + + reg = APIC_PROCPRI; + val = x2apic_read_reg(reg); + /* APIC_PROCPRI is updated with the APIC_TASKPRI update above. */ + GUEST_ASSERT((val & 0xf0) == (x2apic_read_reg(APIC_TASKPRI) & 0xf0)); + GUEST_ASSERT((val & 0xf0) == 0x40); + vec = 0x20; + x2apic_write_reg(APIC_ICR, APIC_DEST_SELF | APIC_INT_ASSERT | vec); + /* Interrupt remains pending in APIC_IRR. */ + val = savic_read_reg(apage, APIC_IRR + APIC_REG_OFF(vec)); + GUEST_ASSERT((val & BIT_ULL(APIC_VEC_POS(vec))) == BIT_ULL(APIC_VEC_POS(vec))); + savic_wrmsr(APIC_TASKPRI, 0x0); + + /* Triggers GP fault */ + savic_rdmsr(APIC_EOI); + + reg = APIC_LDR; + val = x2apic_ldr(savic_rdmsr(APIC_ID)); + hval = savic_hv_read_reg(APIC_LDR); + __GUEST_ASSERT(val == hval, "APIC_LDR mismatch between host %lx and guest %lx", + hval, val); + + /* APIC_SPIV state is not visible to host. */ + reg = APIC_SPIV; + val = savic_rdmsr(APIC_SPIV) & ~APIC_SPIV_APIC_ENABLED; + savic_hv_write_reg(reg, val); + val = savic_rdmsr(APIC_SPIV) | APIC_SPIV_APIC_ENABLED; + guest_verify_host_guest_reg(apage, reg, val, "APIC_SPIV"); + + reg = APIC_ISR; + (void) savic_rdmsr(reg); + /* Triggers GP fault */ + savic_wrmsr(reg, 0x10); + + /* APIC_TMR is not synced to host. */ + reg = APIC_TMR; + val = 0x10000; + guest_verify_host_guest_reg(apage, reg, val, "APIC_TMR"); + vec = 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 = APIC_IRR; + val = 0x10000; + guest_verify_host_guest_reg(apage, reg, val, "APIC_IRR"); + savic_write_reg(apage, reg, 0x0); + + reg = APIC_TMICT; + val = 0x555; + guest_verify_host_guest_reg(apage, reg, val, "APIC_TMICT"); + + reg = APIC_TMCCT; + savic_rdmsr(reg); + savic_wrmsr(reg, 0xf); + + reg = APIC_TDCR; + val = 0x1; + savic_hv_write_reg(reg, val); + val = 0x3; + guest_verify_host_guest_reg(apage, reg, val, "APIC_TDCR"); + + for (i = 0; i < ARRAY_SIZE(lvt_regs); i++) { + reg = lvt_regs[i]; + val = 0x41; + savic_hv_write_reg(reg, val); + val = 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); @@ -302,6 +490,8 @@ static void guest_code(int id) SAVIC_GUEST_SYNC(SAVIC_EN, guest_savic_enabled); + SAVIC_GUEST_SYNC(SAVIC_APIC_MSR_ACCESSES, guest_savic_apic_msr_accesses); + GUEST_DONE(); } @@ -448,7 +638,7 @@ int main(int argc, char *argv[]) vcpu_args_set(vcpus[0], 1, vcpus[0]->id); - vm_install_exception_handler(vm, 29, sev_es_vc_handler); + vm_install_exception_handler(vm, 29, savic_vc_handler); vm_sev_launch(vm, snp_default_policy(), NULL); r = pthread_create(&threads[0], NULL, vcpu_thread, vcpus[0]); From patchwork Fri Feb 28 09:30:20 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996138 Received: from NAM10-BN7-obe.outbound.protection.outlook.com (mail-bn7nam10on2083.outbound.protection.outlook.com [40.107.92.83]) (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 3928025E806; Fri, 28 Feb 2025 10:05:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.92.83 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740737121; cv=fail; b=N06YL4efC3WbHoSkP5zd3WEkaAnnXAB/LfMqOXJl0agB1oQ8wlPj/QEX5DQODCtIdMgCBNkanIWuwK8Y4OnEUYwIWSqloahTEOqJTdUIuLTQQLIbzX9KrZrlzepxcH/jDW8+YzlisUYSgSSrOaFNDCxR39+Pvq4PERhCkZ2wzi4= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740737121; c=relaxed/simple; bh=XqPwa9CiIqEp5yp2cUh8gKsfkGNNnnISCsIy84qaAnU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=WA0/reXDc28ZWVkPU79vtNCsD4f079hBb1MN4FSMAlHDvi6zv6PM3OfnAaWwch5e/PUSpgpnQOhNy7PERTSSgLq95kQAuQosyP+DKIhCVleRosm5BSvpYvqDky94MtChC/91dOpWklH8s6Cy0TSaHE9SpZ+laY8t5K2hAC/vPkM= 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=mjSZvwey; arc=fail smtp.client-ip=40.107.92.83 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="mjSZvwey" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=xQXe0wSvZfZhrUFGZvVa1Ty5gWSAFrx0ZCeSCXzXeLf9DB+4iM/MnkOxGJk0pT0WYrRJyharu00qhr1O7giFnKQenKj0c5N30j3qx32L8cIuF03TfkRmuCQaA6I/xlvb1+QL/I1Qf+tX4QOtLXHH0NUw4AhCPjmxE2vpQ+EXhEuz9NPJdsXaL/+jB8JvozRuxT/C7xx3MS7vJM9kQEii+ZM6cZvZ/fhrUwZSsRFotkjJg+GPPW7XM7BEk2Xn3Yio2Xiuqe1m6Tla8Yd6/lSjCKUP0Txe2tx4A+OzeLlvd3NRqz4VhWWFO0G145PWnTBngarVv02SifS49BJfSWOLvw== 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=ifE1bSqV7JpPbRCfYrQUd7WyU5nekgwpxobPH0MbUCY=; b=cfxTkw5jncf6JGEP0zlGUgaJ0VvLu/aCYMtoJXoy+QRxw0PoGb/ehIvX4tu0rffq+3D0JZ/rtp//PX9XWj2X6esOk+SmkJ+T3iLRXxT5HmCROMoA8oe6cVWrGIKT0k27n7hxCMtnDr6NWD+AKNz9VgShphXaSX0ghI6h9mwFrh8RJVFIA8qXfyUhzKWiqBt8UzGKgN8N/r+KYjROuz8vboT3KjEFE9VoB5dXzUJ6RcntnF6YIJHA24BbNNZ77DTNMyvwj55jnexceoDQhvRFmedn8nJoFjXDgZDvdUa2x3EI4bgLe5ym2jn3ghz5EfFni/Tgr3XRQ3y6ImFqzgROYw== 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=ifE1bSqV7JpPbRCfYrQUd7WyU5nekgwpxobPH0MbUCY=; b=mjSZvweyO6WnV4xpmG2kLzE8VnT9aE2nih5Y6PJERWUwYkXU6G9Dph/+F1C/EXd/jw5KBp8b+XNNLwhjeHThFnJcuOqN+fwDhHnI3J6x5tC3ZHZ7/X5lfvK0ATifwRPgzpoiNNuIcTnJhNg5Paz28ihR669oENGoE4Qu3mU1vPs= Received: from MW4PR04CA0228.namprd04.prod.outlook.com (2603:10b6:303:87::23) by SN7PR12MB6689.namprd12.prod.outlook.com (2603:10b6:806:273::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8466.20; Fri, 28 Feb 2025 10:05:15 +0000 Received: from SJ1PEPF000023D8.namprd21.prod.outlook.com (2603:10b6:303:87:cafe::bb) by MW4PR04CA0228.outlook.office365.com (2603:10b6:303:87::23) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.21 via Frontend Transport; Fri, 28 Feb 2025 10:05:15 +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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by SJ1PEPF000023D8.mail.protection.outlook.com (10.167.244.73) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8511.0 via Frontend Transport; Fri, 28 Feb 2025 10:05:15 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 04:03:43 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 27/31] KVM: selftests: Extend savic test with idle halt testing Date: Fri, 28 Feb 2025 15:00:20 +0530 Message-ID: <20250228093024.114983-28-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF000023D8:EE_|SN7PR12MB6689:EE_ X-MS-Office365-Filtering-Correlation-Id: c9de03c9-af9b-433c-824a-08dd57df65ac X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700013|1800799024|82310400026|376014; X-Microsoft-Antispam-Message-Info: 6nuM1yOsQ2cJ0abIxYaBvbgTOGN43Q4ZN7RiTc99AUijSFyZTnEUzsz2t9/Hd4bT/P+O/1748sXbA04Gd1soLUQqN8EpccvVmBrtDkqG8R4FjDDfU4/hexuwvTT9o9l2RbR+BovC58myGXzZZqQsrmMKYyLBzMDvvyBReb/rxWXSfyPQsGwLRqH0kQoPQpcdAHp76eJtEQa6GGi1/yLdeS0nORZnINaCC3+yRHVb8flas+ZL258BS/oJr90jUmq1CPU0AXPiUIi9sNpI9eetuVRqixArBrmQeQCl59zxmwXOlx3HtMF2fDZrevmZWpdIV3/61i2v0QHRD63C8yQXTC39oIoAhNWVCqMtPSSLt/icYEdxyV4gSSyp0N3rFdjmxgWS5ZnofC+CPWyIIfZ/DtJ8N3eH7P3EHAFal8m4EIUUCsh+mka/JI/PQyFMFV68GfTOKNCvMjpBob/NikHAP36qqFrlSMBPOowQGNopGfX2vvj1/Bpo+g+0fmXDVd68csvSVK1K7/1Ll8EzAxuuCn6lUzjhfdqtzFoykYLDQPt2MlJXMIcE6IaqNAnLuA9S7HULxxZJluPVxj4JH56tkPZ+6u5P+oIv4Gaz426tLVg3zHXu6TlZhGuw0kRcKWvtyXl6/rA6iRxaPmN4NqHW5bn7L1fu0tcny93lANeOxtdxD1m6Bb9nIA5auk4ShiOWfc5P/SVJ7DRucMwoVy0868BOcfQ5RYywkrhln10uKmSdhFKjFs/bLhqY34IcViwSzPTxietalGz9qRZ1DkuRl5W3x1DTzkSgKvzSf9292apXqaXvNG7slADWsvA2XV4oGp09B//keaga9nBXNAP2Fx0jhYbh3GoH6bGB57J1em+bGA1lo66nM1kJUl9VxCHHGQo0rfRV2+WFvPTcgh6R1NyHvbsUI62lo40qucrlye1BYE2GTsEWfUuaXJYwzrBHzPL9fxgmDKtVoI4zAZDFpFLNm/6pMh/XoZ+S3+N6VrspGeGW/+YrgP4FBTd/YPiawWyvgQHL0H4B/yMbhVIpI3djYCo85qksHhVDGM+9+UqGIoqEb06BHY1O3T7CQ3GJ1GzjorHw9z219XcXVzOP/BK1b90zwkakW9w7sb0sW/0W2pbn7pevvBiF8maPy5VEln260SBb48SffMh89vnKcEnTtc0uObCWtyi0cD1C6Uwwk6xnIdRq/36OJO1ceA44sRCjPDArIsgoUTE5PC4fFJOfgxlaXzSqf+Rpt+gofa4kgvCy/0qNbVUm30wG3dcOhaUl/dWGgaxs+EBbQNMJhF90WfvYB5rT3BTaHuzNeSsReNVG0EpqVg7jkQcIG6WFP//Mcc1thizEt65xkwDGN2yb1ik7xQ08WrPtXjenEyw5Pgec0FWpsCy4Z1UhxA8JsfH1EQ+a1oH2jgzDly8SSWvsABrzFqrN3HP2df7h0RmmPOKehNxfJAG93hJrona+xhP64QudHXDWeAl43moolsn6p3zEl+C9NIMqmFsdbd4= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(36860700013)(1800799024)(82310400026)(376014);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Feb 2025 10:05:15.0200 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: c9de03c9-af9b-433c-824a-08dd57df65ac 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF000023D8.namprd21.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR12MB6689 Add idle halt entry and exit on pending events test for Secure AVIC guests. Secure AVIC guests require idle halt intercept to be enabled. Without idle halt intercept being enabled, guest can block in halt forever as hv does not have access to APIC_IRR state to check for pending events. 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/selftests/kvm/x86/savic_test.c index 8cba7a81bce2..5c52254f7b1c 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" #define NR_SAVIC_VCPUS 1 +#define IDLE_HLT_INTR_VECTOR 0x30 +#define NUM_ITERATIONS 2000 +static bool irq_received; static struct kvm_vcpu *vcpus[NR_SAVIC_VCPUS]; static pthread_t threads[NR_SAVIC_VCPUS]; @@ -30,6 +33,7 @@ enum savic_test_state { /* APIC regs state on Secure AVIC enablement */ SAVIC_TEST_STATE(SAVIC_EN), SAVIC_TEST_STATE(SAVIC_APIC_MSR_ACCESSES), + SAVIC_TEST_STATE(SAVIC_IDLE_HALT), }; /* APIC reg values written by host. */ @@ -346,7 +350,8 @@ static void guest_verify_host_guest_reg(struct guest_apic_page *apage, uint32_t hval = savic_hv_read_reg(reg); __GUEST_ASSERT(gval == val, "Unexpected Guest %s 0x%lx, expected val:0x%lx\n", regname, gval, val); - __GUEST_ASSERT(gval == gval2, "Unexpected Guest %s backing page value : 0x%lx, msr read val:0x%lx\n", + __GUEST_ASSERT(gval == gval2, + "Unexpected %s Guest backing page value : 0x%lx, msr read val:0x%lx\n", regname, gval, gval2); switch (reg) { @@ -418,6 +423,7 @@ static void guest_savic_apic_msr_accesses(int id) val = savic_read_reg(apage, APIC_IRR + APIC_REG_OFF(vec)); GUEST_ASSERT((val & BIT_ULL(APIC_VEC_POS(vec))) == BIT_ULL(APIC_VEC_POS(vec))); savic_wrmsr(APIC_TASKPRI, 0x0); + savic_write_reg(apage, APIC_IRR + APIC_REG_OFF(vec), 0); /* Triggers GP fault */ savic_rdmsr(APIC_EOI); @@ -476,6 +482,43 @@ static void guest_savic_apic_msr_accesses(int id) } } +static void guest_idle_hlt_intr_handler(struct ex_regs *regs) +{ + struct guest_apic_page *apage = get_guest_apic_page(); + uint32_t isr, reg; + + WRITE_ONCE(irq_received, true); + reg = APIC_ISR + APIC_REG_OFF(IDLE_HLT_INTR_VECTOR); + isr = 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 = 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 = (APIC_DEST_SELF | APIC_INT_ASSERT | IDLE_HLT_INTR_VECTOR); + + for (i = 0; i < NUM_ITERATIONS; i++) { + asm volatile("cli"); + x2apic_write_reg(APIC_ICR, icr_val); + irr = 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); @@ -492,6 +535,8 @@ static void guest_code(int id) SAVIC_GUEST_SYNC(SAVIC_APIC_MSR_ACCESSES, guest_savic_apic_msr_accesses); + SAVIC_GUEST_SYNC(SAVIC_IDLE_HALT, guest_savic_idle_halt); + GUEST_DONE(); } @@ -621,6 +666,12 @@ static void *vcpu_thread(void *arg) return NULL; } +static void install_exception_handlers(struct kvm_vm *vm) +{ + vm_install_exception_handler(vm, IDLE_HLT_INTR_VECTOR, guest_idle_hlt_intr_handler); + vm_install_exception_handler(vm, 29, savic_vc_handler); +} + int main(int argc, char *argv[]) { struct kvm_sev_init args = { .vmsa_features = BIT_ULL(SVM_FEAT_SECURE_AVIC) | @@ -631,14 +682,16 @@ int main(int argc, char *argv[]) TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SNP)); TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SECURE_AVIC)); + TEST_REQUIRE(this_cpu_has(X86_FEATURE_IDLE_HLT)); vm = _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); + install_exception_handlers(vm); + 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 = pthread_create(&threads[0], NULL, vcpu_thread, vcpus[0]); From patchwork Fri Feb 28 09:30:21 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996139 Received: from NAM02-SN1-obe.outbound.protection.outlook.com (mail-sn1nam02on2042.outbound.protection.outlook.com [40.107.96.42]) (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 3366425F985; Fri, 28 Feb 2025 10:05:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.96.42 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740737153; cv=fail; b=TTAjkNGNl8bLemREYc1SYaQqrhhpSfcH/X2es8NKj/uMC5Z/WcWuCUhVXlRKKoEkEW0/i4fRxCYTGobl/hmBSpUwNNIo2CSxGBSKtxGUqIU8REz/++O7dmz9MO3ZWh+ICd7vPRPRuJdQ+liuV817sKMeF49lwg+F6SLjWWq5ZEA= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740737153; c=relaxed/simple; bh=QTPBDHzoVmoljYBZCCQyufVu+dUwDiPAePQMhYXcNd0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=WMRb0YhBPNigni+seQl5DwlU6xGX4kajxNG0jny/s9HXhMkZ72O3eGc64ktwuManw/evkRNXP1cyaabP6rOzL2Sthz9VvKSCGuEnwMU21Rn24+NlAtuqNNVPB3kbqASiHip+wwaKZ5AIsJDLDE+7hdrjOw9jUmAzidJBoxK+9ms= 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=3ykR+Iyd; arc=fail smtp.client-ip=40.107.96.42 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="3ykR+Iyd" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=TrugsQCJBzlxG+/Iom58bAW5cPTjQUf8t0w3A4iUOVteFuMBEkMWvRMAPEfsb+iuvQFbv8zF9UhD26hF1MdfulyjkuVK3T3V7icuFzOXfoB/m6Gm9KoVth4nftoKGkXGSsqHm6bsgKbKIXlefy2R7nZVtiLL4MlkYR95Hk5BHni1PDhmVFKvR3GqiUf6AlNj4PWBiVCrtDrNNw7KMINnYfv8uce9dIgixGenPW/Gq8IcQiE9+zh6kyJ43Jkq6GEc6lO+bpNXZeUQLYytrwEvX63Vfl1tgRAVksVL1HiCfYIcMYn9JMvaFHrF7qpbCs8jSvq5XLVNdCiaCrAxMV9jmA== 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=ZWFbYfJcwhS358TrK/q4sfsz5815/j8tpJP8JUzvYVE=; b=pkqfw1DppgA0XvsuDGAphGMPzWOBe7Qj01OLWV5wHzEN2n9UcHQwsIvB80KNDlSI2ILLx76h3f76LfaD+nmlQFQZg28PKsugtqPDC1q1ya84JMa2kQguyG/1gX/WekGixFLjtgmrdA6K0fT66t8DpKeCHjS+DNcujHiWyQIHuqnf0RrddjoVleKLnKXzZJkIr+seGY39az9mx7FhWHURO8ljHscdT+wnod+sI3+CRJO0bTgRwULQ2C+YUx/Imcl9CEpIKfhzsM2DnkpyyQmj9lNiKGmLKYILRZWfv576H+BjNa5vur+7WBm8imF1bDvbi5vGICN7cOeJtCScnUCivA== 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=ZWFbYfJcwhS358TrK/q4sfsz5815/j8tpJP8JUzvYVE=; b=3ykR+IydJ8XBZg/D0iqetqycHmcsURW7r8XUfbw6Ue86YVWG8Q5BtF9n3B5uQMwM+DzRQLh0KOEgHgY85iLEB6j4P2SI6emTVGtVN3RtVWyGr5gVCCzpbysE9lgZTdI+SgGYtkZ59X1jZteD4La2bPKp3lafuGvLDcN2tLVDx8k= Received: from PH7PR03CA0006.namprd03.prod.outlook.com (2603:10b6:510:339::25) by IA1PR12MB6162.namprd12.prod.outlook.com (2603:10b6:208:3ea::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8466.21; Fri, 28 Feb 2025 10:05:48 +0000 Received: from SJ1PEPF000023DA.namprd21.prod.outlook.com (2603:10b6:510:339:cafe::d4) by PH7PR03CA0006.outlook.office365.com (2603:10b6:510:339::25) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.21 via Frontend Transport; Fri, 28 Feb 2025 10:05: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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by SJ1PEPF000023DA.mail.protection.outlook.com (10.167.244.75) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8511.0 via Frontend Transport; Fri, 28 Feb 2025 10:05:48 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 04:05:27 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 28/31] KVM: selftests: Add IOAPIC tests for Secure AVIC Date: Fri, 28 Feb 2025 15:00:21 +0530 Message-ID: <20250228093024.114983-29-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF000023DA:EE_|IA1PR12MB6162:EE_ X-MS-Office365-Filtering-Correlation-Id: 8e735f30-704d-4cd0-3cf8-08dd57df7971 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700013|82310400026|376014|1800799024; X-Microsoft-Antispam-Message-Info: 82VYl5FMqFh/lUgmPMFnGeB2qqxwo4ORBlm4XM+SKbxR0OnXKVu6Dk6Ji7B9SmtugEBbzXq5CxpUs3HG8IgGVofRXzqv+5Jom5utpGZfk3CTJy7GikaJaddd9b4jlwTz1P6EWwrepnKywBxX2sMCtRs90Kl8I2hXVosU1HhgGFhX201qLnXVzCGBvQvesMp/tELzFUD16rsI98yVL9Wsl9L1CMKCafCUHTJJA7+7sQAZdTGc+XUYLtkZn+joOQkOLD3Y9oAevUj8OGVQQZfnxhRbCwtLk9O/jJM1crHnvcgdPRBfu7+YL2rznd7TDRFRmnv4INmrukHEHqZUnl0D5XPmDeLnVt5eckuuGaMS5kIx4QPewZoO+LJ4NndMMUizVkg7tfdSxBHu6oJfL6B9RcSY0KSW8jbIq7Ho5tF/pZAwktd+buiNqflsmarXOUiqAaq0zDH8VKPsfEgGtL3pQJa99Dq8NBzZyUO00y2c1wzsTAIXDolGSzb8kov5vzchHxvwMOVu0Xjj0w7WhJHZKQPCUAQn7k5i5E8AWGbsdioQPIW41gkbUKanX3SDdU2rJ5GCsUCfLlTr6EajC8YEcGoDyhNbe9BEzezzdE5toDBUvs7COEzsH+ZJR+o0nHEZpPlnSztMAvt9jT/CupNaPIM6uwunJtcNs+PhSo5p7AjCvCM603zZa0i4WIN4ud/BxRabycujt4mnxSQ9nhx7S45OuQH3aMcCmtl/mfSWOAEZt87iag20qGQx/LROfAmPBGe6YCH7K8GxiO+DJMWyIekTjRca9u4AukKwB+UzHcAfahMHbH/vTk83hJ/r6wqwstZQqT3oz7rIpzgjuPTJa1bCcmBCuLZlpxxBiY+2E4WzgrUBEEBHOo0d3D4PQ1UAUIv1PC5v8bUvUePmip/+Hil5sC4kr/nKcPySQwrD6e7dfQJuySaJfeVkTPwLPLE7kSA1QbntS8LMjxwNKW2MZ+jfVqD3fB0Cr1vloKyvlIpEQ6C28fM+hGKbpYqD7dou1oqvLkM7RvrXKvjicPg7Mr32Hx7ikpgU2fQMirUxFXTNqgei57jmWhA/xLnKPCezqZDsopzF9qrR6DIkMz094uyoKHc0EmN2wEPi1A4+lImc5fcGxSctx6SnmP2npEHtH5uPx5A+TstluIxxhMyG2gfAGBU5GsOKKZoHp2lPSM3xOuo2t3X+m4dZfbmHOMiOOFIKT3Hei8LmZxNXnkhwr7liZnQE+p8lohI9NIHuA8rGEGAk6BJ8DUdgIyGclDmNQNEyIpv7A+8UdQQE6HRCkLS/Y63HcTjHghFHjMJZZgnaV5cSVWAA9yqCfWDUcPWMOy+UXVu9QUWbgCueDOHm1eCgRlqPObR6JnIydzenJs2tHB2QKW8O2nscRzuVjMmyWp54+yGUh/qC5kvF/XQe1mjTqv+gPm4zc5aEJULuD7U5SSNVzjfolhNHdNSKS5e3+5DetJOLcyhq6x3i7Sw70X5qk6h6IiTmcalA7jds2Z4= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(36860700013)(82310400026)(376014)(1800799024);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Feb 2025 10:05:48.1547 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 8e735f30-704d-4cd0-3cf8-08dd57df7971 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF000023DA.namprd21.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA1PR12MB6162 Extend Secure AVIC tests to test edge and level ioapic based interrupt flow. In addition, test RTC_GSI IOAPIC line which has special casing in KVM. Add new interfaces to read and write to IOAPIC redirect tables. 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 | 270 +++++++++++++++++- 7 files changed, 347 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h index 7f97bade5797..33326c5975c0 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -861,6 +861,7 @@ void *vcpu_map_dirty_ring(struct kvm_vcpu *vcpu); void vcpu_args_set(struct kvm_vcpu *vcpu, unsigned int num, ...); 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); #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" #define APIC_DEFAULT_GPA 0xfee00000ULL +#define IOAPIC_DEFAULT_GPA 0xfec00000ULL /* 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); } +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 = 0, + TRIGGER_LEVEL, + TRIGGER_MAX, +}; + +static void *ioapic_addr = (void *)IOAPIC_DEFAULT_GPA; + +static inline void ioapic_write_reg(uint32_t reg, uint32_t val) +{ + *(volatile uint32_t *)ioapic_addr = reg; + *(volatile u32 *)(ioapic_addr + 0x10) = val; +} + +static inline void ioapic_write_redir(unsigned int line, struct ioapic_redirect_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 = 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] = ioapic_read_reg(0x10 + line * 2 + 0); + ((u32 *)&e)[1] = ioapic_read_reg(0x10 + line * 2 + 1); + return e; +} #endif /* SELFTEST_KVM_APIC_H */ diff --git a/tools/testing/selftests/kvm/include/x86/savic.h b/tools/testing/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/selftests/kvm/lib/kvm_util.c index 93b8e2ccc7b3..900fbad7258c 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -1861,6 +1861,23 @@ void kvm_irq_line(struct kvm_vm *vm, uint32_t irq, int level) TEST_ASSERT(ret >= 0, KVM_IOCTL_ERROR(KVM_IRQ_LINE, ret)); } +int _kvm_irq_line_status(struct kvm_vm *vm, uint32_t irq, int level) +{ + struct kvm_irq_level irq_level = { + .irq = irq, + .level = 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 = _kvm_irq_line_status(vm, irq, level); + + TEST_ASSERT(ret >= 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/testing/selftests/kvm/lib/x86/processor.c index 09474be27986..da2f8d974f60 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, uint64_t paddr, int level) "PTE already present for 4k page at vaddr: 0x%lx", vaddr); *pte = PTE_PRESENT_MASK | PTE_WRITABLE_MASK | (paddr & PHYSICAL_PAGE_MASK); - if (paddr == APIC_DEFAULT_GPA) { + if (paddr == APIC_DEFAULT_GPA || paddr == IOAPIC_DEFAULT_GPA) { *pte |= vm->arch.s_bit; return; } diff --git a/tools/testing/selftests/kvm/lib/x86/savic.c b/tools/testing/selftests/kvm/lib/x86/savic.c index c637e486b6e8..ee2d6b66d6ce 100644 --- a/tools/testing/selftests/kvm/lib/x86/savic.c +++ b/tools/testing/selftests/kvm/lib/x86/savic.c @@ -46,6 +46,7 @@ enum lapic_lvt_entry { #define SVM_EXIT_AVIC_UNACCELERATED_ACCESS 0x402 #define SVM_EXIT_AVIC_INCOMPLETE_IPI 0x401 +#define SAVIC_ALLOWED_IRR (APIC_IRR + 0x4) #define SAVIC_NMI_REQ_OFFSET 0x278 /* @@ -108,6 +109,16 @@ struct guest_apic_page *get_guest_apic_page(void) return &apic_page_pool->guest_apic_page[x2apic_read_reg(APIC_ID)]; } +void savic_allow_vector(int vec) +{ + struct guest_apic_page *apage = 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/selftests/kvm/x86/savic_test.c index 5c52254f7b1c..3399ccefc37d 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" #define NR_SAVIC_VCPUS 1 -#define IDLE_HLT_INTR_VECTOR 0x30 #define NUM_ITERATIONS 2000 +#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]; @@ -34,6 +40,8 @@ enum savic_test_state { SAVIC_TEST_STATE(SAVIC_EN), SAVIC_TEST_STATE(SAVIC_APIC_MSR_ACCESSES), SAVIC_TEST_STATE(SAVIC_IDLE_HALT), + SAVIC_TEST_STATE(SAVIC_IOAPIC), + SAVIC_TEST_STATE(SAVIC_IOAPIC2), }; /* APIC reg values written by host. */ @@ -108,6 +116,17 @@ enum context { static struct kvm_lapic_state apic_state[NR_SAVIC_VCPUS]; +/* 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; +}; + +static struct test_data_page *test_data[NR_SAVIC_VCPUS]; + /* * Write APIC reg from host or guest context. * @@ -519,6 +538,177 @@ static void guest_savic_idle_halt(int id) } } +static void _ioapic_level_irq_handler(int vec) +{ + uint32_t isr, tmr; + int offset, pos; + + offset = APIC_REG_OFF(vec); + pos = APIC_VEC_POS(vec); + isr = savic_hv_read_reg(APIC_ISR + offset); + tmr = 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 = 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 = test_data[x2apic_read_reg(APIC_ID)]; + int vec; + + vec = 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 = test_data[x2apic_read_reg(APIC_ID)]; + int vec; + + vec = 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 = 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 = 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 = 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 = test_data[x2apic_read_reg(APIC_ID)]; + int vec = IOAPIC_VECTOR_START; + + __GUEST_ASSERT(READ_ONCE(data->ioapic_eirq1_count) == 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) == 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) == 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) == 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) == 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 = { + .vector = vec, + .delivery_mode = 0, + .dest_mode = 0, + .trig_mode = trig_mode, + .mask = 0, + .dest_id = 0, + .delivery_status = 0, + .remote_irr = 0, + }; + + ioapic_write_redir(line, e); +} + +static void guest_setup_ioapic(int id) +{ + int vec = IOAPIC_VECTOR_START; + struct ioapic_redirect_entry e; + int i, line = 0; + + for (i = 0; i < IOAPIC_NUM_EDGE_VECTORS; i++) { + ioapic_set_redir(line, vec, TRIGGER_EDGE); + e = ioapic_read_redir(line); + __GUEST_ASSERT( + e.vector == vec && e.trig_mode == TRIGGER_EDGE && + e.dest_id == 0, + "Invalid IOAPIC redir entry for line : %d, trig_mode: %d vector: %d", + line, e.trig_mode, e.vector); + vec++; + line++; + } + + for (i = 0; i < IOAPIC_NUM_LEVEL_VECTORS; i++) { + ioapic_set_redir(line, vec, TRIGGER_LEVEL); + e = ioapic_read_redir(line); + __GUEST_ASSERT( + e.vector == vec && e.trig_mode == TRIGGER_LEVEL && + e.dest_id == 0, + "Invalid IOAPIC redir entry for line : %d, trig_mode: %d vector: %d", + line, e.trig_mode, e.vector); + line++; + vec++; + } + + vec = RTC_GSI_IRQ; + line = RTC_GSI; + ioapic_set_redir(line, vec, TRIGGER_EDGE); + e = ioapic_read_redir(line); + __GUEST_ASSERT( + e.vector == vec && e.trig_mode == TRIGGER_EDGE && + e.dest_id == 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 = 0; i < (IOAPIC_NUM_EDGE_VECTORS + IOAPIC_NUM_LEVEL_VECTORS); i++) { + vec = IOAPIC_VECTOR_START + i; + savic_allow_vector(vec); + } + + vec = RTC_GSI_IRQ; + savic_allow_vector(vec); +} + static void guest_code(int id) { GUEST_ASSERT(rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SNP_SECURE_AVIC); @@ -537,6 +727,10 @@ static void guest_code(int id) SAVIC_GUEST_SYNC(SAVIC_IDLE_HALT, guest_savic_idle_halt); + guest_setup_ioapic(id); + SAVIC_GUEST_SYNC(SAVIC_IOAPIC, savic_ioapic); + SAVIC_GUEST_SYNC(SAVIC_IOAPIC2, savic_ioapic2); + GUEST_DONE(); } @@ -611,6 +805,46 @@ static void host_post_savic_en_end(int id) test_apic_vals(id, false, CTXT_HOST, true, true); } +static void host_send_ioapic_irq(struct kvm_vm *vm, int id) +{ + int i; + int vec, offset, pos; + uint32_t regval; + + 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); + + vcpu_ioctl(vcpus[id], KVM_GET_LAPIC, &apic_state[id]); + + for (i = 0; i < IOAPIC_NUM_EDGE_VECTORS; i++) { + vec = IOAPIC_VECTOR_START + i; + offset = APIC_REG_OFF(vec); + regval = *(uint32_t *)&apic_state[id].regs[APIC_TMR + offset]; + pos = APIC_VEC_POS(vec); + TEST_ASSERT(!(regval & BIT_ULL(pos)), "TMR should be 0 for vector: %x", vec); + regval = *(uint32_t *)&apic_state[id].regs[APIC_IRR + offset]; + TEST_ASSERT(regval & BIT_ULL(pos), "IRR should be 1 for vector: %x", vec); + } + + for (i = 0; i < IOAPIC_NUM_LEVEL_VECTORS; i++) { + vec = IOAPIC_VECTOR_START + 2 + i; + offset = APIC_REG_OFF(vec); + regval = *(uint32_t *)&apic_state[id].regs[APIC_TMR + offset]; + pos = APIC_VEC_POS(vec); + TEST_ASSERT(regval & BIT_ULL(pos), "TMR should be 1 for vector: %x", vec); + regval = *(uint32_t *)&apic_state[id].regs[APIC_IRR + offset]; + TEST_ASSERT(regval & BIT_ULL(pos), "IRR should be 1 for vector: %x", vec); + } +} + static void host_test_savic(struct kvm_vm *vm, int id, enum savic_test_state test_state) { switch (test_state) { @@ -632,6 +866,12 @@ static void host_test_savic(struct kvm_vm *vm, int id, enum savic_test_state tes case SAVIC_EN_END: host_post_savic_en_end(id); break; + case SAVIC_IOAPIC_START: + host_send_ioapic_irq(vm, id); + break; + case SAVIC_IOAPIC2_START: + host_send_ioapic_irq(vm, id); + break; default: break; } @@ -660,7 +900,6 @@ static void *vcpu_thread(void *arg) default: TEST_FAIL("Unknown ucall 0x%lx.", uc.cmd); } - } return NULL; @@ -670,6 +909,11 @@ static void install_exception_handlers(struct kvm_vm *vm) { vm_install_exception_handler(vm, IDLE_HLT_INTR_VECTOR, guest_idle_hlt_intr_handler); vm_install_exception_handler(vm, 29, savic_vc_handler); + vm_install_exception_handler(vm, IOAPIC_VECTOR_START, ioapic_edge_irq1_intr_handler); + vm_install_exception_handler(vm, IOAPIC_VECTOR_START + 1, ioapic_edge_irq2_intr_handler); + vm_install_exception_handler(vm, IOAPIC_VECTOR_START + 2, ioapic_level_irq1_intr_handler); + vm_install_exception_handler(vm, IOAPIC_VECTOR_START + 3, ioapic_level_irq2_intr_handler); + vm_install_exception_handler(vm, RTC_GSI_IRQ, ioapic_rtc_gsi_intr_handler); } int main(int argc, char *argv[]) @@ -677,8 +921,10 @@ int main(int argc, char *argv[]) struct kvm_sev_init args = { .vmsa_features = BIT_ULL(SVM_FEAT_SECURE_AVIC) | BIT_ULL(SVM_FEAT_ALLOWED_SEV_FEATURES_VALID) }; + 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; TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SNP)); TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SECURE_AVIC)); @@ -687,11 +933,21 @@ int main(int argc, char *argv[]) vm = _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); + virt_pg_map(vm, IOAPIC_DEFAULT_GPA, IOAPIC_DEFAULT_GPA); install_exception_handlers(vm); vcpu_args_set(vcpus[0], 1, vcpus[0]->id); + for (i = 0; i < NR_SAVIC_VCPUS; i++) { + test_data_page_vaddr = vm_vaddr_alloc_page_shared(vm); + test_data[i] = (struct test_data_page *)test_data_page_vaddr; + shared_data[i] = 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); r = pthread_create(&threads[0], NULL, vcpu_thread, vcpus[0]); @@ -699,6 +955,14 @@ int main(int argc, char *argv[]) pthread_join(threads[0], NULL); + for (i = 0; i < NR_SAVIC_VCPUS; i++) { + struct test_data_page *shared_state = shared_data[i]; + + fprintf(stderr, "VCPU %d ioapic edge irq1 count: %ld edge irq2 count: %ld\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_count); + fprintf(stderr, "VCPU %d ioapic RTC GSI irq1 count: %ld\n", i, shared_state->ioapic_rtc_gsi_irq_count); + } + kvm_vm_free(vm); return 0; From patchwork Fri Feb 28 09:30:22 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996152 Received: from NAM11-DM6-obe.outbound.protection.outlook.com (mail-dm6nam11on2074.outbound.protection.outlook.com [40.107.223.74]) (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 8B79525C700; Fri, 28 Feb 2025 10:06:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.223.74 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740737209; cv=fail; b=Su2n4Ff/odllntYtlpZzIQamf/69y5UEXOW9mwp/RNIdDfMiL2UoaEEr/acDKPq5FibWmJrWkUyZEMaPHqqvYCNt99sVFgKBzbiyRUYbaBBZZ9QuPz2qUYWfFoiLIzypYCKz6IIHLkdfZ2wy4ID4yfk+GDSEtei4cW0Gs+fJ6eA= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740737209; c=relaxed/simple; bh=UaiyzZBb3EFR2uBy6qVkeTjbKbYTndocdiGq4iTXGLA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=MxVOLrSkC7I3BdEr75HL63MKZO66i7IVKjpEcd+MlYu0nFYfbMXnC92t8qPtufOgsF9oN2FkevbS63mCefMKPoAjFWFEb+0mogpuphSXhI9WBpCAfzYvO89H8RCuchtgPsaW0zi+tzI9/hXEkAkGxF9CQVkzP7hA2CrMXCfDRlw= 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=NTTbYonp; arc=fail smtp.client-ip=40.107.223.74 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="NTTbYonp" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=yJR4AXdhGQEqN7xmqHOU4w8+rNhI2URLmrrSwiJZrEPTvyvnGFCMGO6K9ySSxe7lzRBIkjI7XZuwhHBOr+I/fRWJ8qLbQvRkVSASet+p+NBqwWKGU/HlZtpwTqDWy3Agfvk/+8aVKHs+l/BquZ6kXFj14r9UEbHt5r9zg7oYQSWx5Ekns4uDry5d1iLglMgGAi9syI/E6Nj64oLIT0l6VGKKzYri9AYwLLVTN6inM6T6bdLFXwSryocUT66W6d1mqCVpYQrCLbOPpDw0YVPBFxhsHaaqG0ng4xU+iGPVfvaWV4Cov1aW5W3f8R0kYxMI03OfCAD0gxCy0Vh01BGHfA== 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=f7T6w/6dcQJX5IqNVcO3W2qvajcrgGn5xBJvehCu08A=; b=TAV/Qi/k/fVcS/MRtZ+9JveSuukrx97WKMrSLB3e/u5IHlXq6bmIyycHFytk0HinDkQLT+dynZxolhYU73R26RHIPJSCX3d5kEOtOXcdX3dSp9AAa8zg3r5lT03GUCoxJzfjbkVZqQtF2GsUPMH3IxERtnCIF7KyWSr9OtBGnE4qmqgHXICzIKfw6s8fZqRM82Z7CKgVUZjPnJ/YeDRFD8hzyubg2ask22pbeCnvsfD3D/IXnVbxKlvJbUkWhRg+MOUksusF6JSw/BFsvQLBkd/K+kEAvYOIRHeh3gIOf5C612a8OycR80Kh892KN1LTBujvRFvu7QRbpywY3JtTUA== 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=f7T6w/6dcQJX5IqNVcO3W2qvajcrgGn5xBJvehCu08A=; b=NTTbYonpqnzsSExH5omrgrRF3OEqgXjjs/VFoWS5hopeOzSicNZrDdPtCI0HSuLgJM3+vG9Tmfmk2YYVNCq8H+Qa7rKWP4dVrpPI7qYhNsRou8LxAGKUYoRDZITTbsvXWSXzAv2ktpJfHzz9FbkwFQokstu2dlm0NN4bV0EUTIA= Received: from PH7PR03CA0023.namprd03.prod.outlook.com (2603:10b6:510:339::23) by BL1PR12MB5970.namprd12.prod.outlook.com (2603:10b6:208:399::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8489.22; Fri, 28 Feb 2025 10:06:42 +0000 Received: from SJ1PEPF000023DA.namprd21.prod.outlook.com (2603:10b6:510:339:cafe::86) by PH7PR03CA0023.outlook.office365.com (2603:10b6:510:339::23) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.22 via Frontend Transport; Fri, 28 Feb 2025 10:06:42 +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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by SJ1PEPF000023DA.mail.protection.outlook.com (10.167.244.75) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8511.0 via Frontend Transport; Fri, 28 Feb 2025 10:06:42 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 04:05:47 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 29/31] KVM: selftests: Add cross-vCPU IPI testing for SAVIC guests Date: Fri, 28 Feb 2025 15:00:22 +0530 Message-ID: <20250228093024.114983-30-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF000023DA:EE_|BL1PR12MB5970:EE_ X-MS-Office365-Filtering-Correlation-Id: 77f36e68-284c-4808-2e54-08dd57df99d3 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: /e5z87zF5ta2Ny7Zk3OHR7yWZsCP6A4jWq1/XYwiMJT7GiLR4PrDRDjiAthTxEAT2VuouBMslBDIykGSDmS4p/FCTf1xlmFvN1cnYs7ge6goR63kGUfFqKgwcFYButXQVkYHreu4neHV4RIljJPG18NddB90pMqyZXDvwu/sZTr712E0ESv8xG9Qr8ydN5aDeDleNbvxW+LPA0jW4q2Uf6DVJDaqfxn7Bb990ktWlJ2PU1IyXr2H6XLBZw1nfxF25D5z3sTIlOHZdnbJfmvhIp6K/29pSh3wOgli51+COXVPHZsfHYTuvKwGXmaAxzcJQcYisqR65XAxZ0WfHDsz+Ir4RRjXz47mL3+Vi2VR2oE6MoBwjYZSdOQp6pW3QgnyqFbMUqhImBvIqX/25IPWGcfO7+mhNQVEb7FA0tigvONRpoelzvZw+xnO1hP8jNJHdVRiABGCj8jRpjci4snl5Ah2StWz+pFKtEoRwzzJXh+w8MLcrObuYpZzOErim7FydFOZ0KlFYyMQfQ1qL7jALHzLI46s3s6udoJw5iUV7Rga6DoUC7Xl/+CY7A9ruSjuaDQf/0LYBzSN2GwAq2oMQn27hHyG5q4Rl6PdBlW+xMa4XvsggsO1Dh3mh9HUq+qMBK5xEZTj0M32p6s/Dcv1+8BTJkj2mD+xERRoFO4PcEqpIpj0gbsC3pmYU+NofBfx43z8Os5YNXkyV8fnk2wTJcFlJz3ERG7cK4dU14GiZ26VxPl5Dp6vPNInF7heO3FZpar3t4I6sS/GR20UdNyvDwwE0/w+DvfP3d35AVia8z0sfSvCSjG6Z9c69X2FXNZscpOZz7Ygi51Iw1W9KIuBqH5vehYCE3QZoaApuMEKBH3Ua5vQNk5Iqf1QnMFxBvRxBksYsIfd6KqB+trtYB6aDrW09WyMfx99DsMVYiMKlBDVtEwPxiBiRsTfGDs/UUHVHVHXWO5kfiNWCKLo51L9OrYUtZpi/UbP4vNvtXLuorVjKDl+JjVMUvEvoorCofWHu5XjXpFMgVn9zIHDAAkck40oHYdMCi4mTvjkzegI8FVdvwmPc88DYS0R1sXpoiAyuYnfZBF0DzdJguq90dj0RU2UWEj0kbs6RsB6R+MP6k92JsNgOw2dtKxa62bX07WyATjYMFEI8bq0cbcKx4y7bmgFiJ89dG4+33SWg2jKPa1rnf6YgltQDX86+rtNGNHe9lq3VNf2YyZ8br7l0JjLSeXaB5Ooql2e4m4s+rJce7nnpzfRGEIU8eOv9RRys4gyTPBXspepmkn+amSUl4zSDLdvgHodbSqmxZQlENHX6xMrGXW/ZQ15RFSNDjnJSf+12t6Dvy5JrtRd9D4Z/o465W4LUvmNodJt6oQUqYUf77e0KGwoVcOdMihsdGyN2w2k/SZNTN7DlxdWV0IfuF9nt/+/TvnBczULRu8RPia410SfcfodOXaa4rUdq/bxnmPyjPPtmorNVRx2OeSpNTn390yKXGsNZx8kqqn2xadrpws= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.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: 28 Feb 2025 10:06:42.4837 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 77f36e68-284c-4808-2e54-08dd57df99d3 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF000023DA.namprd21.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BL1PR12MB5970 Extend SAVIC test to include various cross-vCPU IPI modes - fixed dest, fixed-logical, broadcast-all, broadcast excluding self. 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/selftests/kvm/x86/savic_test.c index 3399ccefc37d..d677b68aa6c6 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" -#define NR_SAVIC_VCPUS 1 +#define NR_SAVIC_VCPUS 2 #define NUM_ITERATIONS 2000 #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 static bool irq_received; static struct kvm_vcpu *vcpus[NR_SAVIC_VCPUS]; @@ -42,6 +46,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), }; /* APIC reg values written by host. */ @@ -123,6 +128,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; }; static struct test_data_page *test_data[NR_SAVIC_VCPUS]; @@ -709,6 +726,247 @@ static void guest_setup_ioapic(int id) savic_allow_vector(vec); } +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 = 1; i < NR_SAVIC_VCPUS; i++) { + struct test_data_page *data = test_data[i]; + uint64_t dst_apic_id = i; + + if (logical) { + fixed_ipi_p = &data->fixed_logical_ipi_count; + fixed_ipi_hlt_cnt_p = &data->fixed_logical_ipi_hlt_count; + fixed_ipi_wake_cnt_p = &data->fixed_logical_ipi_wake_count; + vec = FIXED_LOGICAL_IPI_VEC | APIC_DEST_LOGICAL; + dst_apic_id = 1 << i; + } else { + fixed_ipi_p = &data->fixed_ipi_count; + fixed_ipi_hlt_cnt_p = &data->fixed_ipi_hlt_count; + fixed_ipi_wake_cnt_p = &data->fixed_ipi_wake_count; + vec = FIXED_IPI_VEC; + dst_apic_id = i; + } + + last_wake_cnt = READ_ONCE(*fixed_ipi_wake_cnt_p); + while (!READ_ONCE(*fixed_ipi_hlt_cnt_p)) + ; + + last_hlt_cnt = READ_ONCE(*fixed_ipi_hlt_cnt_p); + last_fixed_ipi_cnt = READ_ONCE(*fixed_ipi_p); + + for (j = 0; j < NUM_ITERATIONS; j++) { + tsc_start = 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) != last_wake_cnt && + READ_ONCE(*fixed_ipi_hlt_cnt_p) != last_hlt_cnt && + READ_ONCE(*fixed_ipi_p) != last_fixed_ipi_cnt) + break; + } + + __GUEST_ASSERT(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, + "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 = READ_ONCE(*fixed_ipi_wake_cnt_p); + last_hlt_cnt = READ_ONCE(*fixed_ipi_hlt_cnt_p); + last_fixed_ipi_cnt = 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 == APIC_DEST_ALLINC) + vec = BROADCAST_ALL_IPI_VEC; + else + vec = BROADCAST_NOSELF_IPI_VEC; + + for (i = 1; i < NR_SAVIC_VCPUS; i++) { + data = test_data[i]; + + if (dsh == APIC_DEST_ALLINC) + broadcast_ipi_hlt_cnt_p = &data->broadcast_ipi_hlt_count; + else + broadcast_ipi_hlt_cnt_p = &data->broadcast_noself_ipi_hlt_count; + + while (!READ_ONCE(*broadcast_ipi_hlt_cnt_p)) + ; + } + + for (j = 0; j < NUM_ITERATIONS; j++) { + for (i = 1; i < NR_SAVIC_VCPUS; i++) { + data = test_data[i]; + + if (dsh == APIC_DEST_ALLINC) { + last_hlt_cnt[i] = READ_ONCE(data->broadcast_ipi_hlt_count); + last_ipi_cnt[i] = READ_ONCE(data->broadcast_ipi_count); + last_wake_cnt[i] = READ_ONCE(data->broadcast_ipi_wake_count); + } else { + last_hlt_cnt[i] = READ_ONCE(data->broadcast_noself_ipi_hlt_count); + last_ipi_cnt[i] = READ_ONCE(data->broadcast_noself_ipi_count); + last_wake_cnt[i] = READ_ONCE(data->broadcast_noself_ipi_wake_count); + } + } + + x2apic_write_reg(APIC_ICR, APIC_INT_ASSERT | dsh | vec); + + tsc_start = rdtsc(); + + for (i = 1; i < NR_SAVIC_VCPUS; i++) { + data = test_data[i]; + + if (dsh == APIC_DEST_ALLINC) { + broadcast_ipi_p = &data->broadcast_ipi_count; + broadcast_ipi_hlt_cnt_p = &data->broadcast_ipi_hlt_count; + broadcast_ipi_wake_cnt_p = &data->broadcast_ipi_wake_count; + } else { + broadcast_ipi_p = &data->broadcast_noself_ipi_count; + broadcast_ipi_hlt_cnt_p = &data->broadcast_noself_ipi_hlt_count; + broadcast_ipi_wake_cnt_p = &data->broadcast_noself_ipi_wake_count; + } + + while (rdtsc() - tsc_start < 1000000000) { + if (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]) + break; + } + + __GUEST_ASSERT(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], + "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] = READ_ONCE(*broadcast_ipi_wake_cnt_p); + last_hlt_cnt[i] = READ_ONCE(*broadcast_ipi_hlt_cnt_p); + last_ipi_cnt[i] = 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 = 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 = 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 = 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 = test_data[x2apic_read_reg(APIC_ID)]; + + WRITE_ONCE(data->broadcast_noself_ipi_count, data->broadcast_noself_ipi_count + 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 = x2apic_read_reg(APIC_ID); + data = test_data[id]; + savic_enable(); + x2apic_write_reg(APIC_TASKPRI, 0); + + uint64_t *ipi_count_types[][3] = { + { + &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 = 0; i < ARRAY_SIZE(ipi_count_types); i++) { + hlt_count_p = ipi_count_types[i][0]; + ipi_count_p = ipi_count_types[i][1]; + wake_count_p = ipi_count_types[i][2]; + + while (READ_ONCE(*ipi_count_p) != 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); @@ -731,6 +989,8 @@ static void guest_code(int id) SAVIC_GUEST_SYNC(SAVIC_IOAPIC, savic_ioapic); SAVIC_GUEST_SYNC(SAVIC_IOAPIC2, savic_ioapic2); + SAVIC_GUEST_SYNC(SAVIC_IPI, savic_ipi); + GUEST_DONE(); } @@ -914,6 +1174,11 @@ static void install_exception_handlers(struct kvm_vm *vm) vm_install_exception_handler(vm, IOAPIC_VECTOR_START + 2, ioapic_level_irq1_intr_handler); vm_install_exception_handler(vm, IOAPIC_VECTOR_START + 3, ioapic_level_irq2_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_logical_ipi_handler); + vm_install_exception_handler(vm, BROADCAST_ALL_IPI_VEC, guest_broadcast_ipi_handler); + vm_install_exception_handler(vm, BROADCAST_NOSELF_IPI_VEC, + guest_broadcast_noself_ipi_handler); } int main(int argc, char *argv[]) @@ -925,19 +1190,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 = { + .mode = VM_MODE_DEFAULT, + .type = KVM_X86_SNP_VM, + }; TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SNP)); TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SECURE_AVIC)); TEST_REQUIRE(this_cpu_has(X86_FEATURE_IDLE_HLT)); - vm = _vm_sev_create_with_one_vcpu(KVM_X86_SNP_VM, guest_code, &vcpus[0], &args); + vm = __vm_create_with_args(shape, NR_SAVIC_VCPUS, 0, &args); + + vcpus[0] = vm_vcpu_add(vm, 0, guest_code); + for (i = 1; i < NR_SAVIC_VCPUS; ++i) + vcpus[i] = vm_vcpu_add(vm, i, ipi_guest_code); virt_pg_map(vm, APIC_DEFAULT_GPA, APIC_DEFAULT_GPA); virt_pg_map(vm, IOAPIC_DEFAULT_GPA, IOAPIC_DEFAULT_GPA); install_exception_handlers(vm); - vcpu_args_set(vcpus[0], 1, vcpus[0]->id); + for (i = 0; i < NR_SAVIC_VCPUS; i++) + vcpu_args_set(vcpus[i], 1, vcpus[i]->id); for (i = 0; i < NR_SAVIC_VCPUS; i++) { test_data_page_vaddr = vm_vaddr_alloc_page_shared(vm); @@ -950,10 +1224,13 @@ int main(int argc, char *argv[]) vm_sev_launch(vm, snp_default_policy(), NULL); - r = pthread_create(&threads[0], NULL, vcpu_thread, vcpus[0]); - TEST_ASSERT(r == 0, "pthread_create failed errno=%d", errno); + for (i = 0; i < NR_SAVIC_VCPUS; i++) { + r = pthread_create(&threads[i], NULL, vcpu_thread, vcpus[i]); + TEST_ASSERT(r == 0, "pthread_create failed errno=%d", errno); + } - pthread_join(threads[0], NULL); + for (i = 0; i < NR_SAVIC_VCPUS; i++) + pthread_join(threads[i], NULL); for (i = 0; i < NR_SAVIC_VCPUS; i++) { struct test_data_page *shared_state = shared_data[i]; @@ -961,6 +1238,22 @@ int main(int argc, char *argv[]) fprintf(stderr, "VCPU %d ioapic edge irq1 count: %ld edge irq2 count: %ld\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_count); fprintf(stderr, "VCPU %d ioapic RTC GSI irq1 count: %ld\n", i, shared_state->ioapic_rtc_gsi_irq_count); + fprintf(stderr, "vCPU %d fixed IPI counts wake: %ld hlt: %ld num-IPI: %ld\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 hlt: %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); } kvm_vm_free(vm); From patchwork Fri Feb 28 09:30:23 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996153 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (mail-dm6nam12on2083.outbound.protection.outlook.com [40.107.243.83]) (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 E996725CC9A; Fri, 28 Feb 2025 10:08:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.243.83 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740737312; cv=fail; b=aUaBoNYYrngxaw4VQGDMntJ7HRirsegBpgrOKGB7WXurBQc1szkmHSlsHr8cY2IgkYOIGCX7IWVkC0jv59QHHnZoZhpRYeX8vWkbTR0Kf+XU1BKmNNmN3wkE3XmhzIvwf0kfOZy8MkN50oAJ6ujMP8sd7O/mOShfqm4XPY863CA= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740737312; c=relaxed/simple; bh=qCET8kJDixzCKqejduyQbgihL2uHRYK8KCZR8lEEkN8=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=hEIYPWNuFFpVstcGMdy+CV/jkni3me4dK/lMrxn5gdUzR/e68051T/drDFG7TAN70Ho4rPuV+albFdrWJ/EcNUkt5hskKX5h529wUCCtPoO5swmjanoWP0q1EIdrm67xKZrpmdn8wp5ooB8ZRKjJhI4xVNsQEaLLlzYiMVHk8Rk= 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=fO81FAu/; arc=fail smtp.client-ip=40.107.243.83 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="fO81FAu/" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=vvdV9UmNhHxFB5jxN9R8DzC3yjpI13lP8ARbhWMSb3nJNHgkCisqQ7nqhtWpf9khE+dCT2Ys3I6tCl/S+i9KzfDu5OjJ1BXxxm9Kx9mJI6xNZI5hjvMWxf012QUU5sgEpwMJn5AjBlk0vbIQ/MPH4sux9kJZpWIK9Y/Cn7SY0lDXVDufZNAkNHOJM0E/yCGSWjvenPzWzrf9Fg+8bGqtYb5jx8Xg/TTFJIV6/RiTbFiCH89ba3ESOh4rj7qRB8LNg8Rq6juIRFg4tUC8IZZW6P5vsrE69zUcZync43qjjEvXhI6fmxk7qrdI5BGTUhix3H95pbjKx6nJ9963ulRxhw== 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=TcXUSoh8F7z+vI67WUFYQZWlJfSDxkOGQ54KWZzn95I=; b=rhX36ABq79alx6ml4uyb+mHRYYE34FAee5ueoIwdhcitiJYLnNF+IoLDq8P6n61JmEaR6dMD0Oi3N6XSP/pEI9KBqzu9ckHUbaRHMNGbMkopMfDnAwRwgjI2ArzKYtqzaS5CBaRR/e9o13KDZhbCMx99CIjQ/x4KYbkl5/YJMseMUv5TYCu91yzmqMIEoix3S222Fep2MC5zb4bxUslfuS+STX8M07kZewpmRPOf/+LCLJITfl6BcWsw+vl9JRCS6J5Q5cEt5Qdey2stBBh3QIXVd7olKJoV8ypuQWOVNpxRdUWDeJxFffWLlcmmT/2dbnFbvn+HNs50a4YIiWuBZw== 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=TcXUSoh8F7z+vI67WUFYQZWlJfSDxkOGQ54KWZzn95I=; b=fO81FAu/+Oe47p4MoLl0+xuT4dvH0HVhIRsVlrP1Yl2loJO32vw3NGYSwFs3tqb2maMg9uP87MGuVtAcxrXk5e0buuryixnZ0GeTV1OZCxub1ZXf0dAUq4qlCAbOfnc/YVe9pAX7LJaDIsdSdaMsM4Mb5kENm0z32d8OZobWs2M= Received: from CH3P221CA0015.NAMP221.PROD.OUTLOOK.COM (2603:10b6:610:1e7::6) by SA1PR12MB8164.namprd12.prod.outlook.com (2603:10b6:806:338::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8489.23; Fri, 28 Feb 2025 10:08:25 +0000 Received: from DS3PEPF000099E0.namprd04.prod.outlook.com (2603:10b6:610:1e7:cafe::5) by CH3P221CA0015.outlook.office365.com (2603:10b6:610:1e7::6) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.21 via Frontend Transport; Fri, 28 Feb 2025 10:08:24 +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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by DS3PEPF000099E0.mail.protection.outlook.com (10.167.17.203) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 10:08:24 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 04:07:27 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 30/31] KVM: selftests: Add NMI test for SAVIC guests Date: Fri, 28 Feb 2025 15:00:23 +0530 Message-ID: <20250228093024.114983-31-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DS3PEPF000099E0:EE_|SA1PR12MB8164:EE_ X-MS-Office365-Filtering-Correlation-Id: 78a00fa3-5208-4a81-0f0e-08dd57dfd694 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: wXeqUSGWsDfbjgpVMiqYa0WDJRGzP1buwvj+TnJoV67n8wuBnSiyC5HN8DQ+LHC0Rt/NyEReQt0OPq3jI71+IH0hUGP2tbqp4SgDMrZJbmNxjvGEV6xc/CEVZ+Rap8HQe+vHj6NRfYLiCHnO82LgHY/qQgl0rcujuSJGCJesytIU7qJ+bDTlc2nQHEaxjDNsJIGG0GgAYbjrcAfRowti+tR2djoArjTxo3SJWgdW+ndyqBQugN6DatTZ3idqrdSVtQ8oNi3tp/UBZPzV1UNKsLFeQvj3DxIYQQoWTsx9BXZGm6uFSnp+sHl1Mn2X7acyDaQOGlGkxmBQ5eCSoMggZnLwt51NAT4+uJOMtY/7iliawFihQstsiglgsoLPgtnAchoFwknPpzKShekOJpro38cmFHeMcWuR3x2212jWpltm9hn6zSt8qwcZ/k1gpZzdKicprCYck84QmtkWm2kpLTMlK4+LYqbfmuFH1Y92oDhI3W8hinz/OE2lPAisBeKTHPVWZ9vQZoUewEkhF4T68lWo/aJOzhqepv9m2fvNrg0I99PruwA7MinzL3wEG2c/EBos7bxpMqBqChSKVYfcTa9GrecExfynuAfGG6HbudvGC5rb34b/y2124s6iHqdn6x1hZ4i0eTZLBD/LOujZPHH6RtkcK4NDJNlzkBiBHkD5//xdpc9EHCCH+wV4NdJZZSYzhspnNaTGNKYW/o4kABeUnTE0DvjSk6tnP3wIUEfYgNJLQV9fcHL5p8PV3pIHhDitZP/2dksRgJshVblfMoXUwKXwEJPXwxMcfb6k5gGvcYJj6TvyDDAsDihIeYkkEhgm4hl6mSJz/epRGbDuE7QRcLDWDuhbg2QUdAguF6WhlnuZeksdnKFnWbvNfKnDF4VQ2ofisrYxLGHD7I/QmZ4vKnzhiIadlOA+94fJitQ7PFOkz1EhBn1m65GWHLGEKmJqPpSw3HWvctSgkV+3NabqcB9+4NiWxwa9CoZsP52fjgTJDi6TiUQU0liIlsi/3/dDenMIYQUvwvekScb/o1Jp/PY5zabU44LMrr+J/dDlIUKmuL/q5pV5WKl96VRz8bUancEKCZWDp6RoHgoOm3qxYnOb3yrgzFEo6Q0Bye1qQLUzGaYwnnds6IZVgyxUpKDk7BMrRbuC71YQMpdAOnahpF4oO9HIO13Eq0Y7Isw8AiuxQhcT5n9aYvTVBJN7UYvBp8ix8taON0dmLvG5vOHfeUuqibuGcn75/tfvwXvLL3PeK7vM4XF1OYG5oGsIZl5snXgcmsCJcZ6mBcItLJdS5BVkdDKS+zgEWNHRmPb4WVMK0ixYnlKTODZOmMQLm5/hmb+MqxMICK68ktSy6zHP0FlLIhu+aKuNCZqRaa6brlQPE+HYqqHgojkgSgq1p7mqG2xc/BBcN/HtR4JDE1z4CzGgMRlNEkf2ESypyD/DmWk5kJDluyAIH4ES2aNM2dN6rvd2M2HgyPwdV/KM+Qv8dNSqryvEu+VIzB0hMsc= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.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: 28 Feb 2025 10:08:24.4891 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 78a00fa3-5208-4a81-0f0e-08dd57dfd694 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: DS3PEPF000099E0.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA1PR12MB8164 Extend SAVIC test with various NMI tests: - Test NMI injection failure when AllowedNMI is not set by guest. - Test NMI injection when 2 NMIs are pending. - Test ICR based cross-VCPU NMI for fixed-phys, fixed-logical, broadcast-all and broadcast-exclself modes. 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/testing/selftests/kvm/include/x86/processor.h index f09b18944c47..ebd30c4515e7 100644 --- a/tools/testing/selftests/kvm/include/x86/processor.h +++ b/tools/testing/selftests/kvm/include/x86/processor.h @@ -917,6 +917,11 @@ static inline void vcpu_xcrs_set(struct kvm_vcpu *vcpu, struct kvm_xcrs *xcrs) vcpu_ioctl(vcpu, KVM_SET_XCRS, xcrs); } +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 *cpuid, 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 81ee79f63b7f..4e8944ca8440 100644 --- a/tools/testing/selftests/kvm/include/x86/sev.h +++ b/tools/testing/selftests/kvm/include/x86/sev.h @@ -160,4 +160,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/selftests/kvm/lib/x86/savic.c index ee2d6b66d6ce..f7301ec6d45f 100644 --- a/tools/testing/selftests/kvm/lib/x86/savic.c +++ b/tools/testing/selftests/kvm/lib/x86/savic.c @@ -91,13 +91,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 = apic_page->gpa | BIT_ULL(MSR_AMD64_SECURE_AVIC_EN_BIT); + uint64_t val; if (!enable) { wrmsr(MSR_AMD64_SECURE_AVIC_CONTROL, 0); return; } + val = apic_page->gpa | BIT_ULL(MSR_AMD64_SECURE_AVIC_EN_BIT); + if (enable_nmi) val |= BIT_ULL(MSR_AMD64_SECURE_AVIC_ALLOWED_NMI_BIT); @@ -442,15 +444,18 @@ static void savic_handle_icr_write(uint64_t icr_data) bool logical = icr_data & APIC_DEST_LOGICAL; bool nmi = (icr_data & APIC_DM_FIXED_MASK) == APIC_DM_NMI; uint64_t self_icr_data = APIC_DEST_SELF | APIC_INT_ASSERT | vector; - - if (nmi) - self_icr_data |= APIC_DM_NMI; + struct guest_apic_page *apic_page; 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 = &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/selftests/kvm/lib/x86/sev.c index 24a2a29a575b..446f7d7dafda 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 struct ghcb_entry { struct ghcb ghcb; @@ -798,3 +799,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 = ghcb_alloc(); + ghcb = &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 = 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/selftests/kvm/x86/savic_test.c index d677b68aa6c6..277ee18a0cbd 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" -#define NR_SAVIC_VCPUS 2 -#define NUM_ITERATIONS 2000 +#define NR_SAVIC_VCPUS 4 +#define NUM_ITERATIONS 1000 #define IDLE_HLT_INTR_VECTOR 0x30 #define IOAPIC_VECTOR_START 0x81 @@ -47,6 +47,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), }; /* APIC reg values written by host. */ @@ -128,18 +135,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; }; static struct test_data_page *test_data[NR_SAVIC_VCPUS]; @@ -581,9 +602,14 @@ static void _ioapic_level_irq_handler(int vec) vec); } +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 = test_data[x2apic_read_reg(APIC_ID)]; + struct test_data_page *data = get_test_data(); int vec; vec = IOAPIC_VECTOR_START + IOAPIC_NUM_EDGE_VECTORS; @@ -593,7 +619,7 @@ static void ioapic_level_irq1_intr_handler(struct ex_regs *regs) static void ioapic_level_irq2_intr_handler(struct ex_regs *regs) { - struct test_data_page *data = test_data[x2apic_read_reg(APIC_ID)]; + struct test_data_page *data = get_test_data(); int vec; vec = IOAPIC_VECTOR_START + IOAPIC_NUM_EDGE_VECTORS + 1; @@ -603,7 +629,7 @@ static void ioapic_level_irq2_intr_handler(struct ex_regs *regs) static void ioapic_edge_irq1_intr_handler(struct ex_regs *regs) { - struct test_data_page *data = test_data[x2apic_read_reg(APIC_ID)]; + struct test_data_page *data = get_test_data(); WRITE_ONCE(data->ioapic_eirq1_count, data->ioapic_eirq1_count + 1); x2apic_write_reg(APIC_EOI, 0x00); @@ -611,7 +637,7 @@ static void ioapic_edge_irq1_intr_handler(struct ex_regs *regs) static void ioapic_edge_irq2_intr_handler(struct ex_regs *regs) { - struct test_data_page *data = test_data[x2apic_read_reg(APIC_ID)]; + struct test_data_page *data = get_test_data(); WRITE_ONCE(data->ioapic_eirq2_count, data->ioapic_eirq2_count + 1); x2apic_write_reg(APIC_EOI, 0x00); @@ -619,7 +645,7 @@ static void ioapic_edge_irq2_intr_handler(struct ex_regs *regs) static void ioapic_rtc_gsi_intr_handler(struct ex_regs *regs) { - struct test_data_page *data = test_data[x2apic_read_reg(APIC_ID)]; + struct test_data_page *data = get_test_data(); WRITE_ONCE(data->ioapic_rtc_gsi_irq_count, data->ioapic_rtc_gsi_irq_count + 1); x2apic_write_reg(APIC_EOI, 0x00); @@ -627,7 +653,7 @@ static void ioapic_rtc_gsi_intr_handler(struct ex_regs *regs) static void __savic_ioapic(int count) { - struct test_data_page *data = test_data[x2apic_read_reg(APIC_ID)]; + struct test_data_page *data = get_test_data(); int vec = IOAPIC_VECTOR_START; __GUEST_ASSERT(READ_ONCE(data->ioapic_eirq1_count) == count, @@ -726,10 +752,40 @@ static void guest_setup_ioapic(int id) savic_allow_vector(vec); } -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 = + nmi ? &data->fixed_logical_nmi_count : + &data->fixed_logical_ipi_count; + *fixed_ipi_hlt_cnt_p = + nmi ? &data->fixed_logical_nmi_hlt_count : + &data->fixed_logical_ipi_hlt_count; + *fixed_ipi_wake_cnt_p = + nmi ? &data->fixed_logical_nmi_wake_count : + &data->fixed_logical_ipi_wake_count; + } else { + *fixed_ipi_p = + nmi ? &data->fixed_phys_nmi_count : + &data->fixed_phys_ipi_count; + *fixed_ipi_hlt_cnt_p = + nmi ? &data->fixed_phys_nmi_hlt_count : + &data->fixed_phys_ipi_hlt_count; + *fixed_ipi_wake_cnt_p = + 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; @@ -741,26 +797,26 @@ static void savic_fixed_ipi(bool logical) struct test_data_page *data = test_data[i]; uint64_t dst_apic_id = i; + set_fixed_counters(data, &fixed_ipi_p, + &fixed_ipi_hlt_cnt_p, &fixed_ipi_wake_cnt_p, + logical, nmi); if (logical) { - fixed_ipi_p = &data->fixed_logical_ipi_count; - fixed_ipi_hlt_cnt_p = &data->fixed_logical_ipi_hlt_count; - fixed_ipi_wake_cnt_p = &data->fixed_logical_ipi_wake_count; vec = FIXED_LOGICAL_IPI_VEC | APIC_DEST_LOGICAL; dst_apic_id = 1 << i; } else { - fixed_ipi_p = &data->fixed_ipi_count; - fixed_ipi_hlt_cnt_p = &data->fixed_ipi_hlt_count; - fixed_ipi_wake_cnt_p = &data->fixed_ipi_wake_count; vec = FIXED_IPI_VEC; dst_apic_id = i; } + if (nmi) + vec |= APIC_DM_NMI; + last_wake_cnt = READ_ONCE(*fixed_ipi_wake_cnt_p); while (!READ_ONCE(*fixed_ipi_hlt_cnt_p)) ; last_hlt_cnt = READ_ONCE(*fixed_ipi_hlt_cnt_p); - last_fixed_ipi_cnt = READ_ONCE(*fixed_ipi_p); + last_fixed_phys_ipi_cnt = READ_ONCE(*fixed_ipi_p); for (j = 0; j < NUM_ITERATIONS; j++) { tsc_start = rdtsc(); @@ -769,31 +825,73 @@ static void savic_fixed_ipi(bool logical) while (rdtsc() - tsc_start < 1000000000) { if (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) break; } __GUEST_ASSERT(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, - "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) != last_fixed_phys_ipi_cnt, + "%s fixed-%s wake: %ld last_wake: %ld hlt: %ld last_hlt: %ld ipi: %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); last_wake_cnt = READ_ONCE(*fixed_ipi_wake_cnt_p); last_hlt_cnt = READ_ONCE(*fixed_ipi_hlt_cnt_p); - last_fixed_ipi_cnt = READ_ONCE(*fixed_ipi_p); + last_fixed_phys_ipi_cnt = READ_ONCE(*fixed_ipi_p); } } } -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 == 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 == 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 == 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; @@ -808,10 +906,8 @@ static void savic_send_broadcast(int dsh) for (i = 1; i < NR_SAVIC_VCPUS; i++) { data = test_data[i]; - if (dsh == APIC_DEST_ALLINC) - broadcast_ipi_hlt_cnt_p = &data->broadcast_ipi_hlt_count; - else - broadcast_ipi_hlt_cnt_p = &data->broadcast_noself_ipi_hlt_count; + broadcast_ipi_hlt_cnt_p = get_broadcast_hlt_counter( + data, dsh, nmi); while (!READ_ONCE(*broadcast_ipi_hlt_cnt_p)) ; @@ -821,17 +917,20 @@ static void savic_send_broadcast(int dsh) for (i = 1; i < NR_SAVIC_VCPUS; i++) { data = test_data[i]; - if (dsh == APIC_DEST_ALLINC) { - last_hlt_cnt[i] = READ_ONCE(data->broadcast_ipi_hlt_count); - last_ipi_cnt[i] = READ_ONCE(data->broadcast_ipi_count); - last_wake_cnt[i] = READ_ONCE(data->broadcast_ipi_wake_count); - } else { - last_hlt_cnt[i] = READ_ONCE(data->broadcast_noself_ipi_hlt_count); - last_ipi_cnt[i] = READ_ONCE(data->broadcast_noself_ipi_count); - last_wake_cnt[i] = READ_ONCE(data->broadcast_noself_ipi_wake_count); - } + broadcast_ipi_cnt_p = get_broadcast_ipi_counter( + data, dsh, nmi); + broadcast_ipi_hlt_cnt_p = get_broadcast_hlt_counter( + data, dsh, nmi); + broadcast_ipi_wake_cnt_p = get_broadcast_wake_counter( + data, dsh, nmi); + last_ipi_cnt[i] = *broadcast_ipi_cnt_p; + last_hlt_cnt[i] = *broadcast_ipi_hlt_cnt_p; + last_wake_cnt[i] = *broadcast_ipi_wake_cnt_p; } + if (nmi) + vec |= APIC_DM_NMI; + x2apic_write_reg(APIC_ICR, APIC_INT_ASSERT | dsh | vec); tsc_start = rdtsc(); @@ -839,60 +938,59 @@ static void savic_send_broadcast(int dsh) for (i = 1; i < NR_SAVIC_VCPUS; i++) { data = test_data[i]; - if (dsh == APIC_DEST_ALLINC) { - broadcast_ipi_p = &data->broadcast_ipi_count; - broadcast_ipi_hlt_cnt_p = &data->broadcast_ipi_hlt_count; - broadcast_ipi_wake_cnt_p = &data->broadcast_ipi_wake_count; - } else { - broadcast_ipi_p = &data->broadcast_noself_ipi_count; - broadcast_ipi_hlt_cnt_p = &data->broadcast_noself_ipi_hlt_count; - broadcast_ipi_wake_cnt_p = &data->broadcast_noself_ipi_wake_count; - } + broadcast_ipi_cnt_p = get_broadcast_ipi_counter( + data, dsh, nmi); + broadcast_ipi_hlt_cnt_p = get_broadcast_hlt_counter( + data, dsh, nmi); + broadcast_ipi_wake_cnt_p = get_broadcast_wake_counter( + data, dsh, nmi); while (rdtsc() - tsc_start < 1000000000) { if (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]) break; } __GUEST_ASSERT(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], - "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) != last_ipi_cnt[i], + "%s broadcast-%s wake: %ld last_wake: %ld hlt: %ld last_hlt: %ld ipi: %ld last_ipi: %ld", + nmi ? "nmi" : "ipi", + dsh == 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]); last_wake_cnt[i] = READ_ONCE(*broadcast_ipi_wake_cnt_p); last_hlt_cnt[i] = READ_ONCE(*broadcast_ipi_hlt_cnt_p); - last_ipi_cnt[i] = READ_ONCE(*broadcast_ipi_p); + last_ipi_cnt[i] = READ_ONCE(*broadcast_ipi_cnt_p); } } } void savic_ipi(int id) { - savic_fixed_ipi(false); - savic_fixed_ipi(true); + savic_fixed_ipi(false, false); + savic_fixed_ipi(true, false); 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); } -void guest_fixed_ipi_handler(struct ex_regs *regs) +void guest_fixed_phys_ipi_handler(struct ex_regs *regs) { - struct test_data_page *data = test_data[x2apic_read_reg(APIC_ID)]; + struct test_data_page *data = get_test_data(); - 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); } void guest_fixed_logical_ipi_handler(struct ex_regs *regs) { - struct test_data_page *data = test_data[x2apic_read_reg(APIC_ID)]; + struct test_data_page *data = get_test_data(); WRITE_ONCE(data->fixed_logical_ipi_count, data->fixed_logical_ipi_count + 1); x2apic_write_reg(APIC_EOI, 0x00); @@ -900,7 +998,7 @@ void guest_fixed_logical_ipi_handler(struct ex_regs *regs) void guest_broadcast_ipi_handler(struct ex_regs *regs) { - struct test_data_page *data = test_data[x2apic_read_reg(APIC_ID)]; + struct test_data_page *data = get_test_data(); WRITE_ONCE(data->broadcast_ipi_count, data->broadcast_ipi_count + 1); x2apic_write_reg(APIC_EOI, 0x00); @@ -908,13 +1006,65 @@ void guest_broadcast_ipi_handler(struct ex_regs *regs) void guest_broadcast_noself_ipi_handler(struct ex_regs *regs) { - struct test_data_page *data = test_data[x2apic_read_reg(APIC_ID)]; + struct test_data_page *data = get_test_data(); WRITE_ONCE(data->broadcast_noself_ipi_count, data->broadcast_noself_ipi_count + 1); x2apic_write_reg(APIC_EOI, 0x00); } -static void ipi_guest_code(int id, unsigned long secondary_entry) +static void savic_nmi(int id) +{ + struct test_data_page *data = get_test_data(); + + __GUEST_ASSERT(!data->nmi_count, "Invalid NMI count: %ld\n", data->nmi_count); + set_savic_control_msr(get_guest_apic_page(), true, true); +} + +static void savic_nmi2(int id) +{ + struct test_data_page *data = get_test_data(); + + __GUEST_ASSERT(data->nmi_count == 2, "Invalid NMI count: %ld\n", data->nmi_count); +} + +static void savic_nmi3(int id) +{ + struct test_data_page *data = get_test_data(); + + __GUEST_ASSERT(data->nmi_count == 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 = 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 == &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; @@ -928,9 +1078,9 @@ static void ipi_guest_code(int id, unsigned long secondary_entry) uint64_t *ipi_count_types[][3] = { { - &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, @@ -947,6 +1097,26 @@ static void ipi_guest_code(int id, unsigned long secondary_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 + }, }; for (i = 0; i < ARRAY_SIZE(ipi_count_types); i++) { @@ -955,9 +1125,11 @@ static void ipi_guest_code(int id, unsigned long secondary_entry) wake_count_p = ipi_count_types[i][2]; while (READ_ONCE(*ipi_count_p) != 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); } @@ -969,6 +1141,9 @@ static void ipi_guest_code(int id, unsigned long secondary_entry) static void guest_code(int id) { + struct test_data_page *data; + int i; + GUEST_ASSERT(rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SNP_SECURE_AVIC); SAVIC_GUEST_SYNC(RESET, guest_savic_start); @@ -991,6 +1166,39 @@ static void guest_code(int id) SAVIC_GUEST_SYNC(SAVIC_IPI, savic_ipi); + /* Disable host NMI injection in control MSR. */ + set_savic_control_msr(get_guest_apic_page(), true, false); + + data = test_data[id]; + data->nmi_count_p = &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 = 0; i < NR_SAVIC_VCPUS; i++) { + data = test_data[i]; + data->nmi_count_p = &data->fixed_phys_nmi_count; + } + SAVIC_GUEST_SYNC(SAVIC_ICR_FIXED_PHYS_NMI, savic_icr_fixed_phys); + + for (i = 0; i < NR_SAVIC_VCPUS; i++) { + data = test_data[i]; + data->nmi_count_p = &data->fixed_logical_nmi_count; + } + SAVIC_GUEST_SYNC(SAVIC_ICR_FIXED_LOGICAL_NMI, savic_icr_fixed_logical); + + for (i = 0; i < NR_SAVIC_VCPUS; i++) { + data = test_data[i]; + data->nmi_count_p = &data->broadcast_nmi_count; + } + SAVIC_GUEST_SYNC(SAVIC_ICR_BROADCAST_NMI, savic_icr_bcast); + + for (i = 0; i < NR_SAVIC_VCPUS; i++) { + data = test_data[i]; + data->nmi_count_p = &data->broadcast_noself_nmi_count; + } + SAVIC_GUEST_SYNC(SAVIC_ICR_BROADCAST_NOSELF_NMI, savic_icr_bcast_noself); + GUEST_DONE(); } @@ -1105,6 +1313,12 @@ static void host_send_ioapic_irq(struct kvm_vm *vm, int id) } } +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_state test_state) { switch (test_state) { @@ -1132,6 +1346,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; } @@ -1174,11 +1393,12 @@ static void install_exception_handlers(struct kvm_vm *vm) vm_install_exception_handler(vm, IOAPIC_VECTOR_START + 2, ioapic_level_irq1_intr_handler); vm_install_exception_handler(vm, IOAPIC_VECTOR_START + 3, ioapic_level_irq2_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_handler); vm_install_exception_handler(vm, FIXED_LOGICAL_IPI_VEC, guest_fixed_logical_ipi_handler); vm_install_exception_handler(vm, BROADCAST_ALL_IPI_VEC, guest_broadcast_ipi_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); } int main(int argc, char *argv[]) @@ -1239,9 +1459,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_count); fprintf(stderr, "VCPU %d ioapic RTC GSI irq1 count: %ld\n", i, shared_state->ioapic_rtc_gsi_irq_count); fprintf(stderr, "vCPU %d fixed IPI counts wake: %ld hlt: %ld num-IPI: %ld\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, @@ -1250,10 +1470,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 hlt: %ld num-IPI: %ld\n", + fprintf(stderr, "vCPU %d broadcast excluding self IPI counts wake: %ld hlt: %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); } kvm_vm_free(vm); From patchwork Fri Feb 28 09:30:24 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neeraj Upadhyay X-Patchwork-Id: 13996154 Received: from NAM04-DM6-obe.outbound.protection.outlook.com (mail-dm6nam04on2046.outbound.protection.outlook.com [40.107.102.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 B9AE425CC8A; Fri, 28 Feb 2025 10:09:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.102.46 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740737355; cv=fail; b=gOHsU7cepp4BAIA7dcMk4V1w9ZSDg9YGZ1dFz0DPDZ7pQmlqGKP4Pmm8GEyXrIuH0YwUOuLJg9DUhlPPWnUML309q2PXHDpwY9OmLHlFOdlJwSFAe1ljZQz2fS8V+obDoAuX2Gm/SMIpR/kEmCSecTcq6xvHdZhh+OIgvu/QQak= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740737355; c=relaxed/simple; bh=DWGi1BO6ForlXj4A/5BWgACRpoLVHgd/j3syLuJScPk=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=SvukDuT9VLFRdGpP0XBooWAOCECfhQofwScabINDQ/JfleHgElhYqDPx0eP5wd9nm/PMU3fs4FpI6lKG7C8OH12kLNw2T4EHRLDOgmSnKTlmaop5OXuXfm8x0EFofr8acLKRouGKEbehq+/vFtd0gfGtmnBnARVnWSLWmzSe8Zs= 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=yj1dZH6V; arc=fail smtp.client-ip=40.107.102.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="yj1dZH6V" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=hgeNs7M5h22Sf6aoOJHm3vSyT8S8M3FRyoe7Dc2RkIzYGyRPc3YlBRZqC5SpsUi0GkMD7NL7UETrHLsB/vKYL09YGeUMfUrcPI7lYk24QviSOC7i0vfMAsbgyN0TDQSxQD+pMXbMFPpAEkznTYCcRLO+rvZTohzUXI31IP2bNcZe87L9sr2+07qe5qddwPHlxjgGGzu06m5JLIn5XdnOIizhrb4RKYy4CEg7QWS48gRntcgVqSOLF+GGYyLf+Tnh7flOq5S0hDZKUix928n/d7WektumrD2d8QZthY+LpOK0S/QePBbrJF99Oc5inGuvjuY6gRFSFzKCfAFq3R/t0A== 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=OQlXv1nAtP4EGf9PChKWyAyGqPo/OaHIY5vhj+fK1Zk=; b=wI6cxbzf2+Wmz7/zIO5KZmfBtYnLFyNpOejVQ8lhhzFb/NsU+Jmh8/usIeUr5OmEtKZxyk2lQK/uCVCOkwNXFSxbA+M+jAbDQM0KWCr+4Um7PfHJJk6u4i+1mgBFMj+ziaL9s6P6RcIraJ+wn5/8taK1eGJF8Vj7hzGjZg5C4aJqam1+aP70fufO9gMNkgBYDcTAXSsWfB5tuAGwp2dKarEB/GG0s4KiCZNIP5xGHHKIazk3PfXXJdTAYoY20z2iHh2o49IiVxbi0zJkQIiNQ6Le+37s9sRUrDqBZop17TgTPhqBpwS98deeh+Ca1xLf4XZsRwgHgercjDY8UVUuUA== 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=OQlXv1nAtP4EGf9PChKWyAyGqPo/OaHIY5vhj+fK1Zk=; b=yj1dZH6VgpmkQoMcbq/GLXvmoW+GwNITV0j+0yG20AMwaZ49Kl5i9hIo7Izdb3IogJ8uUkbaHbr5cDkK8xIgFOPNOPOfJMEazAbscOyjDyuyjO5xhBGkMdZ9Xzbg7pIm9lb04JCJa8DedfUZSPm0EhA1XVZY0+zgZYZLJ8JRFL8= Received: from DS7PR03CA0156.namprd03.prod.outlook.com (2603:10b6:5:3b2::11) by DS0PR12MB8341.namprd12.prod.outlook.com (2603:10b6:8:f8::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8489.23; Fri, 28 Feb 2025 10:09:11 +0000 Received: from DS3PEPF000099DC.namprd04.prod.outlook.com (2603:10b6:5:3b2:cafe::d) by DS7PR03CA0156.outlook.office365.com (2603:10b6:5:3b2::11) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8489.23 via Frontend Transport; Fri, 28 Feb 2025 10:09:11 +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=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by DS3PEPF000099DC.mail.protection.outlook.com (10.167.17.198) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8489.16 via Frontend Transport; Fri, 28 Feb 2025 10:09:11 +0000 Received: from BLR-L-NUPADHYA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 28 Feb 2025 04:09:00 -0600 From: Neeraj Upadhyay To: , , CC: , , , , , , , , , , , , Subject: [RFC PATCH 31/31] KVM: selftests: Add MSI injection test for SAVIC Date: Fri, 28 Feb 2025 15:00:24 +0530 Message-ID: <20250228093024.114983-32-Neeraj.Upadhyay@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> References: <20250228093024.114983-1-Neeraj.Upadhyay@amd.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DS3PEPF000099DC:EE_|DS0PR12MB8341:EE_ X-MS-Office365-Filtering-Correlation-Id: eccdf399-7d80-4313-4aa1-08dd57dff26a 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: +tfFX493r2HFPGmMVvber2G6QqZXrOIz2zrB7eQKfhPniawROpgfWsNf+PLQNEtW7kKDWAZMuD0A8JaE9YyTQfwI5VPtyi/QUpdhj9G57FfcqQtgITZtT7uUgBkD0NSY80O0d7OJAcXkNDwZYPFYy13r+AD3RWGzXroM3w9oULTR5y/H/U2TLS1r4PJkvD9iqrQA10EWwj6mRvTqjzMnhguP8eDoK+H318XzWVSOUd+kISa+3XKwDpYvZn0lntYrJW9zj11RlG2wfNY4J0kUlijp8t0HCd2lfR/YfJJ+DOzfhChXAzmkFhggamqXHMMxjiIKViGbLWzEja0BWnLxJ2/LdTFetbjsD+zeFrtTxt7kKq6f0iT8in+zz+Sce2G+JREqOgnvTxITPI/iKj53t7yq2k+dOCm7FzUVnT5yxnDZfSu8cbAOnl3INdCCHTcWEmCHcAUsUQBZuNU7OYlFW6lUbE+ftuKsVhJ4Df6Sd5IpVH0fttVOuKkBD4UzxCC27RBDJ3aPC4BBP1ot46hQHZJNJHHN79h2amf14aj7qA5NaTPIOODQn2B4Jcdscx1j4licwHpkqfc6u2sqkeoVgEAeqoTeM2d+CjAUSfg+nvfyNZUWAZFcxmpfUuLwOsyXBYmmEbgPyF9+r0s+Dk3pSNTCIfos6H8+yp9JFzBK6ab9AemkR0qz2k57yKqcI0e75cHHMSBWir5l9uIMQlXaCC8qHQvD0ug1QjEotRWCaMG26C+zpoeOfzBIGlYThJlZhEwpx4COt2gyP0iKCGcf5Nw5mkavjShEfZaCD3hElZuE+ZPaH6pCuh4vMJhATgPXh4bTySusw4zIFK0bH3C9E1tBrZnyMQOeLzRYm29a2Dto5d+vAX5WthBXzukmbKnvkeAkzeLoatH3GbjgdCeql/2WDztAY0HNx1oZJn+c4EUJTii/H3wyVz8N8AZFLV86ogmnMAcw6FONAfYiSd+mhcWLzlsRhgyn49dUOI28LwVvf4VfSIuyv2NBstNDuZLwfG6Yz8HAY6Ky75HC2lI9lZkTEnxEEglVT0dyimqhfHcmis04TQN1doocTjpvic/pOCMOyratdd61n3FU1uBwNk0yDx9hNPCIYLWpZXGO/n0kvv22xgR2RZXjVwlsmbf7KCUCWrPYyozNd6HMnfBT2OHCgC6TABiBp08nR5ImpJshNzh1xdKqmXzyjxULcEinWy6mhhfg0W+Uv+8fjvqzaVsF21dFKU328YdF4iLNc6Tp19DjJbNvYjzqnrfH5x3uco899oGOXcsrAvNfZIqaDSrXTgHqMkdsDLRZL6Fm8bDctbTh1RbX0tkEwBUzxqMqlFMC5rasZuLvO9C15fplJpFck+i4TYMKoIrMeZN8WpYp3rI2dBa7WnpuJfC79COX3syksmhfQ7x7S7qTNN7parVs6ZDn3hszREvRkwvWXEWBUSc56kXTZHL7LUlxw9/77MKBfUZ5/CIi2140Q/brESRmOBFdyFpzlpXRpw5QhUA= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.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: 28 Feb 2025 10:09:11.2072 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: eccdf399-7d80-4313-4aa1-08dd57dff26a 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=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: DS3PEPF000099DC.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS0PR12MB8341 Extend SAVIC test include MSI injection from host. Test scenarios where MSI vector is not allowed by guest in ALLOWED_IRR and when it is allowed. 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/selftests/kvm/x86/savic_test.c index 277ee18a0cbd..edb355e9df42 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 @@ -46,6 +47,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), @@ -135,6 +137,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; @@ -1064,6 +1067,34 @@ static void guest_nmi_handler(struct ex_regs *regs) sev_es_nmi_complete(); } +static void savic_msi_not_allowed(int id) +{ + struct test_data_page *data = get_test_data(); + + savic_allow_vector(MSI_VECTOR); + + __GUEST_ASSERT(READ_ONCE(data->msi_irq_count) == 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 = get_test_data(); + + __GUEST_ASSERT(READ_ONCE(data->msi_irq_count) == 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 = 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; @@ -1164,6 +1195,9 @@ static void guest_code(int id) SAVIC_GUEST_SYNC(SAVIC_IOAPIC, savic_ioapic); SAVIC_GUEST_SYNC(SAVIC_IOAPIC2, savic_ioapic2); + SAVIC_GUEST_SYNC(SAVIC_MSI, savic_msi_not_allowed); + SAVIC_GUEST_SYNC(SAVIC_MSI, savic_msi_allowed); + SAVIC_GUEST_SYNC(SAVIC_IPI, savic_ipi); /* Disable host NMI injection in control MSR. */ @@ -1313,6 +1347,17 @@ static void host_send_ioapic_irq(struct kvm_vm *vm, int id) } } +static void host_send_msi(struct kvm_vm *vm) +{ + struct kvm_msi msi = { + .address_lo = 0, + .address_hi = 0, + .data = MSI_VECTOR, + }; + + __vm_ioctl(vm, KVM_SIGNAL_MSI, &msi); +} + static void host_send_nmi(int id) { vcpu_nmi(vcpus[id]); @@ -1346,6 +1391,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: @@ -1399,6 +1447,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); } int main(int argc, char *argv[])