Merge tag 'x86_tdx_for_6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 tdx updates from Dave Hansen:
 "This includes a single chunk of new functionality for TDX guests which
  allows them to talk to the trusted TDX module software and obtain an
  attestation report.

  This report can then be used to prove the trustworthiness of the guest
  to a third party and get access to things like storage encryption
  keys"

* tag 'x86_tdx_for_6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  selftests/tdx: Test TDX attestation GetReport support
  virt: Add TDX guest driver
  x86/tdx: Add a wrapper to get TDREPORT0 from the TDX Module
This commit is contained in:
Linus Torvalds
2022-12-12 14:27:49 -08:00
15 changed files with 469 additions and 0 deletions

View File

@@ -0,0 +1,10 @@
config TDX_GUEST_DRIVER
tristate "TDX Guest driver"
depends on INTEL_TDX_GUEST
help
The driver provides userspace interface to communicate with
the TDX module to request the TDX guest details like attestation
report.
To compile this driver as module, choose M here. The module will
be called tdx-guest.

View File

@@ -0,0 +1,2 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_TDX_GUEST_DRIVER) += tdx-guest.o

View File

@@ -0,0 +1,102 @@
// SPDX-License-Identifier: GPL-2.0
/*
* TDX guest user interface driver
*
* Copyright (C) 2022 Intel Corporation
*/
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/string.h>
#include <linux/uaccess.h>
#include <uapi/linux/tdx-guest.h>
#include <asm/cpu_device_id.h>
#include <asm/tdx.h>
static long tdx_get_report0(struct tdx_report_req __user *req)
{
u8 *reportdata, *tdreport;
long ret;
reportdata = kmalloc(TDX_REPORTDATA_LEN, GFP_KERNEL);
if (!reportdata)
return -ENOMEM;
tdreport = kzalloc(TDX_REPORT_LEN, GFP_KERNEL);
if (!tdreport) {
ret = -ENOMEM;
goto out;
}
if (copy_from_user(reportdata, req->reportdata, TDX_REPORTDATA_LEN)) {
ret = -EFAULT;
goto out;
}
/* Generate TDREPORT0 using "TDG.MR.REPORT" TDCALL */
ret = tdx_mcall_get_report0(reportdata, tdreport);
if (ret)
goto out;
if (copy_to_user(req->tdreport, tdreport, TDX_REPORT_LEN))
ret = -EFAULT;
out:
kfree(reportdata);
kfree(tdreport);
return ret;
}
static long tdx_guest_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
switch (cmd) {
case TDX_CMD_GET_REPORT0:
return tdx_get_report0((struct tdx_report_req __user *)arg);
default:
return -ENOTTY;
}
}
static const struct file_operations tdx_guest_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = tdx_guest_ioctl,
.llseek = no_llseek,
};
static struct miscdevice tdx_misc_dev = {
.name = KBUILD_MODNAME,
.minor = MISC_DYNAMIC_MINOR,
.fops = &tdx_guest_fops,
};
static const struct x86_cpu_id tdx_guest_ids[] = {
X86_MATCH_FEATURE(X86_FEATURE_TDX_GUEST, NULL),
{}
};
MODULE_DEVICE_TABLE(x86cpu, tdx_guest_ids);
static int __init tdx_guest_init(void)
{
if (!x86_match_cpu(tdx_guest_ids))
return -ENODEV;
return misc_register(&tdx_misc_dev);
}
module_init(tdx_guest_init);
static void __exit tdx_guest_exit(void)
{
misc_deregister(&tdx_misc_dev);
}
module_exit(tdx_guest_exit);
MODULE_AUTHOR("Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>");
MODULE_DESCRIPTION("TDX Guest Driver");
MODULE_LICENSE("GPL");