Skip to content

Commit 5a2c02d

Browse files
x86/sev: Add SVSM vTPM probe/send_command functions
JIRA: https://issues.redhat.com/browse/RHEL-87276 Upstream Status: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git Conflicts: Downstream is missing some commits that exports other API in arch/x86/include/asm/sev.h like commit c552941 ("x86/sev: Carve out and export SNP guest messaging init routines") and commit 1e0b23b ("x86/sev: Relocate SNP guest messaging routines to common code") commit 770de67 Author: Stefano Garzarella <sgarzare@redhat.com> Date: Thu Apr 3 12:09:39 2025 +0200 x86/sev: Add SVSM vTPM probe/send_command functions Add two new functions to probe and send commands to the SVSM vTPM. They leverage the two calls defined by the AMD SVSM specification [1] for the vTPM protocol: SVSM_VTPM_QUERY and SVSM_VTPM_CMD. Expose snp_svsm_vtpm_send_command() to be used by a TPM driver. [1] "Secure VM Service Module for SEV-SNP Guests" Publication # 58019 Revision: 1.00 [ bp: Some doc touchups. ] Co-developed-by: James Bottomley <James.Bottomley@HansenPartnership.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com> Co-developed-by: Claudio Carvalho <cclaudio@linux.ibm.com> Signed-off-by: Claudio Carvalho <cclaudio@linux.ibm.com> Signed-off-by: Stefano Garzarella <sgarzare@redhat.com> Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com> Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org> Link: https://lore.kernel.org/r/20250403100943.120738-2-sgarzare@redhat.com Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
1 parent ea94c08 commit 5a2c02d

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

arch/x86/coco/sev/core.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2636,6 +2636,64 @@ int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, struct sn
26362636
}
26372637
EXPORT_SYMBOL_GPL(snp_issue_guest_request);
26382638

2639+
/**
2640+
* snp_svsm_vtpm_probe() - Probe if SVSM provides a vTPM device
2641+
*
2642+
* Check that there is SVSM and that it supports at least TPM_SEND_COMMAND
2643+
* which is the only request used so far.
2644+
*
2645+
* Return: true if the platform provides a vTPM SVSM device, false otherwise.
2646+
*/
2647+
static bool snp_svsm_vtpm_probe(void)
2648+
{
2649+
struct svsm_call call = {};
2650+
2651+
/* The vTPM device is available only if a SVSM is present */
2652+
if (!snp_vmpl)
2653+
return false;
2654+
2655+
call.caa = svsm_get_caa();
2656+
call.rax = SVSM_VTPM_CALL(SVSM_VTPM_QUERY);
2657+
2658+
if (svsm_perform_call_protocol(&call))
2659+
return false;
2660+
2661+
/* Check platform commands contains TPM_SEND_COMMAND - platform command 8 */
2662+
return call.rcx_out & BIT_ULL(8);
2663+
}
2664+
2665+
/**
2666+
* snp_svsm_vtpm_send_command() - Execute a vTPM operation on SVSM
2667+
* @buffer: A buffer used to both send the command and receive the response.
2668+
*
2669+
* Execute a SVSM_VTPM_CMD call as defined by
2670+
* "Secure VM Service Module for SEV-SNP Guests" Publication # 58019 Revision: 1.00
2671+
*
2672+
* All command request/response buffers have a common structure as specified by
2673+
* the following table:
2674+
* Byte Size     In/Out    Description
2675+
* Offset    (Bytes)
2676+
* 0x000     4          In        Platform command
2677+
 *                         Out       Platform command response size
2678+
*
2679+
* Each command can build upon this common request/response structure to create
2680+
* a structure specific to the command. See include/linux/tpm_svsm.h for more
2681+
* details.
2682+
*
2683+
* Return: 0 on success, -errno on failure
2684+
*/
2685+
int snp_svsm_vtpm_send_command(u8 *buffer)
2686+
{
2687+
struct svsm_call call = {};
2688+
2689+
call.caa = svsm_get_caa();
2690+
call.rax = SVSM_VTPM_CALL(SVSM_VTPM_CMD);
2691+
call.rcx = __pa(buffer);
2692+
2693+
return svsm_perform_call_protocol(&call);
2694+
}
2695+
EXPORT_SYMBOL_GPL(snp_svsm_vtpm_send_command);
2696+
26392697
static struct platform_device sev_guest_device = {
26402698
.name = "sev-guest",
26412699
.id = -1,

arch/x86/include/asm/sev.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,10 @@ struct svsm_call {
327327
#define SVSM_ATTEST_SERVICES 0
328328
#define SVSM_ATTEST_SINGLE_SERVICE 1
329329

330+
#define SVSM_VTPM_CALL(x) ((2ULL << 32) | (x))
331+
#define SVSM_VTPM_QUERY 0
332+
#define SVSM_VTPM_CMD 1
333+
330334
#ifdef CONFIG_AMD_MEM_ENCRYPT
331335

332336
extern u8 snp_vmpl;
@@ -418,6 +422,7 @@ int prepare_pte_enc(struct pte_enc_desc *d);
418422
void set_pte_enc_mask(pte_t *kpte, unsigned long pfn, pgprot_t new_prot);
419423
void snp_kexec_finish(void);
420424
void snp_kexec_begin(void);
425+
int snp_svsm_vtpm_send_command(u8 *buffer);
421426

422427
#else /* !CONFIG_AMD_MEM_ENCRYPT */
423428

@@ -458,6 +463,7 @@ static inline int prepare_pte_enc(struct pte_enc_desc *d) { return 0; }
458463
static inline void set_pte_enc_mask(pte_t *kpte, unsigned long pfn, pgprot_t new_prot) { }
459464
static inline void snp_kexec_finish(void) { }
460465
static inline void snp_kexec_begin(void) { }
466+
static inline int snp_svsm_vtpm_send_command(u8 *buffer) { return -ENODEV; }
461467

462468
#endif /* CONFIG_AMD_MEM_ENCRYPT */
463469

0 commit comments

Comments
 (0)