From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-lj1-f175.google.com (mail-lj1-f175.google.com [209.85.208.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 20D1729CA for ; Tue, 1 Feb 2022 20:17:16 +0000 (UTC) Received: by mail-lj1-f175.google.com with SMTP id a25so25726401lji.9 for ; Tue, 01 Feb 2022 12:17:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=c1G+U9mCR+9y3z9D1TzfeiUfdMNDGnmglMpEe2+/2LE=; b=VpWU+oS1r5knoJXzOyILe4moOYE+R2uHT5zRZ2Jk6DhbUyjF27qJ3+INmDQ6fgW21h Tbks8twIhWx83GEmJz8SvyDl28seEQXqJqh3NV9g5rTHkqsOws4rhC3I/N/p7qcc254t dO5dfpzfe+UZ1qwnCXB5UZJSurEkkiBYs4s3D9Zas6b0x9z+x5I85DrD9l2VaSp+bKq7 SMWCvA1VLe6N2jnWSR72sRQz1JDnI/ile1y5D0ika7OBCB6qjHvaKnf83FjnjAl6pUlX yedLGvX4pfjFeVB5yjbxiMrAQ/0ETQPPiMCTCVHV0Dt1fljCfrW3KHBEl8XoGKzF8eOV yQiw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=c1G+U9mCR+9y3z9D1TzfeiUfdMNDGnmglMpEe2+/2LE=; b=0QC0A50clGjpwUxusKKsszxKdFtxtdbJ66HKAhhfi9XyFiIk1Jq5q1tXK6cD8HtvKm Xu3cw5S580Gvf35FXXXJEstTJASnibS/2vr12oCfhuRtFvcKfkAOMc4HozX2q7i3GEfH y/fUQhoK8WGBCic0sjxFNWTviMB35A/KI1JEyemQva3rJsCJPD6KjGtRVHxuY1AG/IOi 1mmFAxv+4yvN7d+GXyncjZIfcBY2E/subrN5LwIWJUexrxdpRY/VV28mHrVfDkXXBGv9 bicF7XunwjgFcsghAwZQzT8ODcyS8ocvVcGwoIgfhLpP6lao+JyD3uwl0hqQE+Vn6owV 5hJw== X-Gm-Message-State: AOAM533N/erUY030LSN72mdQ0RWRk+t/9JWsLdm0QC12UZ+eoptCM5p7 eBXqBFtVSGEJECxjQBHTcxYsRpXidMYHre3Qoca0Dg== X-Google-Smtp-Source: ABdhPJw/gG064uPw6B2Edvi7SJHms7j1vwY6jMCGatl6ahEztehk1/Zegz8WhJ1BfcdyuJ3eUs0emystXh2QL2v0bB8= X-Received: by 2002:a2e:a781:: with SMTP id c1mr16364597ljf.527.1643746633936; Tue, 01 Feb 2022 12:17:13 -0800 (PST) Precedence: bulk X-Mailing-List: linux-coco@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 References: <20220128171804.569796-1-brijesh.singh@amd.com> <20220128171804.569796-40-brijesh.singh@amd.com> In-Reply-To: <20220128171804.569796-40-brijesh.singh@amd.com> From: Peter Gonda Date: Tue, 1 Feb 2022 13:17:02 -0700 Message-ID: Subject: Re: [PATCH v9 39/43] x86/sev: Provide support for SNP guest request NAEs To: Brijesh Singh Cc: "the arch/x86 maintainers" , LKML , kvm list , linux-efi@vger.kernel.org, platform-driver-x86@vger.kernel.org, linux-coco@lists.linux.dev, linux-mm@kvack.org, Thomas Gleixner , Ingo Molnar , Joerg Roedel , Tom Lendacky , "H. Peter Anvin" , Ard Biesheuvel , Paolo Bonzini , Sean Christopherson , Vitaly Kuznetsov , Jim Mattson , Andy Lutomirski , Dave Hansen , Sergio Lopez , Peter Zijlstra , Srinivas Pandruvada , David Rientjes , Dov Murik , Tobin Feldman-Fitzthum , Borislav Petkov , Michael Roth , Vlastimil Babka , "Kirill A . Shutemov" , Andi Kleen , "Dr . David Alan Gilbert" , brijesh.ksingh@gmail.com, Tony Luck , Marc Orr , Sathyanarayanan Kuppuswamy Content-Type: text/plain; charset="UTF-8" On Fri, Jan 28, 2022 at 10:19 AM Brijesh Singh wrote: > > Version 2 of GHCB specification provides SNP_GUEST_REQUEST and > SNP_EXT_GUEST_REQUEST NAE that can be used by the SNP guest to communicate > with the PSP. > > While at it, add a snp_issue_guest_request() helper that will be used by > driver or other subsystem to issue the request to PSP. > > See SEV-SNP firmware and GHCB spec for more details. > > Signed-off-by: Brijesh Singh > --- > arch/x86/include/asm/sev-common.h | 3 ++ > arch/x86/include/asm/sev.h | 14 ++++++++ > arch/x86/include/uapi/asm/svm.h | 4 +++ > arch/x86/kernel/sev.c | 55 +++++++++++++++++++++++++++++++ > 4 files changed, 76 insertions(+) > > diff --git a/arch/x86/include/asm/sev-common.h b/arch/x86/include/asm/sev-common.h > index cd769984e929..442614879dad 100644 > --- a/arch/x86/include/asm/sev-common.h > +++ b/arch/x86/include/asm/sev-common.h > @@ -128,6 +128,9 @@ struct snp_psc_desc { > struct psc_entry entries[VMGEXIT_PSC_MAX_ENTRY]; > } __packed; > > +/* Guest message request error code */ > +#define SNP_GUEST_REQ_INVALID_LEN BIT_ULL(32) > + > #define GHCB_MSR_TERM_REQ 0x100 > #define GHCB_MSR_TERM_REASON_SET_POS 12 > #define GHCB_MSR_TERM_REASON_SET_MASK 0xf > diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h > index 219abb4590f2..9830ee1d6ef0 100644 > --- a/arch/x86/include/asm/sev.h > +++ b/arch/x86/include/asm/sev.h > @@ -87,6 +87,14 @@ extern bool handle_vc_boot_ghcb(struct pt_regs *regs); > > #define RMPADJUST_VMSA_PAGE_BIT BIT(16) > > +/* SNP Guest message request */ > +struct snp_req_data { > + unsigned long req_gpa; > + unsigned long resp_gpa; > + unsigned long data_gpa; > + unsigned int data_npages; > +}; > + > #ifdef CONFIG_AMD_MEM_ENCRYPT > extern struct static_key_false sev_es_enable_key; > extern void __sev_es_ist_enter(struct pt_regs *regs); > @@ -154,6 +162,7 @@ void snp_set_memory_private(unsigned long vaddr, unsigned int npages); > void snp_set_wakeup_secondary_cpu(void); > bool snp_init(struct boot_params *bp); > void snp_abort(void); > +int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, unsigned long *fw_err); > #else > static inline void sev_es_ist_enter(struct pt_regs *regs) { } > static inline void sev_es_ist_exit(void) { } > @@ -173,6 +182,11 @@ static inline void snp_set_memory_private(unsigned long vaddr, unsigned int npag > static inline void snp_set_wakeup_secondary_cpu(void) { } > static inline bool snp_init(struct boot_params *bp) { return false; } > static inline void snp_abort(void) { } > +static inline int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, > + unsigned long *fw_err) > +{ > + return -ENOTTY; > +} > #endif > > #endif > diff --git a/arch/x86/include/uapi/asm/svm.h b/arch/x86/include/uapi/asm/svm.h > index 8b4c57baec52..5b8bc2b65a5e 100644 > --- a/arch/x86/include/uapi/asm/svm.h > +++ b/arch/x86/include/uapi/asm/svm.h > @@ -109,6 +109,8 @@ > #define SVM_VMGEXIT_SET_AP_JUMP_TABLE 0 > #define SVM_VMGEXIT_GET_AP_JUMP_TABLE 1 > #define SVM_VMGEXIT_PSC 0x80000010 > +#define SVM_VMGEXIT_GUEST_REQUEST 0x80000011 > +#define SVM_VMGEXIT_EXT_GUEST_REQUEST 0x80000012 > #define SVM_VMGEXIT_AP_CREATION 0x80000013 > #define SVM_VMGEXIT_AP_CREATE_ON_INIT 0 > #define SVM_VMGEXIT_AP_CREATE 1 > @@ -225,6 +227,8 @@ > { SVM_VMGEXIT_AP_HLT_LOOP, "vmgexit_ap_hlt_loop" }, \ > { SVM_VMGEXIT_AP_JUMP_TABLE, "vmgexit_ap_jump_table" }, \ > { SVM_VMGEXIT_PSC, "vmgexit_page_state_change" }, \ > + { SVM_VMGEXIT_GUEST_REQUEST, "vmgexit_guest_request" }, \ > + { SVM_VMGEXIT_EXT_GUEST_REQUEST, "vmgexit_ext_guest_request" }, \ > { SVM_VMGEXIT_AP_CREATION, "vmgexit_ap_creation" }, \ > { SVM_VMGEXIT_HV_FEATURES, "vmgexit_hypervisor_feature" }, \ > { SVM_EXIT_ERR, "invalid_guest_state" } > diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c > index cb97200bfda7..1d3ac83226fc 100644 > --- a/arch/x86/kernel/sev.c > +++ b/arch/x86/kernel/sev.c > @@ -2122,3 +2122,58 @@ static int __init snp_check_cpuid_table(void) > } > > arch_initcall(snp_check_cpuid_table); > + > +int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, unsigned long *fw_err) > +{ > + struct ghcb_state state; > + struct es_em_ctxt ctxt; > + unsigned long flags; > + struct ghcb *ghcb; > + int ret; > + > + if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) > + return -ENODEV; > + > + /* > + * __sev_get_ghcb() needs to run with IRQs disabled because it is using > + * a per-CPU GHCB. > + */ > + local_irq_save(flags); > + > + ghcb = __sev_get_ghcb(&state); > + if (!ghcb) { > + ret = -EIO; > + goto e_restore_irq; > + } > + > + vc_ghcb_invalidate(ghcb); > + > + if (exit_code == SVM_VMGEXIT_EXT_GUEST_REQUEST) { > + ghcb_set_rax(ghcb, input->data_gpa); > + ghcb_set_rbx(ghcb, input->data_npages); > + } > + > + ret = sev_es_ghcb_hv_call(ghcb, true, &ctxt, exit_code, input->req_gpa, input->resp_gpa); > + if (ret) > + goto e_put; > + > + 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; In the PSP driver we've had a bit of discussion around the fw_err and the return code and that it would be preferable to have fw_err be a required parameter. And then we can easily make sure fw_err is always non-zero when the return code is non-zero. Thoughts about doing the same inside the guest? > + > + ret = -EIO; > + } > + > +e_put: > + __sev_put_ghcb(&state); > +e_restore_irq: > + local_irq_restore(flags); > + > + return ret; > +} > +EXPORT_SYMBOL_GPL(snp_issue_guest_request); > -- > 2.25.1 >