aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2023-01-03 16:04:00 -0500
committerMike Rapoport (IBM) <rppt@kernel.org>2023-08-11 15:39:18 +0300
commit583165d844987c3252832a4bed7732692223edbc (patch)
tree922b51a816653c6f484ed699b2ef97aaa29b99d0
parent09e81386e6eefc6c35efa49c0d3e3f4c62fe88c3 (diff)
downloadlinux-tpm-pdev.tar.gz
x86/sev: add a SVSM vTPM platform devicetpm-pdev
If the SNP boot has a SVSM, probe for the vTPM device by sending a call to SVSM function 8 with no arguments. If this returns successfully, the vTPM is present in the SVSM (If the SVSM doesn't have a vTPM, this call should return SVSM_ERR_UNSUPPORTED_CALLID). 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 <James.Bottomley@HansenPartnership.com>
-rw-r--r--arch/arm64/kernel/module.c2
-rw-r--r--arch/x86/kernel/sev.c33
2 files changed, 35 insertions, 0 deletions
diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
index 5af4975caeb58..4e8a68ad345e1 100644
--- a/arch/arm64/kernel/module.c
+++ b/arch/arm64/kernel/module.c
@@ -65,6 +65,8 @@ void *module_alloc(unsigned long size)
return NULL;
}
+ pr_info("===> %s: %px\n", __func__, kasan_rest_tag(p));
+
/* Memory is intended to be executable, reset the pointer tag. */
return kasan_reset_tag(p);
}
diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
index f697ed388557a..3165082543d8d 100644
--- a/arch/x86/kernel/sev.c
+++ b/arch/x86/kernel/sev.c
@@ -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 <asm/cpu_entry_area.h>
@@ -2472,10 +2473,24 @@ static struct platform_device sev_guest_device = {
.id = -1,
};
+static struct platform_device tpm_device = {
+ .name = "tpm",
+ .id = -1,
+};
+
+static int tpm_send_buffer(u8 *buffer)
+{
+ struct svsm_caa *caa;
+
+ caa = this_cpu_read(svsm_caa);
+ return __svsm_msr_protocol(caa, 8, __pa(buffer), 0, 0, 0);
+}
+
static int __init snp_init_platform_device(void)
{
struct sev_guest_platform_data data;
u64 gpa;
+ struct svsm_caa *caa = this_cpu_read(svsm_caa);
if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP))
return -ENODEV;
@@ -2492,6 +2507,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 it
+ * probes correctly (probe is to send a call with no arguments
+ * to function 8 and see it comes back as OK)
+ */
+ if (IS_ENABLED(CONFIG_TCG_PLATFORM) && svsm_vmpl &&
+ __svsm_msr_protocol(caa, 8, 0, 0, 0, 0) == 0) {
+ struct tpm_platform_ops pops = {
+ .sendrcv = tpm_send_buffer,
+ };
+
+ 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);