Received: by 2002:a05:6a10:1287:0:0:0:0 with SMTP id d7csp4101116pxv; Mon, 19 Jul 2021 17:01:21 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwMNIJBVmCyLmm+d3nuhFuKy/ZskSofDfK8XGy6MVyoe0RgLJ7eqmv3/gYjogPMOKrzezxg X-Received: by 2002:a05:6638:3824:: with SMTP id i36mr12148772jav.11.1626739281170; Mon, 19 Jul 2021 17:01:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626739281; cv=none; d=google.com; s=arc-20160816; b=W5HQVskDKO7RMazg9Q304w7JzvvA6Z5lcADFCT1DBme6DyG4DhVF1REsiAeKluURMO M+QHdWvBofyaQIiLbTgirWAy6sdVenJdNbucXnyZKKKEbKwAHZLgGLtY2esvF8JKt3VY uXwUf3hTda4SE3AiH6COh/MIAZMd87pNVXo8O2OHiQT+U6ukDnxSbqaS1KjqCw5HklKz rfOnWqi4d2/vUqXWjyvjvddqhXuZ/wuAvEa+BF8RnkFz4ns0S0xOkrYlI5QA3afqqEaC SjSIrI3caDWU73iIxbGDZuv/rTuzHNjamlqtc6qc+bMDZntVyXKOpAWwMdvBIDVKQeMo rKsA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:message-id:subject:cc:to:from:date:dkim-signature; bh=/KQZ/og+MMwG7+gZQy+I2ifIZbW2sC3CrysTm6RWo48=; b=Y4eUwoJtly+s2uku9ddo14y1GvGhaFnz9xeumWOmWGTKeWuJO7ut3TDI4LDFYF32dj dhsldGIIDTYS0UsA/cY+lAz26pLYFqrjqllH9jDttaSB2H0102m3S3+/+yVDpY7xhZqQ j11cXEyTz4VUHCQY1i0IyZmy1lq3SIB8t43lqkmbU1UbsPwXsBuunxpqpLIR+f6RsrSz NFsyUtQfUwi5LmZfuipN7BjAL+B/XT0rkYzwPsBAp0BsL6zGxudCuCdEKL1reKD2WIDE c4htIrtbj8E8R1QjuIQOUFyYGNQzkb713vI6yspMSkjistCqE323pmZ/hZUbp25ay2sQ YcsQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=TrC6uyze; spf=pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id q3si13567684ilu.88.2021.07.19.17.01.08; Mon, 19 Jul 2021 17:01:21 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=TrC6uyze; spf=pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236136AbhGSXSA (ORCPT + 99 others); Mon, 19 Jul 2021 19:18:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58478 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1441885AbhGSWOD (ORCPT ); Mon, 19 Jul 2021 18:14:03 -0400 Received: from mail-pf1-x429.google.com (mail-pf1-x429.google.com [IPv6:2607:f8b0:4864:20::429]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A2013C0613B8 for ; Mon, 19 Jul 2021 15:50:07 -0700 (PDT) Received: by mail-pf1-x429.google.com with SMTP id p36so17956976pfw.11 for ; Mon, 19 Jul 2021 15:50:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=/KQZ/og+MMwG7+gZQy+I2ifIZbW2sC3CrysTm6RWo48=; b=TrC6uyzelR+/+DuhHGkQhT8ZilBSns6EN6zr6R3GsDzwt1A0B1ob14VfGLKbKtyYHf UnePiDR4FpHICi6z5QS4Br4KOWkHIgLEeR8gx7IzpIzQOJFTLlF7+NNZycoVeKnxYD6h HbjmZ/PaBHV0V8e+cfLnxBcowZivtCrjpWnTV8c2ZjABFcunj+ENtzWsgGQLyJbKIFv/ VR+A8muZqP5sibfw7uvl/qPo2Ty2GVOGxwdOKplp/U4hoGQCi7nhVUCLUrGwfAlFMGnd p98tI4Tr+xvCXIgbQNI2AJDXVbX1JKOsFuuzRo2sS//yKyLQdg5uMFTMCUas9NSy8J5b Frtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=/KQZ/og+MMwG7+gZQy+I2ifIZbW2sC3CrysTm6RWo48=; b=D1G7loB5yR6jBaIDH+/IxQo5fg4uI8J7spOcO19pSdbSmjXYpfYKJ09Q5RB4th1bDT o/csoMVseBfCLRygla9Y8V2fjg4vd9iKHZy/0neOLqxP99QWM5ywCj3GhBpkVzIYUCZ1 1S8FmVzFvvgeS1dCuTERKe3BbAuMPL0i0lhi7oQqeH0TFqM7nh9su8aOrIDvXsoVsbNB MgftfSjRx8b0XKq+lt92U2ZY4HDS2qkUzFBwc6Y2k6HWgjZcCipxCyBxCVaBDkwiIZbN x7eVf48yt8dgEDkmRHc1d/4FqOzQjyiokZHLHSf5DYFPjJZc51cQdzooVNAnZbfPfeA7 Jing== X-Gm-Message-State: AOAM532x+4mqvTHHkP04W8ZDYOQbI7A6rr+XJFPOqIVVIJEQKeOKnybU w1BQD20j//ZrK+zwm/FrQDQehw== X-Received: by 2002:a63:a558:: with SMTP id r24mr12070616pgu.438.1626735006916; Mon, 19 Jul 2021 15:50:06 -0700 (PDT) Received: from google.com (157.214.185.35.bc.googleusercontent.com. [35.185.214.157]) by smtp.gmail.com with ESMTPSA id p33sm21208412pfw.40.2021.07.19.15.50.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Jul 2021 15:50:06 -0700 (PDT) Date: Mon, 19 Jul 2021 22:50:02 +0000 From: Sean Christopherson To: Brijesh Singh Cc: x86@kernel.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-efi@vger.kernel.org, platform-driver-x86@vger.kernel.org, linux-coco@lists.linux.dev, linux-mm@kvack.org, linux-crypto@vger.kernel.org, Thomas Gleixner , Ingo Molnar , Joerg Roedel , Tom Lendacky , "H. Peter Anvin" , Ard Biesheuvel , Paolo Bonzini , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Andy Lutomirski , Dave Hansen , Sergio Lopez , Peter Gonda , Peter Zijlstra , Srinivas Pandruvada , David Rientjes , Dov Murik , Tobin Feldman-Fitzthum , Borislav Petkov , Michael Roth , Vlastimil Babka , tony.luck@intel.com, npmccallum@redhat.com, brijesh.ksingh@gmail.com Subject: Re: [PATCH Part2 RFC v4 38/40] KVM: SVM: Provide support for SNP_GUEST_REQUEST NAE event Message-ID: References: <20210707183616.5620-1-brijesh.singh@amd.com> <20210707183616.5620-39-brijesh.singh@amd.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20210707183616.5620-39-brijesh.singh@amd.com> Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org On Wed, Jul 07, 2021, Brijesh Singh wrote: > Version 2 of GHCB specification added the support two SNP Guest Request > Message NAE event. The events allows for an SEV-SNP guest to make request > to the SEV-SNP firmware through hypervisor using the SNP_GUEST_REQUEST > API define in the SEV-SNP firmware specification. IIUC, this snippet in the spec means KVM can't restrict what requests are made by the guests. If so, that makes it difficult to detect/ratelimit a misbehaving guest, and also limits our options if there are firmware issues (hopefully there aren't). E.g. ratelimiting a guest after KVM has explicitly requested it to migrate is not exactly desirable. The hypervisor cannot alter the messages without detection nor read the plaintext of the messages. > The SNP_GUEST_REQUEST requires two unique pages, one page for the request > and one page for the response. The response page need to be in the firmware > state. The GHCB specification says that both the pages need to be in the > hypervisor state but before executing the SEV-SNP command the response page > need to be in the firmware state. ... > Now that KVM supports all the VMGEXIT NAEs required for the base SEV-SNP > feature, set the hypervisor feature to advertise it. It would helpful if this changelog listed the Guest Requests that are required for "base" SNP, e.g. to provide some insight as to why we care about guest requests. > static int snp_bind_asid(struct kvm *kvm, int *error) > @@ -1618,6 +1631,12 @@ static int snp_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp) > if (rc) > goto e_free_context; > > + /* Used for rate limiting SNP guest message request, use the default settings */ > + ratelimit_default_init(&sev->snp_guest_msg_rs); Is this exposed to userspace in any way? This feels very much like a knob that needs to be configurable per-VM. Also, what are the estimated latencies of a guest request? If the worst case latency is >200ms, a default ratelimit frequency of 5hz isn't going to do a whole lot. > +static void snp_handle_guest_request(struct vcpu_svm *svm, struct ghcb *ghcb, > + gpa_t req_gpa, gpa_t resp_gpa) > +{ > + struct sev_data_snp_guest_request data = {}; > + struct kvm_vcpu *vcpu = &svm->vcpu; > + struct kvm *kvm = vcpu->kvm; > + struct kvm_sev_info *sev; > + int rc, err = 0; > + > + if (!sev_snp_guest(vcpu->kvm)) { > + rc = -ENODEV; > + goto e_fail; > + } > + > + sev = &to_kvm_svm(kvm)->sev_info; > + > + if (!__ratelimit(&sev->snp_guest_msg_rs)) { > + pr_info_ratelimited("svm: too many guest message requests\n"); > + rc = -EAGAIN; What guarantee do we have that the guest actually understands -EAGAIN? Ditto for -EINVAL returned by snp_build_guest_buf(). AFAICT, our options are to return one of the error codes defined in "Table 95. Status Codes for SNP_GUEST_REQUEST" of the firmware ABI, kill the guest, or ratelimit the guest without returning control to the guest. > + goto e_fail; > + } > + > + rc = snp_build_guest_buf(svm, &data, req_gpa, resp_gpa); > + if (rc) > + goto e_fail; > + > + sev = &to_kvm_svm(kvm)->sev_info; > + > + mutex_lock(&kvm->lock); Question on the VMPCK sequences. The firmware ABI says: Each guest has four VMPCKs ... Each message contains a sequence number per VMPCK. The sequence number is incremented with each message sent. Messages sent by the guest to the firmware and by the firmware to the guest must be delivered in order. If not, the firmware will reject subsequent messages ... Does that mean there are four independent sequences, i.e. four streams the guest can use "concurrently", or does it mean the overall freshess/integrity check is composed from four VMPCK sequences, all of which must be correct for the message to be valid? If it's the latter, then a traditional mutex isn't really necessary because the guest must implement its own serialization, e.g. it's own mutex or whatever, to ensure there is at most one request in-flight at any given time. And on the KVM side it means KVM can simpy reject requests if there is already an in-flight request. It might also give us more/better options for ratelimiting? > + rc = sev_issue_cmd(kvm, SEV_CMD_SNP_GUEST_REQUEST, &data, &err); > + if (rc) { > + mutex_unlock(&kvm->lock); I suspect you reused this pattern from other, more complex code, but here it's overkill. E.g. if (!rc) rc = kvm_write_guest(kvm, resp_gpa, sev->snp_resp_page, PAGE_SIZE); else if (err) rc = err; mutex_unlock(&kvm->lock); ghcb_set_sw_exit_info_2(ghcb, rc); > + /* If we have a firmware error code then use it. */ > + if (err) > + rc = err; > + > + goto e_fail; > + } > + > + /* Copy the response after the firmware returns success. */ > + rc = kvm_write_guest(kvm, resp_gpa, sev->snp_resp_page, PAGE_SIZE); > + > + mutex_unlock(&kvm->lock); > + > +e_fail: > + ghcb_set_sw_exit_info_2(ghcb, rc); > +} > + > +static void snp_handle_ext_guest_request(struct vcpu_svm *svm, struct ghcb *ghcb, > + gpa_t req_gpa, gpa_t resp_gpa) > +{ > + struct sev_data_snp_guest_request req = {}; > + struct kvm_vcpu *vcpu = &svm->vcpu; > + struct kvm *kvm = vcpu->kvm; > + unsigned long data_npages; > + struct kvm_sev_info *sev; > + unsigned long err; > + u64 data_gpa; > + int rc; > + > + if (!sev_snp_guest(vcpu->kvm)) { > + rc = -ENODEV; > + goto e_fail; > + } > + > + sev = &to_kvm_svm(kvm)->sev_info; > + > + if (!__ratelimit(&sev->snp_guest_msg_rs)) { > + pr_info_ratelimited("svm: too many guest message requests\n"); > + rc = -EAGAIN; > + goto e_fail; > + } > + > + if (!sev->snp_certs_data) { > + pr_err("svm: certs data memory is not allocated\n"); > + rc = -EFAULT; Another instance where the kernel's error numbers will not suffice. > + goto e_fail; > + } > + > + data_gpa = ghcb_get_rax(ghcb); > + data_npages = ghcb_get_rbx(ghcb);