Skip to content

Commit 770de67

Browse files
stefano-garzarellabp3tk0v
authored andcommitted
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
1 parent 0af2f6b commit 770de67

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

arch/x86/coco/sev/core.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2625,6 +2625,64 @@ static int snp_issue_guest_request(struct snp_guest_req *req, struct snp_req_dat
26252625
return ret;
26262626
}
26272627

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

arch/x86/include/asm/sev.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,10 @@ struct svsm_call {
384384
#define SVSM_ATTEST_SERVICES 0
385385
#define SVSM_ATTEST_SINGLE_SERVICE 1
386386

387+
#define SVSM_VTPM_CALL(x) ((2ULL << 32) | (x))
388+
#define SVSM_VTPM_QUERY 0
389+
#define SVSM_VTPM_CMD 1
390+
387391
#ifdef CONFIG_AMD_MEM_ENCRYPT
388392

389393
extern u8 snp_vmpl;
@@ -481,6 +485,8 @@ void snp_msg_free(struct snp_msg_desc *mdesc);
481485
int snp_send_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_req *req,
482486
struct snp_guest_request_ioctl *rio);
483487

488+
int snp_svsm_vtpm_send_command(u8 *buffer);
489+
484490
void __init snp_secure_tsc_prepare(void);
485491
void __init snp_secure_tsc_init(void);
486492

@@ -524,6 +530,7 @@ static inline struct snp_msg_desc *snp_msg_alloc(void) { return NULL; }
524530
static inline void snp_msg_free(struct snp_msg_desc *mdesc) { }
525531
static inline int snp_send_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_req *req,
526532
struct snp_guest_request_ioctl *rio) { return -ENODEV; }
533+
static inline int snp_svsm_vtpm_send_command(u8 *buffer) { return -ENODEV; }
527534
static inline void __init snp_secure_tsc_prepare(void) { }
528535
static inline void __init snp_secure_tsc_init(void) { }
529536

0 commit comments

Comments
 (0)