Message ID | 20221117044433.244656-1-nikunj@amd.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp216258wrr; Wed, 16 Nov 2022 21:01:18 -0800 (PST) X-Google-Smtp-Source: AA0mqf7QkR8GfXj4MIoTpF7rqpUSOojFYyd5bJrwmSxE3Zdx5pUx+A+qR4kFbf5ucQB81w67fAx+ X-Received: by 2002:a17:90a:3d41:b0:213:d34:a80b with SMTP id o1-20020a17090a3d4100b002130d34a80bmr1149497pjf.74.1668661278151; Wed, 16 Nov 2022 21:01:18 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1668661278; cv=pass; d=google.com; s=arc-20160816; b=pXgF/rfW06IHuqnbMz6DG4s2NOEyj47qwEOEEEsqJbvbNgtI4Eesw+fybMl9MaN9GB vz9gAc80NZDFN3EpqqlqHWPWW9jHCaT3FZgbJ396PzMZQlc227JsUCa07Y5qRBG6H1Dy cE4518WkUQ4nfYHC8OywZp4r0Q6rfPMBPUpwylFoXjAP9ufa+ONS8J7eLwTuAgKS4jTL atVr869tcvaJ0aecN8gWs/hKdoqWvH3QAZdPO9trmJB/1gi1Ku4uAs8RLlNaOikorWfd BRa8QhZ5aBWbHur0Tz49G6n8mCNnT52w4NcLOtNzKZX9vXPdePn2M4BJfoOm0NKrc7fk pfQw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=SlrRFHQCFrZ21kW3wSZHbnli+sSJ10JduFtslfmePq0=; b=YzrDouQZZzcOqsA+zxvM5WgcfbF8spazE6dLjEaStFDZc8E2u1JqM1r5wclV2wO6OE 1v7dcDJGbd06CwuiLKdathHv+WBwfP21z736GHWo+VvpzrCxO1g/lQOgkn2++dCPxMZq XbqOj/jiMZGRJTt3c+grHL3JC9rl7abZRo7DmEd9mR6VRSa2T650rVufmPtuZ6YuCgA6 SDAL6jsASZiKqmHpIpU981GAPRHAetTJkfqSrZ99elhVZUhOZFqmvb0seZnroGe8PYp+ R1+S27NrJ2kRsTbTej9+mc2W6zaxgXzsmdOAfO2arcUclTVUgD3TKsES5KN3JftmvkMF x9Hw== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@amd.com header.s=selector1 header.b=PTvcxJDd; arc=pass (i=1 spf=pass spfdomain=amd.com dmarc=pass fromdomain=amd.com); spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=amd.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id bm18-20020a656e92000000b0047699804989si85642pgb.64.2022.11.16.21.01.05; Wed, 16 Nov 2022 21:01:18 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@amd.com header.s=selector1 header.b=PTvcxJDd; arc=pass (i=1 spf=pass spfdomain=amd.com dmarc=pass fromdomain=amd.com); spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=amd.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234612AbiKQEpJ (ORCPT <rfc822;just.gull.subs@gmail.com> + 99 others); Wed, 16 Nov 2022 23:45:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54190 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234000AbiKQEpG (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 16 Nov 2022 23:45:06 -0500 Received: from NAM10-MW2-obe.outbound.protection.outlook.com (mail-mw2nam10on2087.outbound.protection.outlook.com [40.107.94.87]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6304B48747; Wed, 16 Nov 2022 20:45:01 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=bvW68UGrHYezazw/HrY3/jbBbIvmayNypy5BeK+Y9YeoAtKiLeEVPsQE/Ae/3tGFRPkJwdn/DwqqzEiY9FaQJgpRQEpE9j2aWqWxuWnxv3qwXx8jMTPwrdEqU4ymysu1RhBWdf+vK1j0A+gEtg88kKFwLcezTpLQ1j/oFcpplzDJQCOBLbkNn83/wiDPxaJ3W08en7jpRbFOz5jOo9/LzdMUNzlyba/STEYfi/8hI35cOuLyoDYgejpKyfqx0JIxD2IkwH9yP/u5bPa0z4f8s7qWiiOZPzwQ8UjMW7hJzAagdDz4ZU4nLd0WXtjk+fuN1ucwJTvr35Kok0DCO+04hg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=SlrRFHQCFrZ21kW3wSZHbnli+sSJ10JduFtslfmePq0=; b=F5pzAcrJ4jaerAPSmHg06zY45isOufPbnj0ynJ0hTCruKegtX879T/RQNUReTJ+KF3E8BJ60r59S2+mWoAzGqU2LjP+aqA067B5QqbtROYw/h438Sbk5N89/fl88yEyAmrOX3pHxpjqKppWSzEH3mxHwIacF+ojTMqVOBkvPWWGhBXVQGMrTxKsJ1WTOqecuq9QAn7Y4MHl8WPjnbPUZMC+bJ6ibxbXQX2UJyHZpJLh2sHGYwt+fqapgEt6NYfvj0ItO6+e+IfFjk8lG0fPo2pBUjk9sinKtZZG3sqYIBK9rKZ3KoD3DAcemMta8NPzUz/Bbe20yAtJNrLEta01ukA== 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 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=SlrRFHQCFrZ21kW3wSZHbnli+sSJ10JduFtslfmePq0=; b=PTvcxJDdufjREdavHkpBI6VyMNxUZUcdSIk4MkoMbG2j8PQCsI3zPUmEJ8nv4oRkA9AlZZ0pOgvZrGN5TRgDjIZxWQjCV1fWNKsO7sqP2GJSXHUgYrDnKK6kz9BEQF2LtKuR99NPeo+sT167+HYmcx9MKDOFgUbgm9O7JexXNOE= Received: from MW4PR04CA0245.namprd04.prod.outlook.com (2603:10b6:303:88::10) by IA1PR12MB6329.namprd12.prod.outlook.com (2603:10b6:208:3e5::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5813.17; Thu, 17 Nov 2022 04:44:58 +0000 Received: from CO1NAM11FT078.eop-nam11.prod.protection.outlook.com (2603:10b6:303:88:cafe::91) by MW4PR04CA0245.outlook.office365.com (2603:10b6:303:88::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5813.20 via Frontend Transport; Thu, 17 Nov 2022 04:44:57 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by CO1NAM11FT078.mail.protection.outlook.com (10.13.175.177) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.5834.8 via Frontend Transport; Thu, 17 Nov 2022 04:44:57 +0000 Received: from gomati.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.2375.34; Wed, 16 Nov 2022 22:44:53 -0600 From: Nikunj A Dadhania <nikunj@amd.com> To: <linux-kernel@vger.kernel.org>, <x86@kernel.org>, <kvm@vger.kernel.org> CC: <bp@alien8.de>, <mingo@redhat.com>, <tglx@linutronix.de>, <dave.hansen@linux.intel.com>, <seanjc@google.com>, <pbonzini@redhat.com>, <thomas.lendacky@amd.com>, <nikunj@amd.com>, <michael.roth@amd.com>, <stable@kernel.org> Subject: [PATCH] x86/sev: Add SEV-SNP guest feature negotiation support Date: Thu, 17 Nov 2022 10:14:33 +0530 Message-ID: <20221117044433.244656-1-nikunj@amd.com> X-Mailer: git-send-email 2.32.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Originating-IP: [10.180.168.240] X-ClientProxiedBy: SATLEXMB04.amd.com (10.181.40.145) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CO1NAM11FT078:EE_|IA1PR12MB6329:EE_ X-MS-Office365-Filtering-Correlation-Id: 4c1838f3-616b-4f28-01a4-08dac8567aaa X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: clgGznXRavXskn0+EQWLSkCs2LAFHCgoVmNLzNfnPFyMqc6ye5B4U72x7pBGF4YLHdpKL7vPMaZ/TIDyRaBpmACJ0VxKZvywmC6Y1vCRIhcTrXCE2EvX3YR/OfR90EgJlH5w5AmjpnXzaYnq9Wcvm/40/4PhsIyH6BQPC9JkelAqtXrgtuAvt0AaZMAYrU/WjY8XY6dpNtE7opZPdZGDxNVqfbcUKjF95pJAFuOz6tTzB1dwPKZ0SA0gY3J35U1LWe8o3SVOljvbZ9bGW95UY/n2a01hLIWpkcfMjOGCdtzsI0eKfQLrnpmKEy9I8Oc2DHDCGQFKNFXuKTxFYwziU02w1GDnFVSsVWLyHGOEk39XyZQRHmYNqCJTwRh6ywn2F0EsdCpTPljXOcgO1n7gAjrvVnN7GKY3r8BG+lvHiZ+SY/jfuoWiCwVOZEFN+PZ8im1TwjGv5ajSMD9/RJa07twezZMV6+ye9nCmUpj0zCD2fjNiMhdzdbYX/ZeR7IK6u+JxDHLySC86k6Gr1te0m35RAeZQKrxVyFj/lwDwtZCvRdgCx99CLbm/Gh09k0hwM15Yy+O4Eafn0lhlBcq8f71Bn+fk0Q2lNfd0YwUnUh9S0Vc2Pd75UB8vcNfd5eQcJ/pveCV7HgDkUsahSLfQJJnpHme16AZSB05kkW+x9LFvMrQhqoBrEQ7mEZsmoTfVRqhpDKakK6LsLWxeo59Gxshg7uLLW5WlTXTNo0g72vSofMzzRT9vzQg/Oy1IU89HrD96i6tVTPrPJ3rJOnQ66g== 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:(13230022)(4636009)(396003)(346002)(39860400002)(376002)(136003)(451199015)(40470700004)(36840700001)(46966006)(41300700001)(7416002)(4326008)(36756003)(16526019)(2616005)(1076003)(8676002)(8936002)(316002)(5660300002)(70586007)(336012)(26005)(70206006)(186003)(82740400003)(36860700001)(40460700003)(40480700001)(83380400001)(47076005)(82310400005)(426003)(2906002)(81166007)(356005)(6666004)(966005)(478600001)(110136005)(54906003)(7696005)(36900700001);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Nov 2022 04:44:57.5488 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 4c1838f3-616b-4f28-01a4-08dac8567aaa 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: CO1NAM11FT078.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA1PR12MB6329 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1749718168075171161?= X-GMAIL-MSGID: =?utf-8?q?1749718168075171161?= |
Series |
x86/sev: Add SEV-SNP guest feature negotiation support
|
|
Commit Message
Nikunj A. Dadhania
Nov. 17, 2022, 4:44 a.m. UTC
SEV_STATUS indicates features that hypervisor has enabled. Guest
kernel may not support all the features that the hypervisor has
enabled. If the hypervisor has enabled an unsupported feature,
notify the hypervisor and terminate the boot.
More details in AMD64 APM[1] Vol 2: 15.34.10 SEV_STATUS MSR
[1] https://www.amd.com/system/files/TechDocs/40332_4.05.pdf
Fixes: cbd3d4f7c4e5 ("x86/sev: Check SEV-SNP features support")
CC: Michael Roth <michael.roth@amd.com>
CC: Tom Lendacky <thomas.lendacky@amd.com>
CC: <stable@kernel.org>
Signed-off-by: Nikunj A Dadhania <nikunj@amd.com>
---
arch/x86/boot/compressed/sev.c | 18 +++++++++++++
arch/x86/include/asm/msr-index.h | 46 +++++++++++++++++++++++++++++---
2 files changed, 61 insertions(+), 3 deletions(-)
Comments
On Thu, Nov 17, 2022 at 10:14:33AM +0530, Nikunj A Dadhania wrote: > SEV_STATUS indicates features that hypervisor has enabled. Guest "... which the hypervisor has ..." > kernel may not support all the features that the hypervisor has > enabled. If the hypervisor has enabled an unsupported feature, > notify the hypervisor and terminate the boot. This sentence needs expanding: why is the policy of the guest kernel such that it must terminate if the hypervisor has enabled unsupported features? You allude to that in the comments below but this needs to be explained here too. > More details in AMD64 APM[1] Vol 2: 15.34.10 SEV_STATUS MSR > > [1] https://www.amd.com/system/files/TechDocs/40332_4.05.pdf > > Fixes: cbd3d4f7c4e5 ("x86/sev: Check SEV-SNP features support") > CC: Michael Roth <michael.roth@amd.com> > CC: Tom Lendacky <thomas.lendacky@amd.com> > CC: <stable@kernel.org> > Signed-off-by: Nikunj A Dadhania <nikunj@amd.com> > --- > arch/x86/boot/compressed/sev.c | 18 +++++++++++++ > arch/x86/include/asm/msr-index.h | 46 +++++++++++++++++++++++++++++--- > 2 files changed, 61 insertions(+), 3 deletions(-) Btw, how did you test this patch? In file included from ./arch/x86/include/asm/msr.h:5, from ./arch/x86/include/asm/processor.h:22, from ./arch/x86/include/asm/cpufeature.h:5, from ./arch/x86/include/asm/thread_info.h:53, from ./include/linux/thread_info.h:60, from ./arch/x86/include/asm/elf.h:8, from ./include/linux/elf.h:6, from arch/x86/boot/compressed/misc.h:24, from arch/x86/boot/compressed/sev.c:13: arch/x86/boot/compressed/sev.c: In function ‘snp_guest_feature_supported’: ./arch/x86/include/asm/msr-index.h:602:37: error: ‘MSR_AMD64_SNP_BIT13_RESERVED_ENABLED’ undeclared (first use in this function); did you mean ‘MSR_AMD64_SNP_BIT13_RESERVED’? 602 | MSR_AMD64_SNP_BIT13_RESERVED_ENABLED | \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ./arch/x86/include/asm/msr-index.h:602:37: note: in definition of macro ‘SNP_GUEST_SUPPORT_REQUIRED’ 602 | MSR_AMD64_SNP_BIT13_RESERVED_ENABLED | \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ./arch/x86/include/asm/msr-index.h:602:37: note: each undeclared identifier is reported only once for each function it appears in 602 | MSR_AMD64_SNP_BIT13_RESERVED_ENABLED | \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ./arch/x86/include/asm/msr-index.h:602:37: note: in definition of macro ‘SNP_GUEST_SUPPORT_REQUIRED’ 602 | MSR_AMD64_SNP_BIT13_RESERVED_ENABLED | \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ./arch/x86/include/asm/msr-index.h:604:37: error: ‘MSR_AMD64_SNP_BIT15_RESERVED_ENABLED’ undeclared (first use in this function); did you mean ‘MSR_AMD64_SNP_BIT15_RESERVED’? 604 | MSR_AMD64_SNP_BIT15_RESERVED_ENABLED | \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ./arch/x86/include/asm/msr-index.h:604:37: note: in definition of macro ‘SNP_GUEST_SUPPORT_REQUIRED’ 604 | MSR_AMD64_SNP_BIT15_RESERVED_ENABLED | \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ./arch/x86/include/asm/msr-index.h:605:37: error: ‘MSR_AMD64_SNP_MASK_RESERVED_ENABLED’ undeclared (first use in this function); did you mean ‘MSR_AMD64_SNP_MASK_RESERVED’? 605 | MSR_AMD64_SNP_MASK_RESERVED_ENABLED) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ./arch/x86/include/asm/msr-index.h:605:37: note: in definition of macro ‘SNP_GUEST_SUPPORT_REQUIRED’ 605 | MSR_AMD64_SNP_MASK_RESERVED_ENABLED) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ make[2]: *** [scripts/Makefile.build:250: arch/x86/boot/compressed/sev.o] Error 1 make[2]: *** Waiting for unfinished jobs.... make[1]: *** [arch/x86/boot/Makefile:116: arch/x86/boot/compressed/vmlinux] Error 2 make: *** [arch/x86/Makefile:283: bzImage] Error 2 It seems like you're new to this kernel hacking business - please remember that it is absolutely mandatory that patches must be properly tested before sending them upstream. > diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c > index c93930d5ccbd..847d26e761a6 100644 > --- a/arch/x86/boot/compressed/sev.c > +++ b/arch/x86/boot/compressed/sev.c > @@ -270,6 +270,17 @@ static void enforce_vmpl0(void) > sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_NOT_VMPL0); > } > > +static bool snp_guest_feature_supported(void) > +{ > + u64 guest_support = SNP_GUEST_SUPPORT_REQUIRED & ~SNP_GUEST_SUPPORT_AVAILABLE; > + > + /* > + * Return true when SEV features that hypervisor has enabled are > + * also supported by SNP guest kernel > + */ That comment is kinda obvious. > + return !(sev_status & guest_support); > +} > + > void sev_enable(struct boot_params *bp) > { > unsigned int eax, ebx, ecx, edx; > @@ -335,6 +346,13 @@ void sev_enable(struct boot_params *bp) > if (!(get_hv_features() & GHCB_HV_FT_SNP)) > sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED); > > + /* > + * Terminate the boot if hypervisor has enabled a feature > + * unsupported by the guest. > + */ > + if (!snp_guest_feature_supported()) > + sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED); > + > enforce_vmpl0(); > } > > diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h > index 4a2af82553e4..d33691b4cb24 100644 > --- a/arch/x86/include/asm/msr-index.h > +++ b/arch/x86/include/asm/msr-index.h > @@ -567,9 +567,49 @@ > #define MSR_AMD64_SEV_ENABLED_BIT 0 > #define MSR_AMD64_SEV_ES_ENABLED_BIT 1 > #define MSR_AMD64_SEV_SNP_ENABLED_BIT 2 > -#define MSR_AMD64_SEV_ENABLED BIT_ULL(MSR_AMD64_SEV_ENABLED_BIT) > -#define MSR_AMD64_SEV_ES_ENABLED BIT_ULL(MSR_AMD64_SEV_ES_ENABLED_BIT) > -#define MSR_AMD64_SEV_SNP_ENABLED BIT_ULL(MSR_AMD64_SEV_SNP_ENABLED_BIT) > +#define MSR_AMD64_SEV_ENABLED BIT_ULL(MSR_AMD64_SEV_ENABLED_BIT) > +#define MSR_AMD64_SEV_ES_ENABLED BIT_ULL(MSR_AMD64_SEV_ES_ENABLED_BIT) > +#define MSR_AMD64_SEV_SNP_ENABLED BIT_ULL(MSR_AMD64_SEV_SNP_ENABLED_BIT) > +#define MSR_AMD64_SNP_VTOM_ENABLED BIT_ULL(3) > +#define MSR_AMD64_SNP_REFLECT_VC_ENABLED BIT_ULL(4) > +#define MSR_AMD64_SNP_RESTRICTED_INJ_ENABLED BIT_ULL(5) > +#define MSR_AMD64_SNP_ALT_INJ_ENABLED BIT_ULL(6) > +#define MSR_AMD64_SNP_DEBUG_SWAP_ENABLED BIT_ULL(7) > +#define MSR_AMD64_SNP_PREVENT_HOST_IBS_ENABLED BIT_ULL(8) > +#define MSR_AMD64_SNP_BTB_ISOLATION_ENABLED BIT_ULL(9) > +#define MSR_AMD64_SNP_VMPL_SSS_ENABLED BIT_ULL(10) > +#define MSR_AMD64_SNP_SECURE_TSC_ENABLED BIT_ULL(11) > +#define MSR_AMD64_SNP_VMGEXIT_PARAM_ENABLED BIT_ULL(12) > +#define MSR_AMD64_SNP_IBS_VIRT_ENABLED BIT_ULL(14) > +#define MSR_AMD64_SNP_VMSA_REG_PROTECTION_ENABLED BIT_ULL(16) > +#define MSR_AMD64_SNP_SMT_PROTECTION_ENABLED BIT_ULL(17) > +/* Prevent hypervisor to enable undefined feature bits */ > +#define MSR_AMD64_SNP_BIT13_RESERVED BIT_ULL(13) > +#define MSR_AMD64_SNP_BIT15_RESERVED BIT_ULL(15) > +#define MSR_AMD64_SNP_MASK_RESERVED GENMASK_ULL(63, 18) So I don't like this: if you're going to enforce those bits, shouldn't that enforcement happen after *all* those above have been added to the kernel first? Because right now it will be dead code. So what's the actual purpose of this patch? > +/* > + * Features that needs enlightened guest and cannot be supported with > + * unmodified SNP guest kernel. This is subset of SEV_FEATURES. > + */ > +#define SNP_GUEST_SUPPORT_REQUIRED (MSR_AMD64_SNP_VTOM_ENABLED | \ > + MSR_AMD64_SNP_REFLECT_VC_ENABLED | \ > + MSR_AMD64_SNP_RESTRICTED_INJ_ENABLED | \ > + MSR_AMD64_SNP_ALT_INJ_ENABLED | \ > + MSR_AMD64_SNP_VMPL_SSS_ENABLED | \ > + MSR_AMD64_SNP_SECURE_TSC_ENABLED | \ > + MSR_AMD64_SNP_VMGEXIT_PARAM_ENABLED | \ > + MSR_AMD64_SNP_BIT13_RESERVED_ENABLED | \ > + MSR_AMD64_SNP_VMSA_REG_PROTECTION_ENABLED | \ > + MSR_AMD64_SNP_BIT15_RESERVED_ENABLED | \ > + MSR_AMD64_SNP_MASK_RESERVED_ENABLED) > +/* > + * Subset of SNP_GUEST_SUPPORT_REQUIRED, advertising the features that are > + * supported in this enlightened guest kernel. As and when new features are > + * added in the guest kernel, corresponding bit for this feature needs to be > + * added as part of SNP_GUEST_SUPPORT_AVAILABLE. > + */ > +#define SNP_GUEST_SUPPORT_AVAILABLE (0) The reserved bits 13 and 15 trivially belong here already no? And I don't like that AVAILABLE thing either. I think this all should be concentrated in this single function snp_guest_feature_supported() - it should be called snp_guest_supports_all_required_features() or so, so that the name says what it does and there you can pick those apart and say yes or no at the end. I'm also not sure you need each single bit defined separately but rather test a mask instead first. Also, having "_ENABLED" at the end of each bit name is too much - the name is enough.
Hi Boris, On 17/11/22 16:11, Borislav Petkov wrote: > On Thu, Nov 17, 2022 at 10:14:33AM +0530, Nikunj A Dadhania wrote: >> SEV_STATUS indicates features that hypervisor has enabled. Guest > > "... which the hypervisor has ..." Sure. > >> kernel may not support all the features that the hypervisor has >> enabled. If the hypervisor has enabled an unsupported feature, >> notify the hypervisor and terminate the boot. > > This sentence needs expanding: why is the policy of the guest kernel > such that it must terminate if the hypervisor has enabled unsupported > features? > > You allude to that in the comments below but this needs to be explained > here too. Sure > >> More details in AMD64 APM[1] Vol 2: 15.34.10 SEV_STATUS MSR >> >> [1] https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%2F40332_4.05.pdf&data=05%7C01%7Cnikunj.dadhania%40amd.com%7C44df93f0ef4349db849608dac8885136%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C638042785223235199%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=RMoXNQZXTA2O%2F%2BJQHjmWCPMzkzITXt8F071UEYlOyIQ%3D&reserved=0 >> >> Fixes: cbd3d4f7c4e5 ("x86/sev: Check SEV-SNP features support") >> CC: Michael Roth <michael.roth@amd.com> >> CC: Tom Lendacky <thomas.lendacky@amd.com> >> CC: <stable@kernel.org> >> Signed-off-by: Nikunj A Dadhania <nikunj@amd.com> >> --- >> arch/x86/boot/compressed/sev.c | 18 +++++++++++++ >> arch/x86/include/asm/msr-index.h | 46 +++++++++++++++++++++++++++++--- >> 2 files changed, 61 insertions(+), 3 deletions(-) > > Btw, how did you test this patch? <SNIP> > It seems like you're new to this kernel hacking business - please > remember that it is absolutely mandatory that patches must be properly> tested before sending them upstream. My bad, was on a separate tree and missed to test it on latest. >> diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c >> index c93930d5ccbd..847d26e761a6 100644 >> --- a/arch/x86/boot/compressed/sev.c >> +++ b/arch/x86/boot/compressed/sev.c >> @@ -270,6 +270,17 @@ static void enforce_vmpl0(void) >> sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_NOT_VMPL0); >> } >> >> +static bool snp_guest_feature_supported(void) >> +{ >> + u64 guest_support = SNP_GUEST_SUPPORT_REQUIRED & ~SNP_GUEST_SUPPORT_AVAILABLE; >> + >> + /* >> + * Return true when SEV features that hypervisor has enabled are >> + * also supported by SNP guest kernel >> + */ > > That comment is kinda obvious. > >> + return !(sev_status & guest_support); >> +} >> + >> void sev_enable(struct boot_params *bp) >> { >> unsigned int eax, ebx, ecx, edx; >> @@ -335,6 +346,13 @@ void sev_enable(struct boot_params *bp) >> if (!(get_hv_features() & GHCB_HV_FT_SNP)) >> sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED); >> >> + /* >> + * Terminate the boot if hypervisor has enabled a feature >> + * unsupported by the guest. >> + */ >> + if (!snp_guest_feature_supported()) >> + sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED); >> + >> enforce_vmpl0(); >> } >> >> diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h >> index 4a2af82553e4..d33691b4cb24 100644 >> --- a/arch/x86/include/asm/msr-index.h >> +++ b/arch/x86/include/asm/msr-index.h >> @@ -567,9 +567,49 @@ >> #define MSR_AMD64_SEV_ENABLED_BIT 0 >> #define MSR_AMD64_SEV_ES_ENABLED_BIT 1 >> #define MSR_AMD64_SEV_SNP_ENABLED_BIT 2 >> -#define MSR_AMD64_SEV_ENABLED BIT_ULL(MSR_AMD64_SEV_ENABLED_BIT) >> -#define MSR_AMD64_SEV_ES_ENABLED BIT_ULL(MSR_AMD64_SEV_ES_ENABLED_BIT) >> -#define MSR_AMD64_SEV_SNP_ENABLED BIT_ULL(MSR_AMD64_SEV_SNP_ENABLED_BIT) >> +#define MSR_AMD64_SEV_ENABLED BIT_ULL(MSR_AMD64_SEV_ENABLED_BIT) >> +#define MSR_AMD64_SEV_ES_ENABLED BIT_ULL(MSR_AMD64_SEV_ES_ENABLED_BIT) >> +#define MSR_AMD64_SEV_SNP_ENABLED BIT_ULL(MSR_AMD64_SEV_SNP_ENABLED_BIT) >> +#define MSR_AMD64_SNP_VTOM_ENABLED BIT_ULL(3) >> +#define MSR_AMD64_SNP_REFLECT_VC_ENABLED BIT_ULL(4) >> +#define MSR_AMD64_SNP_RESTRICTED_INJ_ENABLED BIT_ULL(5) >> +#define MSR_AMD64_SNP_ALT_INJ_ENABLED BIT_ULL(6) >> +#define MSR_AMD64_SNP_DEBUG_SWAP_ENABLED BIT_ULL(7) >> +#define MSR_AMD64_SNP_PREVENT_HOST_IBS_ENABLED BIT_ULL(8) >> +#define MSR_AMD64_SNP_BTB_ISOLATION_ENABLED BIT_ULL(9) >> +#define MSR_AMD64_SNP_VMPL_SSS_ENABLED BIT_ULL(10) >> +#define MSR_AMD64_SNP_SECURE_TSC_ENABLED BIT_ULL(11) >> +#define MSR_AMD64_SNP_VMGEXIT_PARAM_ENABLED BIT_ULL(12) >> +#define MSR_AMD64_SNP_IBS_VIRT_ENABLED BIT_ULL(14) >> +#define MSR_AMD64_SNP_VMSA_REG_PROTECTION_ENABLED BIT_ULL(16) >> +#define MSR_AMD64_SNP_SMT_PROTECTION_ENABLED BIT_ULL(17) >> +/* Prevent hypervisor to enable undefined feature bits */ >> +#define MSR_AMD64_SNP_BIT13_RESERVED BIT_ULL(13) >> +#define MSR_AMD64_SNP_BIT15_RESERVED BIT_ULL(15) >> +#define MSR_AMD64_SNP_MASK_RESERVED GENMASK_ULL(63, 18) > > So I don't like this: > > if you're going to enforce those bits, shouldn't that enforcement happen > after *all* those above have been added to the kernel first? Not all feature need guest kernel support so I did not use mask, so added all the known bit fields that are published in the APM. > Because right now it will be dead code. > > So what's the actual purpose of this patch? Purpose of this patch is older guests kernel that have SNP enabled (5.19 onward), when a particular SNP feature is enabled by the hypervisor that needs enlightened guest, older kernel wont be able to support the feature. There is no mechanism that the hypervisor can find out what feature is supported by the SNP guest before hand. For example PREVENT_HOST_IBS needs changes on hypervisor and no changes in the guest kernel. In this any guest kernel having SNP support should work. While for SECURE_TSC, hypervisor and guest kernel changes are required. And older guest kernel will not work if hypervisor enables Secure TSC. When secure tsc feature is enabled following define should be changed: #define SNP_GUEST_SUPPORT_AVAILABLE (MSR_AMD64_SNP_SECURE_TSC_ENABLED) >> +/* >> + * Features that needs enlightened guest and cannot be supported with >> + * unmodified SNP guest kernel. This is subset of SEV_FEATURES. >> + */ >> +#define SNP_GUEST_SUPPORT_REQUIRED (MSR_AMD64_SNP_VTOM_ENABLED | \ >> + MSR_AMD64_SNP_REFLECT_VC_ENABLED | \ >> + MSR_AMD64_SNP_RESTRICTED_INJ_ENABLED | \ >> + MSR_AMD64_SNP_ALT_INJ_ENABLED | \ >> + MSR_AMD64_SNP_VMPL_SSS_ENABLED | \ >> + MSR_AMD64_SNP_SECURE_TSC_ENABLED | \ >> + MSR_AMD64_SNP_VMGEXIT_PARAM_ENABLED | \ >> + MSR_AMD64_SNP_BIT13_RESERVED_ENABLED | \ >> + MSR_AMD64_SNP_VMSA_REG_PROTECTION_ENABLED | \ >> + MSR_AMD64_SNP_BIT15_RESERVED_ENABLED | \ >> + MSR_AMD64_SNP_MASK_RESERVED_ENABLED) >> +/* >> + * Subset of SNP_GUEST_SUPPORT_REQUIRED, advertising the features that are >> + * supported in this enlightened guest kernel. As and when new features are >> + * added in the guest kernel, corresponding bit for this feature needs to be >> + * added as part of SNP_GUEST_SUPPORT_AVAILABLE. >> + */ >> +#define SNP_GUEST_SUPPORT_AVAILABLE (0) > > The reserved bits 13 and 15 trivially belong here already no? As they are undefined feature bits, we do not know if it needs enlightened guest, can't add here. > > And I don't like that AVAILABLE thing either. I think this all should be > concentrated in this single function snp_guest_feature_supported() - it > should be called > > snp_guest_supports_all_required_features() snp_guest_supports_all_required_features() { /* Features guest is supporting, currently no SNP features supported */ u64 supported_features = (0); /* Features that will not work without guest support */ u64 required_features = (SNP_VTOM | REFLECT_VC | ...); return !(sev_status & (required_features & ~supported_features)); } > or so, so that the name says what it does and there you can pick those > apart and say yes or no at the end. > > I'm also not sure you need each single bit defined separately but rather > test a mask instead first. > > Also, having "_ENABLED" at the end of each bit name is too much - the > name is enough. Will removed _ENABLED, kept it for consistency of previous defines MSR_AMD64_SEV_ENABLED, etc. Thanks for the review Regards Nikunj
On Thu, Nov 17, 2022 at 05:50:34PM +0530, Nikunj A. Dadhania wrote: > Purpose of this patch is older guests kernel that have SNP enabled > (5.19 onward), when a particular SNP feature is enabled by the > hypervisor that needs enlightened guest, older kernel wont be able to > support the feature. There is no mechanism that the hypervisor can > find out what feature is supported by the SNP guest before hand. > > For example PREVENT_HOST_IBS needs changes on hypervisor and no > changes in the guest kernel. In this any guest kernel having SNP > support should work. > > While for SECURE_TSC, hypervisor and guest kernel changes are > required. And older guest kernel will not work if hypervisor enables > Secure TSC. When secure tsc feature is enabled following define should > be changed: This all is still veiled in mist to me. What are you trying to do here? - Make sure older SNP guests boot on newer hypervisors? - Newer guests boot on older hypervisors? So, first, pls explain in detail what the goal here is. I'm reading the above in multiple ways so you need to spell out first what you wanna do. PREVENT_HOST_IBS doesn't need any enablement. So why is it in the mask? SECURE_TSC needs enablement on both. Why aren't you checking only this one. IOW, I would expect to check *only* for features which the guest needs for the hypervisor to support before it boots. But not check everything wholesale. IOW, I see it this way: guest boots, sees what the hypervisor has enabled as SEV_STATUS cannot be intercepted and acts accordingly. Now, the question how *old* guests should act here is a whole different story as it depends on whether this gets backported to old guests - which doesn't make them old anymore as the checking will happen - or to really old guests without the checking. There it doesn't matter. And come to think of it, this whole deal is no different than having feature bits in CPUID and the kernel implementing them. If the kernel finds a feature bit set in CPUID, it enables the corresponding code. If it doesn't know about it, then it doesn't do anything. Pretty much the same here: if a SNP guest finds a feature flag in SEV_STATUS, then it enables the code corresponding to it. If it doesn't find it but it needs it due to enablement, then it stops booting. So let's define the problem first. Thx.
On 17/11/22 18:23, Borislav Petkov wrote: > On Thu, Nov 17, 2022 at 05:50:34PM +0530, Nikunj A. Dadhania wrote: >> Purpose of this patch is older guests kernel that have SNP enabled >> (5.19 onward), when a particular SNP feature is enabled by the >> hypervisor that needs enlightened guest, older kernel wont be able to >> support the feature. There is no mechanism that the hypervisor can >> find out what feature is supported by the SNP guest before hand. >> >> For example PREVENT_HOST_IBS needs changes on hypervisor and no >> changes in the guest kernel. In this any guest kernel having SNP >> support should work. >> >> While for SECURE_TSC, hypervisor and guest kernel changes are >> required. And older guest kernel will not work if hypervisor enables >> Secure TSC. When secure tsc feature is enabled following define should >> be changed: > > This all is still veiled in mist to me. What are you trying to do here? > > - Make sure older SNP guests boot on newer hypervisors? Yes and No. Yes: For feature flags that do not need an enlightened guest, older guests should boot. No: For feature flags that need an enlightened guest, older guests should detect and fail booting on any hypervisor that sets this feature flag. > - Newer guests boot on older hypervisors? Yes, as the older hypervisor won't enable the new SNP feature flag. > So, first, pls explain in detail what the goal here is. The hypervisor can enable various new features flags(in SEV_FEATURES[1:63]) and start the guest. The hypervisor does not know beforehand that the guest kernel supports the feature that is being enabled. While booting, SNP guests can discover the hypervisor-enabled features by looking at SEV_STATUS MSR. At this point, the SNP guest needs to decide either to continue boot or terminate depending on the feature support in the guest kernel. Otherwise, if we let the guest continue booting with an unsupported feature, the guest can fail in non-obvious manner. * Primary goal here is to detect such unsupported features beforehand and deterministically terminate the guest. * Secondary goal is to use this mechanism to future-proof the current guests for newer reserved features flags that may be defined later. Here is the support matrix per feature that can explain better: HypervisorEnabled: Feature bit is enabled in SEV_FEATURES Required: Feature requires enlightened guest Available: The guest is enlightened for that particular feature. Boot: The expected behavior of the guest, whether it should boot or fail. +-------------------+----------+-------------+----------+ | HypervisorEnabled | Required | Available | Boot | +-------------------+----------+-------------+----------+ | Y | Y | N | N (Fail) | | Y | Y | Y | Y | | Y | N | N | Y | | N | Y/N | Y/N | Y | +-------------------+----------+-------------+----------+ > I'm reading the above in multiple ways so you need to spell out first > what you wanna do. > > PREVENT_HOST_IBS doesn't need any enablement. So why is it in the mask? PREVENT_HOST_IBS will be defined but shouldn't be part of the "Required" mask. > SECURE_TSC needs enablement on both. Why aren't you checking only this > one. SECURE_TSC should be part of "Required" mask and once secure tsc support is up-streamed it should be added to "Available" mask. > IOW, I would expect to check *only* for features which the guest needs > for the hypervisor to support before it boots. But not check everything > wholesale. Guests need to check for features enabled by the hypervisor that is not supported as well, so that we can terminate the guest right there. > IOW, I see it this way: guest boots, sees what the hypervisor has > enabled as SEV_STATUS cannot be intercepted and acts accordingly. > > Now, the question how *old* guests should act here is a whole different > story as it depends on whether this gets backported to old guests - > which doesn't make them old anymore as the checking will happen - Old guests with backport will deny booting with unsupported features. > or to > really old guests without the checking. There it doesn't matter. It does matter for old guests which dont have backport, the behavior will be undefined. Hence fix needs to be back ported till 5.19, where SNP guest support was added. > And come to think of it, this whole deal is no different than having > feature bits in CPUID and the kernel implementing them. > > If the kernel finds a feature bit set in CPUID, it enables the > corresponding code. If it doesn't know about it, then it doesn't do > anything. > > Pretty much the same here: if a SNP guest finds a feature flag in > SEV_STATUS, then it enables the code corresponding to it. This is the good case, where the feature flag is enabled and the guest kernel has support for the feature. This should boot fine. Second Case which we are handling in this patch: SNP guest finds the feature flag enabled, but it does not have code corresponding to that feature. The guest boot should *fail*. > If it doesn't > find it but it needs it due to enablement, then it stops booting. Above is the third case: where the SNP guest does not see the feature flag enabled and the guest should boot fine irrespective of whether it is enlightened or not. Regards, Nikunj
On Fri, Nov 18, 2022 at 06:58:07PM +0530, Nikunj A. Dadhania wrote: > No: For feature flags that need an enlightened guest, older guests > should detect and fail booting on any hypervisor that sets this > feature flag. What would happen with such old guests nowadays? Wouldn't they explode anyway? And how is this supposed to work in practice? I'm guessing this is supposed to address a case where guest owner goes to a cloud provider, boots an old guest and it magically survives booting and then it runs with some false sense of security. But isn't that part of the whole attestation dance where the guest owner checks for a minimum set of features it expects to be present? Because if you do this and the cloud provider updates the hypervisor, all the guest owner images might stop working all of a sudden because of this check. So what is the actual, real-life example where this helps? At all? > The hypervisor can enable various new features flags(in > SEV_FEATURES[1:63]) and start the guest. The hypervisor does not know > beforehand that the guest kernel supports the feature that is being > enabled. This is not the right criterion: it should be more like: can a guest still continue booting with a new feature it doesn't know about and still provide the same security. But see above - you need to think very practically here before even considering such a thing. > While booting, SNP guests can discover the hypervisor-enabled features > by looking at SEV_STATUS MSR. At this point, the SNP guest needs to > decide either to continue boot or terminate depending on the feature > support in the guest kernel. Otherwise, if we let the guest continue > booting with an unsupported feature, the guest can fail in non-obvious > manner. How can an old guest decide when it doesn't even have the intelligence to do so? What you're doing is, have old guests immediately stop booting when they encounter a new feature - even if that new feature doesn't impair their security. > +-------------------+----------+-------------+----------+ > | HypervisorEnabled | Required | Available | Boot | > +-------------------+----------+-------------+----------+ > | Y | Y | N | N (Fail) | This means that you need to know those features which would fail an old guest *upfront*. Like right now. And I hardly doubt that. > PREVENT_HOST_IBS will be defined but shouldn't be part of the > "Required" mask. So it doesn't need to be mentioned at all. > SECURE_TSC should be part of "Required" mask and once secure tsc > support is up-streamed it should be added to "Available" mask. So when a guest owner gets a new guest which supports SECURE_TSC and tries to boot it on an older HV - which is very much pretty everywhere the case - cloud providers won't update their HV kernel whenever - that new guest won't boot at all. Which is a bad bad idea. I don't think you want that. What you want, rather, is to say in the SECURE_TSC enablement code pr_warn("HV doesn't support secure TSC - your guest won't be 100% secure\n"); or so. > Guests need to check for features enabled by the hypervisor that is not > supported as well, so that we can terminate the guest right there. That needs to be done in the feature enablement code of each feature but not wholesale like this. Anyway, I think you get my point. Thx.
Hi Boris, I will work on sending a v2 patch that addresses all your questions/concerns. On 21/11/22 21:44, Borislav Petkov wrote: > On Fri, Nov 18, 2022 at 06:58:07PM +0530, Nikunj A. Dadhania wrote: >> No: For feature flags that need an enlightened guest, older guests >> should detect and fail booting on any hypervisor that sets this >> feature flag. > > What would happen with such old guests nowadays? Wouldn't they explode > anyway? Yes, and the patch is to prevent that and fail gracefully and so I had CC'ed stable. > And how is this supposed to work in practice? > > I'm guessing this is supposed to address a case where guest owner goes > to a cloud provider, boots an old guest and it magically survives > booting and then it runs with some false sense of security. > > But isn't that part of the whole attestation dance where the guest owner > checks for a minimum set of features it expects to be present? > > Because if you do this and the cloud provider updates the hypervisor, > all the guest owner images might stop working all of a sudden because of > this check. > > So what is the actual, real-life example where this helps? At all? A cloud provider having the hypervisor and qemu with Secure TSC support tries to boot an old guest kernel (v5.19): "-object sev-snp-guest,...,secure-tsc=on -kernel vmlinuz-5.19.0" As per the current behavior, the guest kernel will hang. This patch will make sure that if the hypervisor enables this feature, the guest kernel will know early that an unsupported SNP feature is enabled. The guest then sends a terminate message to the hypervisor, indicating that its not able to fulfill hypervisor request to enable SecureTSC and cannot move ahead. >> The hypervisor can enable various new features flags(in >> SEV_FEATURES[1:63]) and start the guest. The hypervisor does not know >> beforehand that the guest kernel supports the feature that is being >> enabled. > > This is not the right criterion: it should be more like: can a guest > still continue booting with a new feature it doesn't know about and > still provide the same security. That is indeed the criterion. Hence, instead of allowing the guest to continue and have it fail randomly later(which would be a debugging nightmare), this is to detect the unsupported feature early and fail gracefully. > But see above - you need to think very practically here before even > considering such a thing. > >> While booting, SNP guests can discover the hypervisor-enabled features >> by looking at SEV_STATUS MSR. At this point, the SNP guest needs to >> decide either to continue boot or terminate depending on the feature >> support in the guest kernel. Otherwise, if we let the guest continue >> booting with an unsupported feature, the guest can fail in non-obvious >> manner. > > How can an old guest decide when it doesn't even have the intelligence > to do so? > > What you're doing is, have old guests immediately stop booting when they > encounter a new feature - even if that new feature doesn't impair their > security. A slight correction: a) If the new feature was enabled by the HV/QEMU. AND b) The new feature requires guest enablement " -object sev-snp-guest,...,secure-tsc=on -kernel vmlinuz-5.19.0 " And it is not done wholesale. > >> +-------------------+----------+-------------+----------+ >> | HypervisorEnabled | Required | Available | Boot | >> +-------------------+----------+-------------+----------+ >> | Y | Y | N | N (Fail) | > > This means that you need to know those features which would fail an old > guest *upfront*. Like right now. And I hardly doubt that. > >> PREVENT_HOST_IBS will be defined but shouldn't be part of the >> "Required" mask. > > So it doesn't need to be mentioned at all. Yes, we could get rid of defines that do not need to be included in required mask. >> SECURE_TSC should be part of "Required" mask and once secure tsc >> support is up-streamed it should be added to "Available" mask. > > So when a guest owner gets a new guest which supports SECURE_TSC and > tries to boot it on an older HV - which is very much pretty everywhere > the case - cloud providers won't update their HV kernel whenever - that > new guest won't boot at all. I think you misunderstood, if the HV does not have Secure TSC and new guest has Secure TSC, still the guest should boot. As the hypervisor didnt request the feature to be enabled (below row in the table) +-------------------+----------+-------------+----------+ | HypervisorEnabled | Required | Available | Boot | +-------------------+----------+-------------+----------+ | N | Y/N | Y/N | Y | +-------------------+----------+-------------+----------+ > > Which is a bad bad idea. I don't think you want that. > > What you want, rather, is to say in the SECURE_TSC enablement code > > pr_warn("HV doesn't support secure TSC - your guest won't be 100% secure\n"); > > or so. > >> Guests need to check for features enabled by the hypervisor that is not >> supported as well, so that we can terminate the guest right there. > > That needs to be done in the feature enablement code of each feature but > not wholesale like this. > > Anyway, I think you get my point. Regards Nikunj
diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c index c93930d5ccbd..847d26e761a6 100644 --- a/arch/x86/boot/compressed/sev.c +++ b/arch/x86/boot/compressed/sev.c @@ -270,6 +270,17 @@ static void enforce_vmpl0(void) sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_NOT_VMPL0); } +static bool snp_guest_feature_supported(void) +{ + u64 guest_support = SNP_GUEST_SUPPORT_REQUIRED & ~SNP_GUEST_SUPPORT_AVAILABLE; + + /* + * Return true when SEV features that hypervisor has enabled are + * also supported by SNP guest kernel + */ + return !(sev_status & guest_support); +} + void sev_enable(struct boot_params *bp) { unsigned int eax, ebx, ecx, edx; @@ -335,6 +346,13 @@ void sev_enable(struct boot_params *bp) if (!(get_hv_features() & GHCB_HV_FT_SNP)) sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED); + /* + * Terminate the boot if hypervisor has enabled a feature + * unsupported by the guest. + */ + if (!snp_guest_feature_supported()) + sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED); + enforce_vmpl0(); } diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 4a2af82553e4..d33691b4cb24 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -567,9 +567,49 @@ #define MSR_AMD64_SEV_ENABLED_BIT 0 #define MSR_AMD64_SEV_ES_ENABLED_BIT 1 #define MSR_AMD64_SEV_SNP_ENABLED_BIT 2 -#define MSR_AMD64_SEV_ENABLED BIT_ULL(MSR_AMD64_SEV_ENABLED_BIT) -#define MSR_AMD64_SEV_ES_ENABLED BIT_ULL(MSR_AMD64_SEV_ES_ENABLED_BIT) -#define MSR_AMD64_SEV_SNP_ENABLED BIT_ULL(MSR_AMD64_SEV_SNP_ENABLED_BIT) +#define MSR_AMD64_SEV_ENABLED BIT_ULL(MSR_AMD64_SEV_ENABLED_BIT) +#define MSR_AMD64_SEV_ES_ENABLED BIT_ULL(MSR_AMD64_SEV_ES_ENABLED_BIT) +#define MSR_AMD64_SEV_SNP_ENABLED BIT_ULL(MSR_AMD64_SEV_SNP_ENABLED_BIT) +#define MSR_AMD64_SNP_VTOM_ENABLED BIT_ULL(3) +#define MSR_AMD64_SNP_REFLECT_VC_ENABLED BIT_ULL(4) +#define MSR_AMD64_SNP_RESTRICTED_INJ_ENABLED BIT_ULL(5) +#define MSR_AMD64_SNP_ALT_INJ_ENABLED BIT_ULL(6) +#define MSR_AMD64_SNP_DEBUG_SWAP_ENABLED BIT_ULL(7) +#define MSR_AMD64_SNP_PREVENT_HOST_IBS_ENABLED BIT_ULL(8) +#define MSR_AMD64_SNP_BTB_ISOLATION_ENABLED BIT_ULL(9) +#define MSR_AMD64_SNP_VMPL_SSS_ENABLED BIT_ULL(10) +#define MSR_AMD64_SNP_SECURE_TSC_ENABLED BIT_ULL(11) +#define MSR_AMD64_SNP_VMGEXIT_PARAM_ENABLED BIT_ULL(12) +#define MSR_AMD64_SNP_IBS_VIRT_ENABLED BIT_ULL(14) +#define MSR_AMD64_SNP_VMSA_REG_PROTECTION_ENABLED BIT_ULL(16) +#define MSR_AMD64_SNP_SMT_PROTECTION_ENABLED BIT_ULL(17) +/* Prevent hypervisor to enable undefined feature bits */ +#define MSR_AMD64_SNP_BIT13_RESERVED BIT_ULL(13) +#define MSR_AMD64_SNP_BIT15_RESERVED BIT_ULL(15) +#define MSR_AMD64_SNP_MASK_RESERVED GENMASK_ULL(63, 18) + +/* + * Features that needs enlightened guest and cannot be supported with + * unmodified SNP guest kernel. This is subset of SEV_FEATURES. + */ +#define SNP_GUEST_SUPPORT_REQUIRED (MSR_AMD64_SNP_VTOM_ENABLED | \ + MSR_AMD64_SNP_REFLECT_VC_ENABLED | \ + MSR_AMD64_SNP_RESTRICTED_INJ_ENABLED | \ + MSR_AMD64_SNP_ALT_INJ_ENABLED | \ + MSR_AMD64_SNP_VMPL_SSS_ENABLED | \ + MSR_AMD64_SNP_SECURE_TSC_ENABLED | \ + MSR_AMD64_SNP_VMGEXIT_PARAM_ENABLED | \ + MSR_AMD64_SNP_BIT13_RESERVED_ENABLED | \ + MSR_AMD64_SNP_VMSA_REG_PROTECTION_ENABLED | \ + MSR_AMD64_SNP_BIT15_RESERVED_ENABLED | \ + MSR_AMD64_SNP_MASK_RESERVED_ENABLED) +/* + * Subset of SNP_GUEST_SUPPORT_REQUIRED, advertising the features that are + * supported in this enlightened guest kernel. As and when new features are + * added in the guest kernel, corresponding bit for this feature needs to be + * added as part of SNP_GUEST_SUPPORT_AVAILABLE. + */ +#define SNP_GUEST_SUPPORT_AVAILABLE (0) #define MSR_AMD64_VIRT_SPEC_CTRL 0xc001011f