From patchwork Tue Apr 6 22:49:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 416847 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A9869C433B4 for ; Tue, 6 Apr 2021 22:50:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6764E613D3 for ; Tue, 6 Apr 2021 22:50:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344204AbhDFWuS (ORCPT ); Tue, 6 Apr 2021 18:50:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40056 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344191AbhDFWuQ (ORCPT ); Tue, 6 Apr 2021 18:50:16 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0D41CC06174A for ; Tue, 6 Apr 2021 15:50:08 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id q14so6671868ybk.22 for ; Tue, 06 Apr 2021 15:50:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=9unnZdwnJBhmIr85WtW6opdl6PIonHCZIupIJTvjWiM=; b=TkbGpsapVhMM/9vNTvKB2L0fGV6FDhcQqCVGeETLXWxcwfezHG91/Q32wDXz4NNQzM nc0exNLd9sY6ryGmhhmyHB1RRJGT8Chj3tHZWlz8EP2ltZ2XznhwfwqVrVa8wOWGyxx7 0q80IQ90Nro8z6l81DX7mZp32wgeHg/9fnbOVCWSN+TnbJo+T+psv21FIznZvp11IQSD 7OO9fnXsMk0l7y7GljMe9yy4UhNrmsgXxl6Vnzk+LjeuD/C1qm4zOXUElsRpln+otQI5 b1CaykelVe2JuM1a88H8nPQECvnwDlaUMgwiRCR90/JGzBaByfMcJAkkJv8tWLv1lKzC aw8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=9unnZdwnJBhmIr85WtW6opdl6PIonHCZIupIJTvjWiM=; b=ECZPQYFLzUbyOh5xtUU3VwhNd4bdmj5hUUbe4PtyT57I0qRtEKmWHZKCnrQyO0f39v uq8Cw3Gq8PjbubXifX63I43W9FA2bWXJPN4qDjicv0rVcyV5+v3dHfe7aC+7nn0IWqyY KpVX36hNJvAahvYHU9m8NzPDBzabklJ5tjdlOaW3iMXm8j+BWkkI91tgNeZh7F+6xuOf YfbO9E4v5lIHB63gT0dzAQPAsDDNBLUo95jyYe/77Zm3Q5kcLbZBzrxy0sofU8llf3eS RNq90QqXpP/xypA+Ws6o7zgTypMbUID+ChZhEAMmU6UmOx+ryY8vCA93AmMVU/ET57fs rVcw== X-Gm-Message-State: AOAM531aK8i7rGWYOBzPj9J53etKSbKtnXWdTDKAW523qsh0FhViDFK4 53/ZKQSnO0poubNfmS1uDPX4aq6acJU= X-Google-Smtp-Source: ABdhPJzlb0ZbdnN3YVCAvkv4hLaHNRneUSdCrOk9RA1gK+d59njBjzucCXv09ROJce8rsyMB2b1YQgaYp58= X-Received: from seanjc798194.pdx.corp.google.com ([2620:15c:f:10:24a1:90fb:182b:777c]) (user=seanjc job=sendgmr) by 2002:a25:b3c1:: with SMTP id x1mr517791ybf.506.1617749407346; Tue, 06 Apr 2021 15:50:07 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 6 Apr 2021 15:49:45 -0700 In-Reply-To: <20210406224952.4177376-1-seanjc@google.com> Message-Id: <20210406224952.4177376-2-seanjc@google.com> Mime-Version: 1.0 References: <20210406224952.4177376-1-seanjc@google.com> X-Mailer: git-send-email 2.31.0.208.g409f899ff0-goog Subject: [PATCH v2 1/8] crypto: ccp: Free SEV device if SEV init fails From: Sean Christopherson To: Paolo Bonzini , Brijesh Singh , Tom Lendacky , John Allen Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, Borislav Petkov , Christophe Leroy Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org Free the SEV device if later initialization fails. The memory isn't technically leaked as it's tracked in the top-level device's devres list, but unless the top-level device is removed, the memory won't be freed and is effectively leaked. Signed-off-by: Sean Christopherson --- drivers/crypto/ccp/sev-dev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index cb9b4c4e371e..ba240d33d26e 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -987,7 +987,7 @@ int sev_dev_init(struct psp_device *psp) if (!sev->vdata) { ret = -ENODEV; dev_err(dev, "sev: missing driver data\n"); - goto e_err; + goto e_sev; } psp_set_sev_irq_handler(psp, sev_irq_handler, sev); @@ -1002,6 +1002,8 @@ int sev_dev_init(struct psp_device *psp) e_irq: psp_clear_sev_irq_handler(psp); +e_sev: + devm_kfree(dev, sev); e_err: psp->sev_data = NULL; From patchwork Tue Apr 6 22:49:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 416058 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C6619C433B4 for ; Tue, 6 Apr 2021 22:50:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8BFBC613D4 for ; Tue, 6 Apr 2021 22:50:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344268AbhDFWuZ (ORCPT ); Tue, 6 Apr 2021 18:50:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40080 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344222AbhDFWuT (ORCPT ); Tue, 6 Apr 2021 18:50:19 -0400 Received: from mail-qk1-x74a.google.com (mail-qk1-x74a.google.com [IPv6:2607:f8b0:4864:20::74a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 449D4C061761 for ; Tue, 6 Apr 2021 15:50:10 -0700 (PDT) Received: by mail-qk1-x74a.google.com with SMTP id v136so13604431qkb.9 for ; Tue, 06 Apr 2021 15:50:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=rbJKuZiYmoPztANxesWQ34dxBaTXzqRp8iyZHN+wEGM=; b=nAKAuPL8B+BdMLeg3F3EAJJ5PNzAtP7SbEN0VteWmXGIHeiK0Vq4YArK0VahJJo7I8 6X0PqiNu5YzhkVeNZ7T8gQofgQAJuimJ26X2/4FdbkEwRVIG14txaPcJxGJ5UF+dOF6+ I1toJgcJaO5y/dhvYCJ0a3na0F8JLZkmOQ6XDdSfALJ8/G0QGWoHGOsQO3zxCfgrM9Te vBsPm6RoAlnd52uD0yGE36Kwhp0AHyEYg1+zBcdYGygwmlncS48emDP3tDbxVKjs6bDe /svO2xmQG8rYo++QHEBBNz+CXAP3ZfRc7fiTR8Vcd2hWPKz0O2fSDtMcj2Wxa6NuEIr8 ZraA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=rbJKuZiYmoPztANxesWQ34dxBaTXzqRp8iyZHN+wEGM=; b=HyNc7NCeghqCJb4RAKkGpjVpwPZmOgQKOX2ddAA2kRG3pXlDcrngv6uKx696XC252C kEgt2BhVtaJasbteZpW7GsHs/r2tPfcmKlX/XQoOHdEr+CI4Ag+l0d7DS/gsGG4p0Kju fphRR0wLx+bdRKajRvWvelTtaWhDZt86ssYijkRB0rJj+sy0a0O8IMVmvwBS66J3CKg+ 9FhUSzFO8JxZwjfETH5hxwf84k/atGgTGEXweTnbcwoV68VDq71dxOLAWDqDbQuZxRE5 MK9Ujdq3UvaaDKv/olJyGMNa50Mb98nr0ekpZoRnSIZU5Hs/VCe8Uub19vcRNKPLLNFI 2vzQ== X-Gm-Message-State: AOAM530vsTj8du+nzBU8fQiqqoHMVAfzOqmz1HKRMNlc1ZVuZxNM1imV m2XcT2ei2/Aoz24O1QJNyTaSxor72B8= X-Google-Smtp-Source: ABdhPJwm7pfZujrg/BIGog4XctMHpyiLl3E+kj+Fx4XTnJuxbhBHJLrsXv4TuEif/H0+XTkkCPk9cb900q8= X-Received: from seanjc798194.pdx.corp.google.com ([2620:15c:f:10:24a1:90fb:182b:777c]) (user=seanjc job=sendgmr) by 2002:a0c:f30a:: with SMTP id j10mr528109qvl.20.1617749409335; Tue, 06 Apr 2021 15:50:09 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 6 Apr 2021 15:49:46 -0700 In-Reply-To: <20210406224952.4177376-1-seanjc@google.com> Message-Id: <20210406224952.4177376-3-seanjc@google.com> Mime-Version: 1.0 References: <20210406224952.4177376-1-seanjc@google.com> X-Mailer: git-send-email 2.31.0.208.g409f899ff0-goog Subject: [PATCH v2 2/8] crypto: ccp: Detect and reject "invalid" addresses destined for PSP From: Sean Christopherson To: Paolo Bonzini , Brijesh Singh , Tom Lendacky , John Allen Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, Borislav Petkov , Christophe Leroy Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org Explicitly reject using pointers that are not virt_to_phys() friendly as the source for SEV commands that are sent to the PSP. The PSP works with physical addresses, and __pa()/virt_to_phys() will not return the correct address in these cases, e.g. for a vmalloc'd pointer. At best, the bogus address will cause the command to fail, and at worst lead to system instability. While it's unlikely that callers will deliberately use a bad pointer for SEV buffers, a caller can easily use a vmalloc'd pointer unknowingly when running with CONFIG_VMAP_STACK=y as it's not obvious that putting the command buffers on the stack would be bad. The command buffers are relative small and easily fit on the stack, and the APIs to do not document that the incoming pointer must be a physically contiguous, __pa() friendly pointer. Cc: Brijesh Singh Cc: Borislav Petkov Cc: Tom Lendacky Cc: Christophe Leroy Fixes: 200664d5237f ("crypto: ccp: Add Secure Encrypted Virtualization (SEV) command support") Signed-off-by: Sean Christopherson --- drivers/crypto/ccp/sev-dev.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index ba240d33d26e..3e0d1d6922ba 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -150,6 +150,9 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret) sev = psp->sev_data; + if (data && WARN_ON_ONCE(!virt_addr_valid(data))) + return -EINVAL; + /* Get the physical address of the command buffer */ phys_lsb = data ? lower_32_bits(__psp_pa(data)) : 0; phys_msb = data ? upper_32_bits(__psp_pa(data)) : 0; From patchwork Tue Apr 6 22:49:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 416846 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT, USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E56D0C43462 for ; Tue, 6 Apr 2021 22:50:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C32F4613E2 for ; Tue, 6 Apr 2021 22:50:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344285AbhDFWu1 (ORCPT ); Tue, 6 Apr 2021 18:50:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40100 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344234AbhDFWuY (ORCPT ); Tue, 6 Apr 2021 18:50:24 -0400 Received: from mail-qv1-xf4a.google.com (mail-qv1-xf4a.google.com [IPv6:2607:f8b0:4864:20::f4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3D0F3C061763 for ; Tue, 6 Apr 2021 15:50:12 -0700 (PDT) Received: by mail-qv1-xf4a.google.com with SMTP id j10so4371059qvp.11 for ; Tue, 06 Apr 2021 15:50:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=E1A/gblkNN/6Bje/9QrJMIEH7pX9CVt+XIM7D2u/QT4=; b=k1VLrYy+geJqpko3bJBWfwTk7EFl/ntdo4+YIV6WjKWLywWZAhoCVI99Q33FIXTJwJ PRmqJeDnkiUYEUU7ndGPuSz3KmCtBoeeH7ySyVSr6sbMr1EvcB//QT+06+cnMn4FfZJ/ KNaCshRzkkcxCp6akBaQXn1jRKJ54Il9u6Plq+rdA58o1fb6yRqtR8rAUmfg3qKACgAV c7lrryjKG/h30uTEp1VyZqTgDrsfvNK0D5zj+T7p+t+aWra9t8VUgWqGk+Ex1W/AF/Qv nDU8QCFt3eokVPgAEupHKjYowpFTcL83hGHmZeT4PJUVnzNjEoiRzetiwD0yFksn9rEu 0Qvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=E1A/gblkNN/6Bje/9QrJMIEH7pX9CVt+XIM7D2u/QT4=; b=fFXTU0VqGg0rrYTOKV9krcDbeNOHsBaeE105V+CTyIgqPGrw+kKVGYCD9UpGAzzhM8 L6soet4t6YiduHbdTQK+ZLhlcVKTBXhzggA0cck1h7ivgbeyVu/gtVN9yAvMgFWN+w6x 9eI+DLD8oGyvgB9g8pDRzFR9nC8hS7Ba3V0uAMDnh152uXthNfPhmFoSwR/fk915fqVX rUnpJtb7UrkfnSp6FeILSViYpM7pLa8PHfnDZ1cs8vX2HV2o8En+kRxCupXK5pMbgduy t1s5AXt8PIcP0G3xmJyqdLvf2Jn4s84n481ta7rB6uzpJn5x20NBsi34A5hc8ZlX048Y sODg== X-Gm-Message-State: AOAM531O0uLM2Bpi3K9Dsyqjjk3mWoIGALinVUQ4yZVTUID3tBs7haOw c7xrx0PyA5vaPgLo3b87J5NKZXe5TME= X-Google-Smtp-Source: ABdhPJxaxI7VjhhziYAL29D415tAxRWY0bganDlSPJ66nRvZU20MmlqaN5wLWQj0nlMBfo2tlmwp4MwJvlM= X-Received: from seanjc798194.pdx.corp.google.com ([2620:15c:f:10:24a1:90fb:182b:777c]) (user=seanjc job=sendgmr) by 2002:a0c:b410:: with SMTP id u16mr319148qve.8.1617749411458; Tue, 06 Apr 2021 15:50:11 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 6 Apr 2021 15:49:47 -0700 In-Reply-To: <20210406224952.4177376-1-seanjc@google.com> Message-Id: <20210406224952.4177376-4-seanjc@google.com> Mime-Version: 1.0 References: <20210406224952.4177376-1-seanjc@google.com> X-Mailer: git-send-email 2.31.0.208.g409f899ff0-goog Subject: [PATCH v2 3/8] crypto: ccp: Reject SEV commands with mismatching command buffer From: Sean Christopherson To: Paolo Bonzini , Brijesh Singh , Tom Lendacky , John Allen Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, Borislav Petkov , Christophe Leroy Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org WARN on and reject SEV commands that provide a valid data pointer, but do not have a known, non-zero length. And conversely, reject commands that take a command buffer but none is provided (data is null). Aside from sanity checking input, disallowing a non-null pointer without a non-zero size will allow a future patch to cleanly handle vmalloc'd data by copying the data to an internal __pa() friendly buffer. Note, this also effectively prevents callers from using commands that have a non-zero length and are not known to the kernel. This is not an explicit goal, but arguably the side effect is a good thing from the kernel's perspective. Cc: Brijesh Singh Cc: Borislav Petkov Cc: Tom Lendacky Signed-off-by: Sean Christopherson --- drivers/crypto/ccp/sev-dev.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index 3e0d1d6922ba..47a372e07223 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -141,6 +141,7 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret) struct sev_device *sev; unsigned int phys_lsb, phys_msb; unsigned int reg, ret = 0; + int buf_len; if (!psp || !psp->sev_data) return -ENODEV; @@ -150,6 +151,10 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret) sev = psp->sev_data; + buf_len = sev_cmd_buffer_len(cmd); + if (WARN_ON_ONCE(!data != !buf_len)) + return -EINVAL; + if (data && WARN_ON_ONCE(!virt_addr_valid(data))) return -EINVAL; @@ -161,7 +166,7 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret) cmd, phys_msb, phys_lsb, psp_timeout); print_hex_dump_debug("(in): ", DUMP_PREFIX_OFFSET, 16, 2, data, - sev_cmd_buffer_len(cmd), false); + buf_len, false); iowrite32(phys_lsb, sev->io_regs + sev->vdata->cmdbuff_addr_lo_reg); iowrite32(phys_msb, sev->io_regs + sev->vdata->cmdbuff_addr_hi_reg); @@ -197,7 +202,7 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret) } print_hex_dump_debug("(out): ", DUMP_PREFIX_OFFSET, 16, 2, data, - sev_cmd_buffer_len(cmd), false); + buf_len, false); return ret; } From patchwork Tue Apr 6 22:49:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 416057 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5B8D6C433B4 for ; Tue, 6 Apr 2021 22:50:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 35F79613D8 for ; Tue, 6 Apr 2021 22:50:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344301AbhDFWu2 (ORCPT ); Tue, 6 Apr 2021 18:50:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40112 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344248AbhDFWuZ (ORCPT ); Tue, 6 Apr 2021 18:50:25 -0400 Received: from mail-qt1-x849.google.com (mail-qt1-x849.google.com [IPv6:2607:f8b0:4864:20::849]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6AB99C0613D8 for ; Tue, 6 Apr 2021 15:50:14 -0700 (PDT) Received: by mail-qt1-x849.google.com with SMTP id m11so10982824qtx.19 for ; Tue, 06 Apr 2021 15:50:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=qeSDdPOEtLNZrGRyxSYQgQknQgwqkWb9I9sk4ziJ/OY=; b=Ga8o+6478WTe8xCs6ZDLhRgmVbg0E75BCEhnCWjj7i5U/bRBxcG3TKKGDrnjWjQPhP YlUD2J8mbYE0aHwukhb+JIRrQr4uORpXru4RoYbEdu8NU62S1heGZuqTiaCjr7UohHYk ToF1rDvEQtdYCR8p6CzPjPKYPK3XwRtg1SUO0aa5WuygwCg5uXS0CeGeNj8BX1NgQTaT nwiBrJWUHnUjmQPWv08jlxXLAjdyEq6b/iVLt/lXQlPp9QZrBxI/eVPurY+5wDiKXfDh HpZLNqRSD+BcRELE6rYzPq2k9kteRJIKsqYuvn3KraV1ETtRIj6pZaTW0hOHG4v66E17 jObQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=qeSDdPOEtLNZrGRyxSYQgQknQgwqkWb9I9sk4ziJ/OY=; b=o/2tvF2bOz5LNDLIlTVPQDe2sL1lk1UbZ+0N26e2aAvX9kASG68Y96p+jXfFlSGzeM Putz/mClDwgtidJjLGsF/fwK6UmjxCZoSbOkf9XUK3vq1dsr5HWJIAyNCwJvmigKpoC2 456Jih1nK0od3yIc7miy6U4wWSeBd5TD6BKU4oHI4YFPs5af1xB3ZAc36PuvZObGWXmO d0yzK75eYRKaP6cMW3LAmrhnk3Uo2WNOUBDuujMqnf9uOkXEjOuZJ4yYTEQwQ9yvVw8l UApj9i8Y4folHRj/5aH1ZOYutcGk0vsFvpunpcvn9pWKOBrKTyzzpsmSOTMra0iz4/C/ zQ6A== X-Gm-Message-State: AOAM533QvgErMlETg7ZG0CyWSZytftyQnGg/taLz1Dres4o5VkgMWmgz tjjOipjQRnEAE8J6ru5EO+TwRYwpcfw= X-Google-Smtp-Source: ABdhPJyIcg9FGDhdO9rpoL2pPltZjsRaVybBMXUirh1bVIlL7/QgG8RFL7dOmXOb+OkSJdLe0/L4GoYHs3A= X-Received: from seanjc798194.pdx.corp.google.com ([2620:15c:f:10:24a1:90fb:182b:777c]) (user=seanjc job=sendgmr) by 2002:a05:6214:7e4:: with SMTP id bp4mr279190qvb.5.1617749413669; Tue, 06 Apr 2021 15:50:13 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 6 Apr 2021 15:49:48 -0700 In-Reply-To: <20210406224952.4177376-1-seanjc@google.com> Message-Id: <20210406224952.4177376-5-seanjc@google.com> Mime-Version: 1.0 References: <20210406224952.4177376-1-seanjc@google.com> X-Mailer: git-send-email 2.31.0.208.g409f899ff0-goog Subject: [PATCH v2 4/8] crypto: ccp: Play nice with vmalloc'd memory for SEV command structs From: Sean Christopherson To: Paolo Bonzini , Brijesh Singh , Tom Lendacky , John Allen Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, Borislav Petkov , Christophe Leroy Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org Copy the incoming @data comman to an internal buffer so that callers can put SEV command buffers on the stack without running afoul of CONFIG_VMAP_STACK=y, i.e. without bombing on vmalloc'd pointers. As of today, the largest supported command takes a 68 byte buffer, i.e. pretty much every command can be put on the stack. Because sev_cmd_mutex is held for the entirety of a transaction, only a single bounce buffer is required. Use the internal buffer unconditionally, as the majority of in-kernel users will soon switch to using the stack. At that point, checking virt_addr_valid() becomes (negligible) overhead in most cases, and supporting both paths slightly increases complexity. Since the commands are all quite small, the cost of the copies is insignificant compared to the latency of communicating with the PSP. Allocate a full page for the buffer as opportunistic preparation for SEV-SNP, which requires the command buffer to be in firmware state for commands that trigger memory writes from the PSP firmware. Using a full page now will allow SEV-SNP support to simply transition the page as needed. Cc: Brijesh Singh Cc: Borislav Petkov Cc: Tom Lendacky Cc: Christophe Leroy Signed-off-by: Sean Christopherson --- drivers/crypto/ccp/sev-dev.c | 28 +++++++++++++++++++++++----- drivers/crypto/ccp/sev-dev.h | 2 ++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index 47a372e07223..4aedbdaffe90 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -155,12 +155,17 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret) if (WARN_ON_ONCE(!data != !buf_len)) return -EINVAL; - if (data && WARN_ON_ONCE(!virt_addr_valid(data))) - return -EINVAL; + /* + * Copy the incoming data to driver's scratch buffer as __pa() will not + * work for some memory, e.g. vmalloc'd addresses, and @data may not be + * physically contiguous. + */ + if (data) + memcpy(sev->cmd_buf, data, buf_len); /* Get the physical address of the command buffer */ - phys_lsb = data ? lower_32_bits(__psp_pa(data)) : 0; - phys_msb = data ? upper_32_bits(__psp_pa(data)) : 0; + phys_lsb = data ? lower_32_bits(__psp_pa(sev->cmd_buf)) : 0; + phys_msb = data ? upper_32_bits(__psp_pa(sev->cmd_buf)) : 0; dev_dbg(sev->dev, "sev command id %#x buffer 0x%08x%08x timeout %us\n", cmd, phys_msb, phys_lsb, psp_timeout); @@ -204,6 +209,13 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret) print_hex_dump_debug("(out): ", DUMP_PREFIX_OFFSET, 16, 2, data, buf_len, false); + /* + * Copy potential output from the PSP back to data. Do this even on + * failure in case the caller wants to glean something from the error. + */ + if (data) + memcpy(data, sev->cmd_buf, buf_len); + return ret; } @@ -984,6 +996,10 @@ int sev_dev_init(struct psp_device *psp) if (!sev) goto e_err; + sev->cmd_buf = (void *)devm_get_free_pages(dev, GFP_KERNEL, 0); + if (!sev->cmd_buf) + goto e_sev; + psp->sev_data = sev; sev->dev = dev; @@ -995,7 +1011,7 @@ int sev_dev_init(struct psp_device *psp) if (!sev->vdata) { ret = -ENODEV; dev_err(dev, "sev: missing driver data\n"); - goto e_sev; + goto e_buf; } psp_set_sev_irq_handler(psp, sev_irq_handler, sev); @@ -1010,6 +1026,8 @@ int sev_dev_init(struct psp_device *psp) e_irq: psp_clear_sev_irq_handler(psp); +e_buf: + devm_free_pages(dev, (unsigned long)sev->cmd_buf); e_sev: devm_kfree(dev, sev); e_err: diff --git a/drivers/crypto/ccp/sev-dev.h b/drivers/crypto/ccp/sev-dev.h index dd5c4fe82914..e1572f408577 100644 --- a/drivers/crypto/ccp/sev-dev.h +++ b/drivers/crypto/ccp/sev-dev.h @@ -52,6 +52,8 @@ struct sev_device { u8 api_major; u8 api_minor; u8 build; + + void *cmd_buf; }; int sev_dev_init(struct psp_device *psp); From patchwork Tue Apr 6 22:49:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 416845 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CFC15C433B4 for ; Tue, 6 Apr 2021 22:50:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9DE85613D3 for ; Tue, 6 Apr 2021 22:50:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344443AbhDFWud (ORCPT ); Tue, 6 Apr 2021 18:50:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40098 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344211AbhDFWuZ (ORCPT ); Tue, 6 Apr 2021 18:50:25 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E6F46C06175F for ; Tue, 6 Apr 2021 15:50:16 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id w9so21946737ybw.7 for ; Tue, 06 Apr 2021 15:50:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=KV8GfpQpTpZiH9kgk6yjg0OW0xYFz416RtlhJj6iD3k=; b=KliXWp2g9Qy94K28mZN3A9edJ79cTeJZGPIT/dvVPG3nEZODDUlMty1dxIQkzPZVEq IejkcTASBjb+WMZeH44zaRuAjFaZVIMuGhu7on2VJJYY+bNLF/Apuq4bRuOmBVL67atQ YLot98CuvP2rYMp9cm0RdHAP4ekEqLDiG13Rni4yaK13/yGSLQyUNAO/fTg4THwyFmXX uSKH1OLuEKSA7QfoAimnzYpqjRYNnrysg0AzGoEpGIpGHHGBQLj00qNs8Vb/K1J7bqA1 3krOcnpp3o9zHUEdQTjLrSPJdaELEDLB6iTLoVRaDsZ+UiYg35XzBr7LA5bx23Oia9Ex WCiQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=KV8GfpQpTpZiH9kgk6yjg0OW0xYFz416RtlhJj6iD3k=; b=NnFTA3XRXNyBAaD60qDRpRi4IO+cMZiMrga7MAgCu4mKuQdBQJxgj5YJDirAeQRUCf Ql5OJTXlgR3hZDvONHtm9iWdbnIyDcDPyIFeaGMJ0RJSzgBjTsLoItFY9fQHP95pLpcA /estpGAf6+BHfRRlnkCYYAPO+sozknp/d3YkpqlnYrJp3JEPVOUH60kdb9uoy/8AXl7N gHuUUvAbnGJRxwNrOutG//bLSXZ8iH5QBdroazFAyDhn9nd4SNeh7yueOwFD/r2BGLm+ GGNioltu9Vtk1S+aSRA5MwRBqonrFq6BOis/7as+cKn0faaZ5Ip2nQhuGyi+4m1VJmIN hC2w== X-Gm-Message-State: AOAM530OKBAU5dej4WZ/AVtqErk8GLWfz5XQH8E476EvH8UfHEd0J6ca dTrcnK7HsV4SGtXJJnu0iyb21TlLg6U= X-Google-Smtp-Source: ABdhPJy9XGKAT95aAkCt7uMojqdd8CgerWE4Lz4pLzTBfTrY8EHhpYRnvnE0j16oGynVgrxBClvlecyjA0w= X-Received: from seanjc798194.pdx.corp.google.com ([2620:15c:f:10:24a1:90fb:182b:777c]) (user=seanjc job=sendgmr) by 2002:a25:da44:: with SMTP id n65mr545254ybf.68.1617749416164; Tue, 06 Apr 2021 15:50:16 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 6 Apr 2021 15:49:49 -0700 In-Reply-To: <20210406224952.4177376-1-seanjc@google.com> Message-Id: <20210406224952.4177376-6-seanjc@google.com> Mime-Version: 1.0 References: <20210406224952.4177376-1-seanjc@google.com> X-Mailer: git-send-email 2.31.0.208.g409f899ff0-goog Subject: [PATCH v2 5/8] crypto: ccp: Use the stack for small SEV command buffers From: Sean Christopherson To: Paolo Bonzini , Brijesh Singh , Tom Lendacky , John Allen Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, Borislav Petkov , Christophe Leroy Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org For commands with small input/output buffers, use the local stack to "allocate" the structures used to communicate with the PSP. Now that __sev_do_cmd_locked() gracefully handles vmalloc'd buffers, there's no reason to avoid using the stack, e.g. CONFIG_VMAP_STACK=y will just work. Signed-off-by: Sean Christopherson --- drivers/crypto/ccp/sev-dev.c | 122 ++++++++++++++--------------------- 1 file changed, 47 insertions(+), 75 deletions(-) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index 4aedbdaffe90..bb0d6de071e6 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -396,7 +396,7 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable) { struct sev_device *sev = psp_master->sev_data; struct sev_user_data_pek_csr input; - struct sev_data_pek_csr *data; + struct sev_data_pek_csr data; void __user *input_address; void *blob = NULL; int ret; @@ -407,29 +407,24 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable) if (copy_from_user(&input, (void __user *)argp->data, sizeof(input))) return -EFAULT; - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; - /* userspace wants to query CSR length */ - if (!input.address || !input.length) + if (!input.address || !input.length) { + data.address = 0; + data.len = 0; goto cmd; + } /* allocate a physically contiguous buffer to store the CSR blob */ input_address = (void __user *)input.address; - if (input.length > SEV_FW_BLOB_MAX_SIZE) { - ret = -EFAULT; - goto e_free; - } + if (input.length > SEV_FW_BLOB_MAX_SIZE) + return -EFAULT; blob = kmalloc(input.length, GFP_KERNEL); - if (!blob) { - ret = -ENOMEM; - goto e_free; - } + if (!blob) + return -ENOMEM; - data->address = __psp_pa(blob); - data->len = input.length; + data.address = __psp_pa(blob); + data.len = input.length; cmd: if (sev->state == SEV_STATE_UNINIT) { @@ -438,10 +433,10 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable) goto e_free_blob; } - ret = __sev_do_cmd_locked(SEV_CMD_PEK_CSR, data, &argp->error); + ret = __sev_do_cmd_locked(SEV_CMD_PEK_CSR, &data, &argp->error); /* If we query the CSR length, FW responded with expected data. */ - input.length = data->len; + input.length = data.len; if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) { ret = -EFAULT; @@ -455,8 +450,6 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable) e_free_blob: kfree(blob); -e_free: - kfree(data); return ret; } @@ -588,7 +581,7 @@ static int sev_ioctl_do_pek_import(struct sev_issue_cmd *argp, bool writable) { struct sev_device *sev = psp_master->sev_data; struct sev_user_data_pek_cert_import input; - struct sev_data_pek_cert_import *data; + struct sev_data_pek_cert_import data; void *pek_blob, *oca_blob; int ret; @@ -598,19 +591,14 @@ static int sev_ioctl_do_pek_import(struct sev_issue_cmd *argp, bool writable) if (copy_from_user(&input, (void __user *)argp->data, sizeof(input))) return -EFAULT; - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; - /* copy PEK certificate blobs from userspace */ pek_blob = psp_copy_user_blob(input.pek_cert_address, input.pek_cert_len); - if (IS_ERR(pek_blob)) { - ret = PTR_ERR(pek_blob); - goto e_free; - } + if (IS_ERR(pek_blob)) + return PTR_ERR(pek_blob); - data->pek_cert_address = __psp_pa(pek_blob); - data->pek_cert_len = input.pek_cert_len; + data.reserved = 0; + data.pek_cert_address = __psp_pa(pek_blob); + data.pek_cert_len = input.pek_cert_len; /* copy PEK certificate blobs from userspace */ oca_blob = psp_copy_user_blob(input.oca_cert_address, input.oca_cert_len); @@ -619,8 +607,8 @@ static int sev_ioctl_do_pek_import(struct sev_issue_cmd *argp, bool writable) goto e_free_pek; } - data->oca_cert_address = __psp_pa(oca_blob); - data->oca_cert_len = input.oca_cert_len; + data.oca_cert_address = __psp_pa(oca_blob); + data.oca_cert_len = input.oca_cert_len; /* If platform is not in INIT state then transition it to INIT */ if (sev->state != SEV_STATE_INIT) { @@ -629,21 +617,19 @@ static int sev_ioctl_do_pek_import(struct sev_issue_cmd *argp, bool writable) goto e_free_oca; } - ret = __sev_do_cmd_locked(SEV_CMD_PEK_CERT_IMPORT, data, &argp->error); + ret = __sev_do_cmd_locked(SEV_CMD_PEK_CERT_IMPORT, &data, &argp->error); e_free_oca: kfree(oca_blob); e_free_pek: kfree(pek_blob); -e_free: - kfree(data); return ret; } static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp) { struct sev_user_data_get_id2 input; - struct sev_data_get_id *data; + struct sev_data_get_id data; void __user *input_address; void *id_blob = NULL; int ret; @@ -657,28 +643,25 @@ static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp) input_address = (void __user *)input.address; - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; - if (input.address && input.length) { id_blob = kmalloc(input.length, GFP_KERNEL); - if (!id_blob) { - kfree(data); + if (!id_blob) return -ENOMEM; - } - data->address = __psp_pa(id_blob); - data->len = input.length; + data.address = __psp_pa(id_blob); + data.len = input.length; + } else { + data.address = 0; + data.len = 0; } - ret = __sev_do_cmd_locked(SEV_CMD_GET_ID, data, &argp->error); + ret = __sev_do_cmd_locked(SEV_CMD_GET_ID, &data, &argp->error); /* * Firmware will return the length of the ID value (either the minimum * required length or the actual length written), return it to the user. */ - input.length = data->len; + input.length = data.len; if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) { ret = -EFAULT; @@ -686,7 +669,7 @@ static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp) } if (id_blob) { - if (copy_to_user(input_address, id_blob, data->len)) { + if (copy_to_user(input_address, id_blob, data.len)) { ret = -EFAULT; goto e_free; } @@ -694,7 +677,6 @@ static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp) e_free: kfree(id_blob); - kfree(data); return ret; } @@ -744,7 +726,7 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable) struct sev_device *sev = psp_master->sev_data; struct sev_user_data_pdh_cert_export input; void *pdh_blob = NULL, *cert_blob = NULL; - struct sev_data_pdh_cert_export *data; + struct sev_data_pdh_cert_export data; void __user *input_cert_chain_address; void __user *input_pdh_cert_address; int ret; @@ -762,9 +744,7 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable) if (copy_from_user(&input, (void __user *)argp->data, sizeof(input))) return -EFAULT; - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; + memset(&data, 0, sizeof(data)); /* Userspace wants to query the certificate length. */ if (!input.pdh_cert_address || @@ -776,25 +756,19 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable) input_cert_chain_address = (void __user *)input.cert_chain_address; /* Allocate a physically contiguous buffer to store the PDH blob. */ - if (input.pdh_cert_len > SEV_FW_BLOB_MAX_SIZE) { - ret = -EFAULT; - goto e_free; - } + if (input.pdh_cert_len > SEV_FW_BLOB_MAX_SIZE) + return -EFAULT; /* Allocate a physically contiguous buffer to store the cert chain blob. */ - if (input.cert_chain_len > SEV_FW_BLOB_MAX_SIZE) { - ret = -EFAULT; - goto e_free; - } + if (input.cert_chain_len > SEV_FW_BLOB_MAX_SIZE) + return -EFAULT; pdh_blob = kmalloc(input.pdh_cert_len, GFP_KERNEL); - if (!pdh_blob) { - ret = -ENOMEM; - goto e_free; - } + if (!pdh_blob) + return -ENOMEM; - data->pdh_cert_address = __psp_pa(pdh_blob); - data->pdh_cert_len = input.pdh_cert_len; + data.pdh_cert_address = __psp_pa(pdh_blob); + data.pdh_cert_len = input.pdh_cert_len; cert_blob = kmalloc(input.cert_chain_len, GFP_KERNEL); if (!cert_blob) { @@ -802,15 +776,15 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable) goto e_free_pdh; } - data->cert_chain_address = __psp_pa(cert_blob); - data->cert_chain_len = input.cert_chain_len; + data.cert_chain_address = __psp_pa(cert_blob); + data.cert_chain_len = input.cert_chain_len; cmd: - ret = __sev_do_cmd_locked(SEV_CMD_PDH_CERT_EXPORT, data, &argp->error); + ret = __sev_do_cmd_locked(SEV_CMD_PDH_CERT_EXPORT, &data, &argp->error); /* If we query the length, FW responded with expected data. */ - input.cert_chain_len = data->cert_chain_len; - input.pdh_cert_len = data->pdh_cert_len; + input.cert_chain_len = data.cert_chain_len; + input.pdh_cert_len = data.pdh_cert_len; if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) { ret = -EFAULT; @@ -835,8 +809,6 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable) kfree(cert_blob); e_free_pdh: kfree(pdh_blob); -e_free: - kfree(data); return ret; } From patchwork Tue Apr 6 22:49:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 416056 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C01AAC433ED for ; Tue, 6 Apr 2021 22:50:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8ABCD613D5 for ; Tue, 6 Apr 2021 22:50:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344494AbhDFWuh (ORCPT ); Tue, 6 Apr 2021 18:50:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40104 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344279AbhDFWu1 (ORCPT ); Tue, 6 Apr 2021 18:50:27 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0AABAC061761 for ; Tue, 6 Apr 2021 15:50:19 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id x7so8495949ybs.10 for ; Tue, 06 Apr 2021 15:50:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=Oh9gQc9FxkOOr6m1SlSa7AzCZn8dzyUsrSaGNuqfpq4=; b=UXREyiJYnQipVxQ+Qy+sDhopb/Ly+Ghq7LDGBf8ODRndoTCOmZF30p4tHaYsRfLk0Q oWntMPoIzgJfWBKYTGKFlysQqT5HiT0T+xDHSVsARZDzvl2qHxsqARzXEXlxqq7kTWe8 Ogwa4InQErV/XCC19e02tsvPCaHFrxtIWkhmqWIhYbjnosdu1cgCB88XoTDP1PukHHfl cDXr5pRM8nufyTEqZ8OTok82BSI+Nz5t7QTSzRMzrR8PzMWbkQg8TJRd1Xp5M9m1IkgO chRQ5c4NFrCgloZjliO/LX3Ve/W/PPL2jLku9kAMNd0sq5AmxwuEVQpcHIPUheKv79iL gfWA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=Oh9gQc9FxkOOr6m1SlSa7AzCZn8dzyUsrSaGNuqfpq4=; b=H480Fgg764g2236+fVX7Cq21TAT+xkYF7Kd2xyGH6o3TC7qN/uneRw99N+5Omb49wy 4P7I9jfEVmUzCQnlp6F9at9oEFaxKcnNXnmyt8ileWIh1OU06+vh8etyjpgnXd11/aC3 +fLzuv7lFsmDU5VQtyKJdCIlRF/Z3ZbGt+tvlNiVW4XZYZmhL5/ByC1gL5o80NV2XM11 XDcLenMnBfwen34tw4Bi41DGHao0BmU7Rw3W1/RWszLCyUh8FxZ/DHj7o82JmyWyjzK5 UWRfrAe++rQiuKssSvjTB1HxVL7aEVE9EqZx8YgpIRek6FrmKIhfjScKWfQH+meCRLP/ w/yA== X-Gm-Message-State: AOAM532sHUC74sUDW7Hb1zMjoV2L3i5v7gLk9g8xuG8vKZVJ1WnSxuG3 uSW27PaF64LVbJrMkhL26mDm/jkiLvU= X-Google-Smtp-Source: ABdhPJzy50MVzew6CiucoLtIec+dAe/cp5LYPaMjWfzHEfKrfAPLQiTmEDhRPyt08PaWtXLKFnHEFDKhbdY= X-Received: from seanjc798194.pdx.corp.google.com ([2620:15c:f:10:24a1:90fb:182b:777c]) (user=seanjc job=sendgmr) by 2002:a25:e004:: with SMTP id x4mr436617ybg.499.1617749418312; Tue, 06 Apr 2021 15:50:18 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 6 Apr 2021 15:49:50 -0700 In-Reply-To: <20210406224952.4177376-1-seanjc@google.com> Message-Id: <20210406224952.4177376-7-seanjc@google.com> Mime-Version: 1.0 References: <20210406224952.4177376-1-seanjc@google.com> X-Mailer: git-send-email 2.31.0.208.g409f899ff0-goog Subject: [PATCH v2 6/8] crypto: ccp: Use the stack and common buffer for status commands From: Sean Christopherson To: Paolo Bonzini , Brijesh Singh , Tom Lendacky , John Allen Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, Borislav Petkov , Christophe Leroy Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org Drop the dedicated status_cmd_buf and instead use a local variable for PLATFORM_STATUS. Now that the low level helper uses an internal buffer for all commands, using the stack for the upper layers is safe even when running with CONFIG_VMAP_STACK=y. Signed-off-by: Sean Christopherson --- drivers/crypto/ccp/sev-dev.c | 27 ++++++++++++--------------- drivers/crypto/ccp/sev-dev.h | 1 - 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index bb0d6de071e6..e54774b0d637 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -315,15 +315,14 @@ static int sev_platform_shutdown(int *error) static int sev_get_platform_state(int *state, int *error) { - struct sev_device *sev = psp_master->sev_data; + struct sev_user_data_status data; int rc; - rc = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, - &sev->status_cmd_buf, error); + rc = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, &data, error); if (rc) return rc; - *state = sev->status_cmd_buf.state; + *state = data.state; return rc; } @@ -361,15 +360,14 @@ static int sev_ioctl_do_reset(struct sev_issue_cmd *argp, bool writable) static int sev_ioctl_do_platform_status(struct sev_issue_cmd *argp) { - struct sev_device *sev = psp_master->sev_data; - struct sev_user_data_status *data = &sev->status_cmd_buf; + struct sev_user_data_status data; int ret; - ret = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, data, &argp->error); + ret = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, &data, &argp->error); if (ret) return ret; - if (copy_to_user((void __user *)argp->data, data, sizeof(*data))) + if (copy_to_user((void __user *)argp->data, &data, sizeof(data))) ret = -EFAULT; return ret; @@ -469,21 +467,20 @@ EXPORT_SYMBOL_GPL(psp_copy_user_blob); static int sev_get_api_version(void) { struct sev_device *sev = psp_master->sev_data; - struct sev_user_data_status *status; + struct sev_user_data_status status; int error = 0, ret; - status = &sev->status_cmd_buf; - ret = sev_platform_status(status, &error); + ret = sev_platform_status(&status, &error); if (ret) { dev_err(sev->dev, "SEV: failed to get status. Error: %#x\n", error); return 1; } - sev->api_major = status->api_major; - sev->api_minor = status->api_minor; - sev->build = status->build; - sev->state = status->state; + sev->api_major = status.api_major; + sev->api_minor = status.api_minor; + sev->build = status.build; + sev->state = status.state; return 0; } diff --git a/drivers/crypto/ccp/sev-dev.h b/drivers/crypto/ccp/sev-dev.h index e1572f408577..0fd21433f627 100644 --- a/drivers/crypto/ccp/sev-dev.h +++ b/drivers/crypto/ccp/sev-dev.h @@ -46,7 +46,6 @@ struct sev_device { unsigned int int_rcvd; wait_queue_head_t int_queue; struct sev_misc_dev *misc; - struct sev_user_data_status status_cmd_buf; struct sev_data_init init_cmd_buf; u8 api_major; From patchwork Tue Apr 6 22:49:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 416844 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0B5FEC433B4 for ; Tue, 6 Apr 2021 22:50:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C6E96613D4 for ; Tue, 6 Apr 2021 22:50:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344636AbhDFWuz (ORCPT ); Tue, 6 Apr 2021 18:50:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40142 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344323AbhDFWua (ORCPT ); Tue, 6 Apr 2021 18:50:30 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5C56DC0613D8 for ; Tue, 6 Apr 2021 15:50:21 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id x22so21770895ybi.1 for ; Tue, 06 Apr 2021 15:50:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=csTFUpsRawa07wcmPlEmUE8R3c/8ED1fSyaPMVbY1/I=; b=ff3Qi8XlXaAP8Ho2RSWqRgeiGlfya7kplhOvaksEp9BmY37Y78knjcMBQPMdr0bkdj i6mofTDVD21bxrCn2qrsF6/ZM5F6AG/PtOnjbNgjZjDFFTzA+pp5DQUFL91v9mwNdKrg 9KlR5eJb1m25NsJhf18rWWy1y5RCmIEiN0Q3nokwOo0bcVMPIQFOdbEgypQ3VGVC4A88 Y20jYwiqSnMhAoyDCjMaSoxIHssFJ/hRvxuS93qqIMdYAUmgnLvhW5iGZWzGlmi1zT5q iYu8Q/4JfbkQ414gV4CUnQpHfmJERzjFRjHGL+lAH0/nBivSMrJvmW6JoTItq6Du7w4E IYBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=csTFUpsRawa07wcmPlEmUE8R3c/8ED1fSyaPMVbY1/I=; b=lGhNrs5OAZffNfP0F7XT7+iSKqaCBKNUBKynZa9bNgf/cc4vdJU3rELXZlubmNs82h iEFbSlbxAvS5kMTFpNVJ8+llD37B2vlEs4Kpa3Y7qOOiNL0vPayK2shOsO0s9ev7MahV 8CKZA2Qnf3YDY2KrSx5HY/mJfQLz/TD1dHphdRlgvL2081O+rLbYp2QMmaprFUm8uusm iUj1e2vajZ1UGzaq/qkICl/iwc4fSbNJpi0fu13YBVf2guTACYBh1DA7ja8A81Ndh+Av NIYl/l2QD0B+y68zHGcRWuHhnTt5BmK6toEaqpbbDAb9bpCoF6+31aa7Kdgkg9TWDedR zsGQ== X-Gm-Message-State: AOAM532ZN61aZVLwwS3UHvhxi3a0edbP0v66itN0SyeGcNd3XEi0hbmG GqqQoEJOuX3RzsRHkro+aFvxstO59FE= X-Google-Smtp-Source: ABdhPJzA/KxCkl9GQmyOLhOkCUX3BBpDSU1ecrOweyAwp+jRB/OA9VvOLBWyuq9yZ7lYhKOxmUTIcFoJpfQ= X-Received: from seanjc798194.pdx.corp.google.com ([2620:15c:f:10:24a1:90fb:182b:777c]) (user=seanjc job=sendgmr) by 2002:a25:4cc6:: with SMTP id z189mr475227yba.453.1617749420597; Tue, 06 Apr 2021 15:50:20 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 6 Apr 2021 15:49:51 -0700 In-Reply-To: <20210406224952.4177376-1-seanjc@google.com> Message-Id: <20210406224952.4177376-8-seanjc@google.com> Mime-Version: 1.0 References: <20210406224952.4177376-1-seanjc@google.com> X-Mailer: git-send-email 2.31.0.208.g409f899ff0-goog Subject: [PATCH v2 7/8] crypto: ccp: Use the stack and common buffer for INIT command From: Sean Christopherson To: Paolo Bonzini , Brijesh Singh , Tom Lendacky , John Allen Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, Borislav Petkov , Christophe Leroy Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org Drop the dedicated init_cmd_buf and instead use a local variable. Now that the low level helper uses an internal buffer for all commands, using the stack for the upper layers is safe even when running with CONFIG_VMAP_STACK=y. Signed-off-by: Sean Christopherson --- drivers/crypto/ccp/sev-dev.c | 10 ++++++---- drivers/crypto/ccp/sev-dev.h | 1 - 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index e54774b0d637..9ff28df03030 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -233,6 +233,7 @@ static int sev_do_cmd(int cmd, void *data, int *psp_ret) static int __sev_platform_init_locked(int *error) { struct psp_device *psp = psp_master; + struct sev_data_init data; struct sev_device *sev; int rc = 0; @@ -244,6 +245,7 @@ static int __sev_platform_init_locked(int *error) if (sev->state == SEV_STATE_INIT) return 0; + memset(&data, 0, sizeof(data)); if (sev_es_tmr) { u64 tmr_pa; @@ -253,12 +255,12 @@ static int __sev_platform_init_locked(int *error) */ tmr_pa = __pa(sev_es_tmr); - sev->init_cmd_buf.flags |= SEV_INIT_FLAGS_SEV_ES; - sev->init_cmd_buf.tmr_address = tmr_pa; - sev->init_cmd_buf.tmr_len = SEV_ES_TMR_SIZE; + data.flags |= SEV_INIT_FLAGS_SEV_ES; + data.tmr_address = tmr_pa; + data.tmr_len = SEV_ES_TMR_SIZE; } - rc = __sev_do_cmd_locked(SEV_CMD_INIT, &sev->init_cmd_buf, error); + rc = __sev_do_cmd_locked(SEV_CMD_INIT, &data, error); if (rc) return rc; diff --git a/drivers/crypto/ccp/sev-dev.h b/drivers/crypto/ccp/sev-dev.h index 0fd21433f627..666c21eb81ab 100644 --- a/drivers/crypto/ccp/sev-dev.h +++ b/drivers/crypto/ccp/sev-dev.h @@ -46,7 +46,6 @@ struct sev_device { unsigned int int_rcvd; wait_queue_head_t int_queue; struct sev_misc_dev *misc; - struct sev_data_init init_cmd_buf; u8 api_major; u8 api_minor; From patchwork Tue Apr 6 22:49:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 416055 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT, USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 37DFEC43462 for ; Tue, 6 Apr 2021 22:50:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DFA3C613EC for ; Tue, 6 Apr 2021 22:50:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344656AbhDFWu4 (ORCPT ); Tue, 6 Apr 2021 18:50:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40154 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344356AbhDFWuc (ORCPT ); Tue, 6 Apr 2021 18:50:32 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9B3D5C0613DA for ; Tue, 6 Apr 2021 15:50:23 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id q14so6672348ybk.22 for ; Tue, 06 Apr 2021 15:50:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=E+tEX+0Keq6mEUZny7PGNfi9VWWcG1wSqQSbazqbJNw=; b=cr21xwVs3neHdR4cHfz97MMweJRQoNvKx8pkp5Zq/q6ySfbwkiZTsg/s7tceMXdOea F1LSILBTyEdWNHANoWluvfVFpcbCJYMne3S8+Bodm5Qhi8I5++jwsaLTJliqCh2j/XLy Nq1/HrIG/a9xH6GMf8P9PxLtcv7auW+eMljydMvcxdWLuBGjJz/xlLilF2xhnWNCtE5B ds89B3hXS6Ep1bWpE0MpWMkbFyIjPeNVMoSAr7SwJx+VNCaqZt7PPNaoHWiQYt1c3iF7 OGXFPZyK0BnCn3M8TsAoMme7A6mK/ldrF2oCsd8Rr2XbJ6jpzA2XdJANwi9T8cJUD+mS lxlw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=E+tEX+0Keq6mEUZny7PGNfi9VWWcG1wSqQSbazqbJNw=; b=mk1Y+2M/6FJp0T3fVSBtEKsAaZH3OdF9zK+HtjtXPCqTBidGUcdFoW77fhsLi+bYyQ pWqUIV4+jQbDUuIH2q+ODFovF44sNYz6tmhha5ulsz2o7RToNQl4h25RXvb/RJjpQeAQ MilO4L9fFE3casVNlgiB8j5jV2K8GOQxdJClaa0NiD4yAkWA/TNs8w8+OUHfv6cUAQr1 4MHw8oPDPKZ9FUxz+mIPdgfU8rfwLNNzYkPsjER2nHdhVC2U59tN60Jh1ReDXabojk3K t/eyQNuC+dQb7SNkjaLlSVUVQc0x+7sIxfFB/A8BY1JbZ2mJUtTq1w0Z4AYpEQNVLvoj JkvQ== X-Gm-Message-State: AOAM533aUGme/AnhobTC7Q40OtaNTFKHsfzpB3F5oCyi3mD/fjMuLzlb M7wAbZLjBMi35NvzeJfxkxg9VtFmSUA= X-Google-Smtp-Source: ABdhPJwZ4qB3+J8/X6Al1I3ExKyMnJmu5X9FfJrLSycD89eha6Q0Ske+ByL0q666ov7j6tAMd7MhJfCUaeI= X-Received: from seanjc798194.pdx.corp.google.com ([2620:15c:f:10:24a1:90fb:182b:777c]) (user=seanjc job=sendgmr) by 2002:a25:d211:: with SMTP id j17mr450284ybg.449.1617749422840; Tue, 06 Apr 2021 15:50:22 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 6 Apr 2021 15:49:52 -0700 In-Reply-To: <20210406224952.4177376-1-seanjc@google.com> Message-Id: <20210406224952.4177376-9-seanjc@google.com> Mime-Version: 1.0 References: <20210406224952.4177376-1-seanjc@google.com> X-Mailer: git-send-email 2.31.0.208.g409f899ff0-goog Subject: [PATCH v2 8/8] KVM: SVM: Allocate SEV command structures on local stack From: Sean Christopherson To: Paolo Bonzini , Brijesh Singh , Tom Lendacky , John Allen Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, Borislav Petkov , Christophe Leroy Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org Use the local stack to "allocate" the structures used to communicate with the PSP. The largest struct used by KVM, sev_data_launch_secret, clocks in at 52 bytes, well within the realm of reasonable stack usage. The smallest structs are a mere 4 bytes, i.e. the pointer for the allocation is larger than the allocation itself. Now that the PSP driver plays nice with vmalloc pointers, putting the data on a virtually mapped stack (CONFIG_VMAP_STACK=y) will not cause explosions. Cc: Brijesh Singh Cc: Tom Lendacky Signed-off-by: Sean Christopherson --- arch/x86/kvm/svm/sev.c | 262 +++++++++++++++-------------------------- 1 file changed, 96 insertions(+), 166 deletions(-) diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 5457138c7347..316fd39c7aef 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -150,35 +150,22 @@ static void sev_asid_free(int asid) static void sev_unbind_asid(struct kvm *kvm, unsigned int handle) { - struct sev_data_decommission *decommission; - struct sev_data_deactivate *data; + struct sev_data_decommission decommission; + struct sev_data_deactivate deactivate; if (!handle) return; - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return; - - /* deactivate handle */ - data->handle = handle; + deactivate.handle = handle; /* Guard DEACTIVATE against WBINVD/DF_FLUSH used in ASID recycling */ down_read(&sev_deactivate_lock); - sev_guest_deactivate(data, NULL); + sev_guest_deactivate(&deactivate, NULL); up_read(&sev_deactivate_lock); - kfree(data); - - decommission = kzalloc(sizeof(*decommission), GFP_KERNEL); - if (!decommission) - return; - /* decommission handle */ - decommission->handle = handle; - sev_guest_decommission(decommission, NULL); - - kfree(decommission); + decommission.handle = handle; + sev_guest_decommission(&decommission, NULL); } static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp) @@ -216,19 +203,14 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp) static int sev_bind_asid(struct kvm *kvm, unsigned int handle, int *error) { - struct sev_data_activate *data; + struct sev_data_activate activate; int asid = sev_get_asid(kvm); int ret; - data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT); - if (!data) - return -ENOMEM; - /* activate ASID on the given handle */ - data->handle = handle; - data->asid = asid; - ret = sev_guest_activate(data, error); - kfree(data); + activate.handle = handle; + activate.asid = asid; + ret = sev_guest_activate(&activate, error); return ret; } @@ -258,7 +240,7 @@ static int sev_issue_cmd(struct kvm *kvm, int id, void *data, int *error) static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp) { struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; - struct sev_data_launch_start *start; + struct sev_data_launch_start start; struct kvm_sev_launch_start params; void *dh_blob, *session_blob; int *error = &argp->error; @@ -270,20 +252,16 @@ static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp) if (copy_from_user(¶ms, (void __user *)(uintptr_t)argp->data, sizeof(params))) return -EFAULT; - start = kzalloc(sizeof(*start), GFP_KERNEL_ACCOUNT); - if (!start) - return -ENOMEM; + memset(&start, 0, sizeof(start)); dh_blob = NULL; if (params.dh_uaddr) { dh_blob = psp_copy_user_blob(params.dh_uaddr, params.dh_len); - if (IS_ERR(dh_blob)) { - ret = PTR_ERR(dh_blob); - goto e_free; - } + if (IS_ERR(dh_blob)) + return PTR_ERR(dh_blob); - start->dh_cert_address = __sme_set(__pa(dh_blob)); - start->dh_cert_len = params.dh_len; + start.dh_cert_address = __sme_set(__pa(dh_blob)); + start.dh_cert_len = params.dh_len; } session_blob = NULL; @@ -294,40 +272,38 @@ static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp) goto e_free_dh; } - start->session_address = __sme_set(__pa(session_blob)); - start->session_len = params.session_len; + start.session_address = __sme_set(__pa(session_blob)); + start.session_len = params.session_len; } - start->handle = params.handle; - start->policy = params.policy; + start.handle = params.handle; + start.policy = params.policy; /* create memory encryption context */ - ret = __sev_issue_cmd(argp->sev_fd, SEV_CMD_LAUNCH_START, start, error); + ret = __sev_issue_cmd(argp->sev_fd, SEV_CMD_LAUNCH_START, &start, error); if (ret) goto e_free_session; /* Bind ASID to this guest */ - ret = sev_bind_asid(kvm, start->handle, error); + ret = sev_bind_asid(kvm, start.handle, error); if (ret) goto e_free_session; /* return handle to userspace */ - params.handle = start->handle; + params.handle = start.handle; if (copy_to_user((void __user *)(uintptr_t)argp->data, ¶ms, sizeof(params))) { - sev_unbind_asid(kvm, start->handle); + sev_unbind_asid(kvm, start.handle); ret = -EFAULT; goto e_free_session; } - sev->handle = start->handle; + sev->handle = start.handle; sev->fd = argp->sev_fd; e_free_session: kfree(session_blob); e_free_dh: kfree(dh_blob); -e_free: - kfree(start); return ret; } @@ -446,7 +422,7 @@ static int sev_launch_update_data(struct kvm *kvm, struct kvm_sev_cmd *argp) unsigned long vaddr, vaddr_end, next_vaddr, npages, pages, size, i; struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; struct kvm_sev_launch_update_data params; - struct sev_data_launch_update_data *data; + struct sev_data_launch_update_data data; struct page **inpages; int ret; @@ -456,20 +432,14 @@ static int sev_launch_update_data(struct kvm *kvm, struct kvm_sev_cmd *argp) if (copy_from_user(¶ms, (void __user *)(uintptr_t)argp->data, sizeof(params))) return -EFAULT; - data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT); - if (!data) - return -ENOMEM; - vaddr = params.uaddr; size = params.len; vaddr_end = vaddr + size; /* Lock the user memory. */ inpages = sev_pin_memory(kvm, vaddr, size, &npages, 1); - if (IS_ERR(inpages)) { - ret = PTR_ERR(inpages); - goto e_free; - } + if (IS_ERR(inpages)) + return PTR_ERR(inpages); /* * Flush (on non-coherent CPUs) before LAUNCH_UPDATE encrypts pages in @@ -477,6 +447,9 @@ static int sev_launch_update_data(struct kvm *kvm, struct kvm_sev_cmd *argp) */ sev_clflush_pages(inpages, npages); + data.reserved = 0; + data.handle = sev->handle; + for (i = 0; vaddr < vaddr_end; vaddr = next_vaddr, i += pages) { int offset, len; @@ -491,10 +464,9 @@ static int sev_launch_update_data(struct kvm *kvm, struct kvm_sev_cmd *argp) len = min_t(size_t, ((pages * PAGE_SIZE) - offset), size); - data->handle = sev->handle; - data->len = len; - data->address = __sme_page_pa(inpages[i]) + offset; - ret = sev_issue_cmd(kvm, SEV_CMD_LAUNCH_UPDATE_DATA, data, &argp->error); + data.len = len; + data.address = __sme_page_pa(inpages[i]) + offset; + ret = sev_issue_cmd(kvm, SEV_CMD_LAUNCH_UPDATE_DATA, &data, &argp->error); if (ret) goto e_unpin; @@ -510,8 +482,6 @@ static int sev_launch_update_data(struct kvm *kvm, struct kvm_sev_cmd *argp) } /* unlock the user pages */ sev_unpin_memory(kvm, inpages, npages); -e_free: - kfree(data); return ret; } @@ -563,16 +533,14 @@ static int sev_es_sync_vmsa(struct vcpu_svm *svm) static int sev_launch_update_vmsa(struct kvm *kvm, struct kvm_sev_cmd *argp) { struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; - struct sev_data_launch_update_vmsa *vmsa; + struct sev_data_launch_update_vmsa vmsa; struct kvm_vcpu *vcpu; int i, ret; if (!sev_es_guest(kvm)) return -ENOTTY; - vmsa = kzalloc(sizeof(*vmsa), GFP_KERNEL); - if (!vmsa) - return -ENOMEM; + vmsa.reserved = 0; kvm_for_each_vcpu(i, vcpu, kvm) { struct vcpu_svm *svm = to_svm(vcpu); @@ -580,7 +548,7 @@ static int sev_launch_update_vmsa(struct kvm *kvm, struct kvm_sev_cmd *argp) /* Perform some pre-encryption checks against the VMSA */ ret = sev_es_sync_vmsa(svm); if (ret) - goto e_free; + return ret; /* * The LAUNCH_UPDATE_VMSA command will perform in-place @@ -590,27 +558,25 @@ static int sev_launch_update_vmsa(struct kvm *kvm, struct kvm_sev_cmd *argp) */ clflush_cache_range(svm->vmsa, PAGE_SIZE); - vmsa->handle = sev->handle; - vmsa->address = __sme_pa(svm->vmsa); - vmsa->len = PAGE_SIZE; - ret = sev_issue_cmd(kvm, SEV_CMD_LAUNCH_UPDATE_VMSA, vmsa, + vmsa.handle = sev->handle; + vmsa.address = __sme_pa(svm->vmsa); + vmsa.len = PAGE_SIZE; + ret = sev_issue_cmd(kvm, SEV_CMD_LAUNCH_UPDATE_VMSA, &vmsa, &argp->error); if (ret) - goto e_free; + return ret; svm->vcpu.arch.guest_state_protected = true; } -e_free: - kfree(vmsa); - return ret; + return 0; } static int sev_launch_measure(struct kvm *kvm, struct kvm_sev_cmd *argp) { void __user *measure = (void __user *)(uintptr_t)argp->data; struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; - struct sev_data_launch_measure *data; + struct sev_data_launch_measure data; struct kvm_sev_launch_measure params; void __user *p = NULL; void *blob = NULL; @@ -622,9 +588,7 @@ static int sev_launch_measure(struct kvm *kvm, struct kvm_sev_cmd *argp) if (copy_from_user(¶ms, measure, sizeof(params))) return -EFAULT; - data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT); - if (!data) - return -ENOMEM; + memset(&data, 0, sizeof(data)); /* User wants to query the blob length */ if (!params.len) @@ -632,23 +596,20 @@ static int sev_launch_measure(struct kvm *kvm, struct kvm_sev_cmd *argp) p = (void __user *)(uintptr_t)params.uaddr; if (p) { - if (params.len > SEV_FW_BLOB_MAX_SIZE) { - ret = -EINVAL; - goto e_free; - } + if (params.len > SEV_FW_BLOB_MAX_SIZE) + return -EINVAL; - ret = -ENOMEM; blob = kmalloc(params.len, GFP_KERNEL_ACCOUNT); if (!blob) - goto e_free; + return -ENOMEM; - data->address = __psp_pa(blob); - data->len = params.len; + data.address = __psp_pa(blob); + data.len = params.len; } cmd: - data->handle = sev->handle; - ret = sev_issue_cmd(kvm, SEV_CMD_LAUNCH_MEASURE, data, &argp->error); + data.handle = sev->handle; + ret = sev_issue_cmd(kvm, SEV_CMD_LAUNCH_MEASURE, &data, &argp->error); /* * If we query the session length, FW responded with expected data. @@ -665,63 +626,50 @@ static int sev_launch_measure(struct kvm *kvm, struct kvm_sev_cmd *argp) } done: - params.len = data->len; + params.len = data.len; if (copy_to_user(measure, ¶ms, sizeof(params))) ret = -EFAULT; e_free_blob: kfree(blob); -e_free: - kfree(data); return ret; } static int sev_launch_finish(struct kvm *kvm, struct kvm_sev_cmd *argp) { struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; - struct sev_data_launch_finish *data; - int ret; + struct sev_data_launch_finish data; if (!sev_guest(kvm)) return -ENOTTY; - data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT); - if (!data) - return -ENOMEM; - - data->handle = sev->handle; - ret = sev_issue_cmd(kvm, SEV_CMD_LAUNCH_FINISH, data, &argp->error); - - kfree(data); - return ret; + data.handle = sev->handle; + return sev_issue_cmd(kvm, SEV_CMD_LAUNCH_FINISH, &data, &argp->error); } static int sev_guest_status(struct kvm *kvm, struct kvm_sev_cmd *argp) { struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; struct kvm_sev_guest_status params; - struct sev_data_guest_status *data; + struct sev_data_guest_status data; int ret; if (!sev_guest(kvm)) return -ENOTTY; - data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT); - if (!data) - return -ENOMEM; + memset(&data, 0, sizeof(data)); - data->handle = sev->handle; - ret = sev_issue_cmd(kvm, SEV_CMD_GUEST_STATUS, data, &argp->error); + data.handle = sev->handle; + ret = sev_issue_cmd(kvm, SEV_CMD_GUEST_STATUS, &data, &argp->error); if (ret) - goto e_free; + return ret; - params.policy = data->policy; - params.state = data->state; - params.handle = data->handle; + params.policy = data.policy; + params.state = data.state; + params.handle = data.handle; if (copy_to_user((void __user *)(uintptr_t)argp->data, ¶ms, sizeof(params))) ret = -EFAULT; -e_free: - kfree(data); + return ret; } @@ -730,23 +678,17 @@ static int __sev_issue_dbg_cmd(struct kvm *kvm, unsigned long src, int *error, bool enc) { struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; - struct sev_data_dbg *data; - int ret; + struct sev_data_dbg data; - data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT); - if (!data) - return -ENOMEM; + data.reserved = 0; + data.handle = sev->handle; + data.dst_addr = dst; + data.src_addr = src; + data.len = size; - data->handle = sev->handle; - data->dst_addr = dst; - data->src_addr = src; - data->len = size; - - ret = sev_issue_cmd(kvm, - enc ? SEV_CMD_DBG_ENCRYPT : SEV_CMD_DBG_DECRYPT, - data, error); - kfree(data); - return ret; + return sev_issue_cmd(kvm, + enc ? SEV_CMD_DBG_ENCRYPT : SEV_CMD_DBG_DECRYPT, + &data, error); } static int __sev_dbg_decrypt(struct kvm *kvm, unsigned long src_paddr, @@ -966,7 +908,7 @@ static int sev_dbg_crypt(struct kvm *kvm, struct kvm_sev_cmd *argp, bool dec) static int sev_launch_secret(struct kvm *kvm, struct kvm_sev_cmd *argp) { struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; - struct sev_data_launch_secret *data; + struct sev_data_launch_secret data; struct kvm_sev_launch_secret params; struct page **pages; void *blob, *hdr; @@ -998,41 +940,36 @@ static int sev_launch_secret(struct kvm *kvm, struct kvm_sev_cmd *argp) goto e_unpin_memory; } - ret = -ENOMEM; - data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT); - if (!data) - goto e_unpin_memory; + memset(&data, 0, sizeof(data)); offset = params.guest_uaddr & (PAGE_SIZE - 1); - data->guest_address = __sme_page_pa(pages[0]) + offset; - data->guest_len = params.guest_len; + data.guest_address = __sme_page_pa(pages[0]) + offset; + data.guest_len = params.guest_len; blob = psp_copy_user_blob(params.trans_uaddr, params.trans_len); if (IS_ERR(blob)) { ret = PTR_ERR(blob); - goto e_free; + goto e_unpin_memory; } - data->trans_address = __psp_pa(blob); - data->trans_len = params.trans_len; + data.trans_address = __psp_pa(blob); + data.trans_len = params.trans_len; hdr = psp_copy_user_blob(params.hdr_uaddr, params.hdr_len); if (IS_ERR(hdr)) { ret = PTR_ERR(hdr); goto e_free_blob; } - data->hdr_address = __psp_pa(hdr); - data->hdr_len = params.hdr_len; + data.hdr_address = __psp_pa(hdr); + data.hdr_len = params.hdr_len; - data->handle = sev->handle; - ret = sev_issue_cmd(kvm, SEV_CMD_LAUNCH_UPDATE_SECRET, data, &argp->error); + data.handle = sev->handle; + ret = sev_issue_cmd(kvm, SEV_CMD_LAUNCH_UPDATE_SECRET, &data, &argp->error); kfree(hdr); e_free_blob: kfree(blob); -e_free: - kfree(data); e_unpin_memory: /* content of memory is updated, mark pages dirty */ for (i = 0; i < n; i++) { @@ -1047,7 +984,7 @@ static int sev_get_attestation_report(struct kvm *kvm, struct kvm_sev_cmd *argp) { void __user *report = (void __user *)(uintptr_t)argp->data; struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; - struct sev_data_attestation_report *data; + struct sev_data_attestation_report data; struct kvm_sev_attestation_report params; void __user *p; void *blob = NULL; @@ -1059,9 +996,7 @@ static int sev_get_attestation_report(struct kvm *kvm, struct kvm_sev_cmd *argp) if (copy_from_user(¶ms, (void __user *)(uintptr_t)argp->data, sizeof(params))) return -EFAULT; - data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT); - if (!data) - return -ENOMEM; + memset(&data, 0, sizeof(data)); /* User wants to query the blob length */ if (!params.len) @@ -1069,23 +1004,20 @@ static int sev_get_attestation_report(struct kvm *kvm, struct kvm_sev_cmd *argp) p = (void __user *)(uintptr_t)params.uaddr; if (p) { - if (params.len > SEV_FW_BLOB_MAX_SIZE) { - ret = -EINVAL; - goto e_free; - } + if (params.len > SEV_FW_BLOB_MAX_SIZE) + return -EINVAL; - ret = -ENOMEM; blob = kmalloc(params.len, GFP_KERNEL_ACCOUNT); if (!blob) - goto e_free; + return -ENOMEM; - data->address = __psp_pa(blob); - data->len = params.len; - memcpy(data->mnonce, params.mnonce, sizeof(params.mnonce)); + data.address = __psp_pa(blob); + data.len = params.len; + memcpy(data.mnonce, params.mnonce, sizeof(params.mnonce)); } cmd: - data->handle = sev->handle; - ret = sev_issue_cmd(kvm, SEV_CMD_ATTESTATION_REPORT, data, &argp->error); + data.handle = sev->handle; + ret = sev_issue_cmd(kvm, SEV_CMD_ATTESTATION_REPORT, &data, &argp->error); /* * If we query the session length, FW responded with expected data. */ @@ -1101,13 +1033,11 @@ static int sev_get_attestation_report(struct kvm *kvm, struct kvm_sev_cmd *argp) } done: - params.len = data->len; + params.len = data.len; if (copy_to_user(report, ¶ms, sizeof(params))) ret = -EFAULT; e_free_blob: kfree(blob); -e_free: - kfree(data); return ret; }