Add two new functions to probe and send commands to the SVSM vTPM. They leverage the two calls defined by the AMD SVSM specification for the vTPM protocol: SVSM_VTPM_QUERY and SVSM_VTPM_CMD. Expose these functions to be used by other modules such as a tpm driver. Co-developed-by: James Bottomley <James.Bottomley@xxxxxxxxxxxxxxxxxxxxx> Signed-off-by: James Bottomley <James.Bottomley@xxxxxxxxxxxxxxxxxxxxx> Co-developed-by: Claudio Carvalho <cclaudio@xxxxxxxxxxxxx> Signed-off-by: Claudio Carvalho <cclaudio@xxxxxxxxxxxxx> Signed-off-by: Stefano Garzarella <sgarzare@xxxxxxxxxx> --- James, Claudio are you fine with the Cdb, Sob? The code is pretty much similar to what was in the initial RFC, but I changed the context for that I reset the author but added C-o-b. Please, let me know if this is okay or if I need to do anything else (reset the author, etc.) --- arch/x86/include/asm/sev.h | 3 +++ arch/x86/coco/sev/core.c | 47 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h index f6ebf4492606..e379bcdddf07 100644 --- a/arch/x86/include/asm/sev.h +++ b/arch/x86/include/asm/sev.h @@ -485,6 +485,9 @@ void snp_msg_free(struct snp_msg_desc *mdesc); int snp_send_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_req *req, struct snp_guest_request_ioctl *rio); +bool snp_svsm_vtpm_probe(void); +int snp_svsm_vtpm_send_command(u8 *buffer); + void __init snp_secure_tsc_prepare(void); void __init snp_secure_tsc_init(void); diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c index 82492efc5d94..4158e447d645 100644 --- a/arch/x86/coco/sev/core.c +++ b/arch/x86/coco/sev/core.c @@ -2628,6 +2628,53 @@ static int snp_issue_guest_request(struct snp_guest_req *req, struct snp_req_dat return ret; } +bool snp_svsm_vtpm_probe(void) +{ + struct svsm_call call = {}; + u64 send_cmd_mask = 0; + u64 platform_cmds; + u64 features; + int ret; + + /* The vTPM device is available only if we have a SVSM */ + if (!snp_vmpl) + return false; + + call.caa = svsm_get_caa(); + call.rax = SVSM_VTPM_CALL(SVSM_VTPM_QUERY); + + ret = svsm_perform_call_protocol(&call); + + if (ret != SVSM_SUCCESS) + return false; + + features = call.rdx_out; + platform_cmds = call.rcx_out; + + /* No feature supported, it should be zero */ + if (features) + pr_warn("SNP SVSM vTPM unsupported features: 0x%llx\n", + features); + + /* TPM_SEND_COMMAND - platform command 8 */ + send_cmd_mask = 1 << 8; + + return (platform_cmds & send_cmd_mask) == send_cmd_mask; +} +EXPORT_SYMBOL_GPL(snp_svsm_vtpm_probe); + +int snp_svsm_vtpm_send_command(u8 *buffer) +{ + struct svsm_call call = {}; + + call.caa = svsm_get_caa(); + call.rax = SVSM_VTPM_CALL(SVSM_VTPM_CMD); + call.rcx = __pa(buffer); + + return svsm_perform_call_protocol(&call); +} +EXPORT_SYMBOL_GPL(snp_svsm_vtpm_send_command); + static struct platform_device sev_guest_device = { .name = "sev-guest", .id = -1, -- 2.48.1