Skip to content

Commit

Permalink
x86/sev: add a SVSM vTPM platform device
Browse files Browse the repository at this point in the history
If the SNP boot has a SVSM, probe for the vTPM device by sending a
SVSM_VTPM_QUERY call (function 8). The SVSM will return a bitmap with the
TPM_SEND_COMMAND bit set only if the vTPM is present and it is able to handle
TPM commands at runtime.

If a vTPM is found, register a platform device as "platform:tpm" so it
can be attached to the tpm_platform.c driver.

Signed-off-by: James Bottomley <[email protected]>
Signed-off-by: Joerg Roedel <[email protected]>
[SG] Code adjusted with some changes introduced in 6.11
Signed-off-by: Stefano Garzarella <[email protected]>
  • Loading branch information
James Bottomley authored and roy-hopkins committed Nov 4, 2024
1 parent 7b5d750 commit 9fd49e0
Showing 1 changed file with 63 additions and 0 deletions.
63 changes: 63 additions & 0 deletions arch/x86/coco/sev/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <linux/cpumask.h>
#include <linux/efi.h>
#include <linux/platform_device.h>
#include <linux/tpm_platform.h>
#include <linux/io.h>
#include <linux/psp-sev.h>
#include <linux/dmi.h>
Expand Down Expand Up @@ -2510,6 +2511,50 @@ static struct platform_device sev_guest_device = {
.id = -1,
};

static struct platform_device tpm_device = {
.name = "tpm",
.id = -1,
};

static int snp_issue_svsm_vtpm_send_command(u8 *buffer)
{
struct svsm_call call = {};

call.caa = svsm_get_caa();
call.rax = (2ULL << 32) | 1;
call.rcx = __pa(buffer);

return svsm_perform_call_protocol(&call);
}

static bool is_svsm_vtpm_send_command_supported(void)
{
struct svsm_call call = {};
u64 send_cmd_mask = 0;
u64 platform_cmds;
u64 features;
int ret;

call.caa = svsm_get_caa();
call.rax = 2ULL << 32;

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 must be zero */
if (features)
return false;

send_cmd_mask = 1 << 8;

return (platform_cmds & send_cmd_mask) == send_cmd_mask;
}

static int __init snp_init_platform_device(void)
{
struct sev_guest_platform_data data;
Expand All @@ -2530,6 +2575,24 @@ static int __init snp_init_platform_device(void)
return -ENODEV;

pr_info("SNP guest platform device initialized.\n");

/*
* The VTPM device is available only if we have a SVSM and
* its VTPM supports the TPM_SEND_COMMAND platform command
*/

if (IS_ENABLED(CONFIG_TCG_PLATFORM) && snp_vmpl &&
is_svsm_vtpm_send_command_supported()) {
struct tpm_platform_ops pops = {
.sendrcv = snp_issue_svsm_vtpm_send_command,
};

if (platform_device_add_data(&tpm_device, &pops, sizeof(pops)))
return -ENODEV;
if (platform_device_register(&tpm_device))
return -ENODEV;
pr_info("SNP SVSM VTPM platform device initialized\n");
}
return 0;
}
device_initcall(snp_init_platform_device);
Expand Down

0 comments on commit 9fd49e0

Please sign in to comment.