diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2023-01-03 16:04:00 -0500 |
---|---|---|
committer | Mike Rapoport (IBM) <rppt@kernel.org> | 2023-08-11 15:39:18 +0300 |
commit | 583165d844987c3252832a4bed7732692223edbc (patch) | |
tree | 922b51a816653c6f484ed699b2ef97aaa29b99d0 | |
parent | 09e81386e6eefc6c35efa49c0d3e3f4c62fe88c3 (diff) | |
download | linux-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.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/sev.c | 33 |
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); |