From patchwork Thu May 11 07:23:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Khalid Elmously X-Patchwork-Id: 1779791 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=QUnqXShk; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QH3Lw3YLPz214p for ; Thu, 11 May 2023 17:24:55 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1px0fP-0002Ji-Eb; Thu, 11 May 2023 07:24:47 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1px0fM-0002Ia-CU for kernel-team@lists.ubuntu.com; Thu, 11 May 2023 07:24:44 +0000 Received: from mail-qk1-f197.google.com (mail-qk1-f197.google.com [209.85.222.197]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 49E703F481 for ; Thu, 11 May 2023 07:24:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1683789881; bh=uTiHltTQc1+8uuX4tItaPiqpIlLBUxIIB5mQ5E8iHds=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=QUnqXShkYzSPO/x9oDwX100WjWT6NGWJJr5Uo0NkF6sHkXPiknB6tBvdDUwna8gCv jLjTHEqtTe/Xr6IefR4L/FACTEHX9YCF1v09w8rhx1nG7pmZLt1w7aLWiu2wjf3aEp uwSxNtMJ1O3laWhFmkyI2L0R2lw8h3Zmm5nGy564uqaoBI5RZBt17icmcHmm3R//yh 1mfpI+pMlnMWtBKEaR+J6MygtLphy4HUK+9P+1UMD2o/7DsU6Sj3HqwDRNGM3lq7X6 UAB2GwCwFrdjztvSLf/t3AMsvM0Igy01DxVGQ8koSidlWEwpEQN0gFGRTMZGAc6FBb /C05KC8tAN0Gg== Received: by mail-qk1-f197.google.com with SMTP id af79cd13be357-7578369dff3so1596353085a.0 for ; Thu, 11 May 2023 00:24:41 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683789881; x=1686381881; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=uTiHltTQc1+8uuX4tItaPiqpIlLBUxIIB5mQ5E8iHds=; b=dEBFpLFtxz8AZodLR1ZjPMEEb5nmec6yY+mNZa2i01GVfI+fLiAmPTfzKGS7Q2Sck5 6x50aT8pcexRRG8QGRBlWGffqcPi9vqCM2qGOCI31Gh6A8YRrjTODIW0Q/JGLRG/nEPq z4TIJQffDbjIZQOj0Bz35XJmdwpRAN9B92+DXgtj9vLET0oa+4bR7QjBv0R2UG1se6zm 2b99sllzltgjmOhPV9RvgWl0R+3le1xMjc75kMNWR0y4c2XwPyLG/QkBEmeJaudOPVnQ h5wv/iMfV6NwfZ9OVJbsnmJajGcQgX/SU/9ux+UT+uejEJ1+xuQezDMiBU9gUAPty8vQ ysUw== X-Gm-Message-State: AC+VfDzTIawEJX79xfrCHblx6imhCa4we6pAGnitSlZQXv8Hk4/QKvzS E+JtoqcJ1yPYAIg0tArP76JY54o/xSUL/9jxGW4ybQbeV0kdC4DAa3/6dKq5oIJ5IzY+iKng1f5 paACVTJFvGYtQnppbo/qywOxlfd2qAC74lwUMBl72AdODeci2tuFG X-Received: by 2002:a05:622a:14c:b0:3f3:8ac9:9966 with SMTP id v12-20020a05622a014c00b003f38ac99966mr24483451qtw.21.1683789880880; Thu, 11 May 2023 00:24:40 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ4pYncNWdvVwx9q0CLVKjUaCaNaYPq0S0bVGec19DbE6OymWATqvOTQ40m4i/vwXMVCLki7+A== X-Received: by 2002:a05:622a:14c:b0:3f3:8ac9:9966 with SMTP id v12-20020a05622a014c00b003f38ac99966mr24483433qtw.21.1683789880587; Thu, 11 May 2023 00:24:40 -0700 (PDT) Received: from k2.fuzzbuzz.org ([38.147.253.170]) by smtp.gmail.com with ESMTPSA id x27-20020ac8701b000000b003ef5ba0702fsm2053475qtm.7.2023.05.11.00.24.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 May 2023 00:24:40 -0700 (PDT) From: Khalid Elmously To: kernel-team@lists.ubuntu.com Subject: [SRU][v2][j/gcp][PATCH 2/2] virt/coco/sev-guest: Add throttling awareness Date: Thu, 11 May 2023 03:23:56 -0400 Message-Id: <20230511072357.1165970-3-khalid.elmously@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230511072357.1165970-1-khalid.elmously@canonical.com> References: <20230511072357.1165970-1-khalid.elmously@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Dionna Glaze BugLink: https://bugs.launchpad.net/bugs/2013198 A potentially malicious SEV guest can constantly hammer the hypervisor using this driver to send down requests and thus prevent or at least considerably hinder other guests from issuing requests to the secure processor which is a shared platform resource. Therefore, the host is permitted and encouraged to throttle such guest requests. Add the capability to handle the case when the hypervisor throttles excessive numbers of requests issued by the guest. Otherwise, the VM platform communication key will be disabled, preventing the guest from attesting itself. Realistically speaking, a well-behaved guest should not even care about throttling. During its lifetime, it would end up issuing a handful of requests which the hardware can easily handle. This is more to address the case of a malicious guest. Such guest should get throttled and if its VMPCK gets disabled, then that's its own wrongdoing and perhaps that guest even deserves it. To the implementation: the hypervisor signals with SNP_GUEST_REQ_ERR_BUSY that the guest requests should be throttled. That error code is returned in the upper 32-bit half of exitinfo2 and this is part of the GHCB spec v2. So the guest is given a throttling period of 1 minute in which it retries the request every 2 seconds. This is a good default but if it turns out to not pan out in practice, it can be tweaked later. For safety, since the encryption algorithm in GHCBv2 is AES_GCM, control must remain in the kernel to complete the request with the current sequence number. Returning without finishing the request allows the guest to make another request but with different message contents. This is IV reuse, and breaks cryptographic protections. [ bp: - Rewrite commit message and do a simplified version. - The stable tags are supposed to denote that a cleanup should go upfront before backporting this so that any future fixes to this can preserve the sanity of the backporter(s). ] Fixes: d5af44dde546 ("x86/sev: Provide support for SNP guest request NAEs") Signed-off-by: Dionna Glaze Co-developed-by: Borislav Petkov (AMD) Signed-off-by: Borislav Petkov (AMD) Reviewed-by: Tom Lendacky Cc: # d6fd48eff750 ("virt/coco/sev-guest: Check SEV_SNP attribute at probe time") Cc: # 970ab823743f (" virt/coco/sev-guest: Simplify extended guest request handling") Cc: # c5a338274bdb ("virt/coco/sev-guest: Remove the disable_vmpck label in handle_guest_request()") Cc: # 0fdb6cc7c89c ("virt/coco/sev-guest: Carve out the request issuing logic into a helper") Cc: # d25bae7dc7b0 ("virt/coco/sev-guest: Do some code style cleanups") Cc: # fa4ae42cc60a ("virt/coco/sev-guest: Convert the sw_exit_info_2 checking to a switch-case") Link: https://lore.kernel.org/r/20230214164638.1189804-2-dionnaglaze@google.com (backported from commit 72f7754dcf31c87c92c0c353dcf747814cc5ce10) [ kmously: 72f7754dcf3 was initially written for 6.0 before finally landing in 6.3. The initial proposal can be found at https://lore.kernel.org/lkml/Y9emVjoTBrM2+Y5P@zn.tnic/T/ I used that first implementation as the inspiration for this patch as it is closer to the Ubuntu 5.19 code. This was discussed with the patch author (Dionna) and confirmed this is the right approach ] Signed-off-by: Khalid Elmously diff --git a/arch/x86/include/asm/sev-common.h b/arch/x86/include/asm/sev-common.h index e6e75f19f6fd9..5c8319798954d 100644 --- a/arch/x86/include/asm/sev-common.h +++ b/arch/x86/include/asm/sev-common.h @@ -126,8 +126,9 @@ struct snp_psc_desc { struct psc_entry entries[VMGEXIT_PSC_MAX_ENTRY]; } __packed; -/* Guest message request error code */ +/* Guest message request error codes */ #define SNP_GUEST_REQ_INVALID_LEN BIT_ULL(32) +#define SNP_GUEST_REQ_ERR_BUSY BIT_ULL(33) #define GHCB_MSR_TERM_REQ 0x100 #define GHCB_MSR_TERM_REASON_SET_POS 12 diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c index 2a99145fd3aee..db4f84b1f8423 100644 --- a/arch/x86/kernel/sev.c +++ b/arch/x86/kernel/sev.c @@ -2208,15 +2208,13 @@ int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, unsigned if (ret) goto e_put; + *fw_err = ghcb->save.sw_exit_info_2; if (ghcb->save.sw_exit_info_2) { /* Number of expected pages are returned in RBX */ if (exit_code == SVM_VMGEXIT_EXT_GUEST_REQUEST && ghcb->save.sw_exit_info_2 == SNP_GUEST_REQ_INVALID_LEN) input->data_npages = ghcb_get_rbx(ghcb); - if (fw_err) - *fw_err = ghcb->save.sw_exit_info_2; - ret = -EIO; } diff --git a/drivers/virt/coco/sevguest/sevguest.c b/drivers/virt/coco/sevguest/sevguest.c index f7991bc920e4d..5f0db4a28a25c 100644 --- a/drivers/virt/coco/sevguest/sevguest.c +++ b/drivers/virt/coco/sevguest/sevguest.c @@ -324,7 +324,7 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in u8 type, void *req_buf, size_t req_sz, void *resp_buf, u32 resp_sz, __u64 *fw_err) { - unsigned long err; + unsigned long err = 0xff; u64 seqno; int rc; @@ -340,6 +340,7 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in if (rc) return rc; +retry: /* * Call firmware to process the request. In this function the encrypted * message enters shared memory with the host. So after this call the @@ -348,6 +349,14 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in */ rc = snp_issue_guest_request(exit_code, &snp_dev->input, &err); + /* + * The host may return SNP_GUEST_REQ_ERR_EBUSY if the request has been + * throttled. Retry in the driver to avoid returning and reusing the + * message sequence number on a different message. + */ + if (err == SNP_GUEST_REQ_ERR_BUSY) + goto retry; + /* * If the extended guest request fails due to having too small of a * certificate data buffer, retry the same guest request without the