-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
TDX guest driver exposes IOCTL interfaces to service TDX guest user-specific requests. Currently, it is only used to allow the user to get the TDREPORT to support TDX attestation. Details about the TDX attestation process are documented in Documentation/x86/tdx.rst, and the IOCTL details are documented in Documentation/virt/coco/tdx-guest.rst. Operations like getting TDREPORT involves sending a blob of data as input and getting another blob of data as output. It was considered to use a sysfs interface for this, but it doesn't fit well into the standard sysfs model for configuring values. It would be possible to do read/write on files, but it would need multiple file descriptors, which would be somewhat messy. IOCTLs seems to be the best fitting and simplest model for this use case. The AMD sev-guest driver also uses IOCTL interface to support attestation. [Bagas Sanjaya: Ack is for documentation portion] Acked-by: Kai Huang <kai.huang@intel.com> Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Acked-by: Wander Lairson Costa <wander@redhat.com> Reviewed-by: Bagas Sanjaya <bagasdotme@gmail.com> Reviewed-by: Tony Luck <tony.luck@intel.com> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
- Loading branch information
Kuppuswamy Sathyanarayanan
committed
Sep 28, 2022
1 parent
2bd128a
commit 2ad4077
Showing
10 changed files
with
286 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
.. SPDX-License-Identifier: GPL-2.0 | ||
=================================================================== | ||
TDX Guest API Documentation | ||
=================================================================== | ||
|
||
1. General description | ||
====================== | ||
|
||
The TDX guest driver exposes IOCTL interfaces via /dev/tdx-guest misc | ||
device to allow userspace to get certain TDX guest specific details. | ||
|
||
2. API description | ||
================== | ||
|
||
In this section, for each supported IOCTL, following information is | ||
provided along with a generic description. | ||
|
||
:Input parameters: Parameters passed to the IOCTL and related details. | ||
:Output: Details about output data and return value (with details about the non | ||
common error values). | ||
|
||
2.1 TDX_CMD_GET_REPORT | ||
---------------------- | ||
|
||
:Input parameters: struct tdx_report_req | ||
:Output: Upon successful execution, TDREPORT data is copied to | ||
tdx_report_req.tdreport and return 0. Return -EIO on | ||
TDCALL failure or standard error number on other common | ||
failures. | ||
|
||
The TDX_CMD_GET_REPORT IOCTL can be used by the attestation software to | ||
get the TDREPORT from the TDX module using TDCALL[TDG.MR.REPORT]. | ||
|
||
Reference | ||
--------- | ||
|
||
TDX reference material is collected here: | ||
|
||
https://www.intel.com/content/www/us/en/developer/articles/technical/intel-trust-domain-extensions.html | ||
|
||
The driver is based on TDX module specification v1.0 and TDX GHCI specification v1.0. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# SPDX-License-Identifier: GPL-2.0-only | ||
obj-$(CONFIG_TDX_GUEST_DRIVER) += tdx-guest.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* | ||
* TDX guest user interface driver | ||
* | ||
* Copyright (C) 2022 Intel Corporation | ||
*/ | ||
|
||
#include <linux/io.h> | ||
#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_report(void __user *argp) | ||
{ | ||
u8 *reportdata, *tdreport; | ||
struct tdx_report_req req; | ||
long ret; | ||
|
||
if (copy_from_user(&req, argp, sizeof(req))) | ||
return -EFAULT; | ||
|
||
/* | ||
* Per TDX Module 1.0 specification, section titled | ||
* "TDG.MR.REPORT", REPORTDATA length is fixed as | ||
* TDX_REPORTDATA_LEN, TDREPORT length is fixed as | ||
* TDX_REPORT_LEN, and TDREPORT subtype is fixed as 0. | ||
*/ | ||
if (req.subtype || req.rpd_len != TDX_REPORTDATA_LEN || | ||
req.tdr_len != TDX_REPORT_LEN) | ||
return -EINVAL; | ||
|
||
if (memchr_inv(req.reserved, 0, sizeof(req.reserved))) | ||
return -EINVAL; | ||
|
||
reportdata = kmalloc(req.rpd_len, GFP_KERNEL); | ||
if (!reportdata) | ||
return -ENOMEM; | ||
|
||
tdreport = kzalloc(req.tdr_len, GFP_KERNEL); | ||
if (!tdreport) { | ||
ret = -ENOMEM; | ||
goto out; | ||
} | ||
|
||
if (copy_from_user(reportdata, u64_to_user_ptr(req.reportdata), | ||
req.rpd_len)) { | ||
ret = -EFAULT; | ||
goto out; | ||
} | ||
|
||
/* | ||
* Generate TDREPORT using "TDG.MR.REPORT" TDCALL. | ||
* | ||
* Get the TDREPORT using REPORTDATA as input. Refer to | ||
* section 22.3.3 TDG.MR.REPORT leaf in the TDX Module 1.0 | ||
* Specification for detailed information. | ||
*/ | ||
ret = __tdx_module_call(TDX_GET_REPORT, virt_to_phys(tdreport), | ||
virt_to_phys(reportdata), req.subtype, | ||
0, NULL); | ||
if (ret) { | ||
ret = -EIO; | ||
goto out; | ||
} | ||
|
||
if (copy_to_user(u64_to_user_ptr(req.tdreport), tdreport, req.tdr_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_REPORT: | ||
return tdx_get_report((void __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 = TDX_GUEST_DEVICE, | ||
.minor = MISC_DYNAMIC_MINOR, | ||
.fops = &tdx_guest_fops, | ||
}; | ||
|
||
static int __init tdx_guest_init(void) | ||
{ | ||
if (!cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) | ||
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); | ||
|
||
static const struct x86_cpu_id tdx_guest_ids[] = { | ||
X86_MATCH_FEATURE(X86_FEATURE_TDX_GUEST, NULL), | ||
{} | ||
}; | ||
MODULE_DEVICE_TABLE(x86cpu, tdx_guest_ids); | ||
|
||
MODULE_AUTHOR("Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>"); | ||
MODULE_DESCRIPTION("TDX Guest Driver"); | ||
MODULE_LICENSE("GPL"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ | ||
#ifndef _UAPI_LINUX_TDX_GUEST_H_ | ||
#define _UAPI_LINUX_TDX_GUEST_H_ | ||
|
||
#include <linux/ioctl.h> | ||
#include <linux/types.h> | ||
|
||
#define TDX_GUEST_DEVICE "tdx-guest" | ||
|
||
/* Length of the REPORTDATA used in TDG.MR.REPORT TDCALL */ | ||
#define TDX_REPORTDATA_LEN 64 | ||
|
||
/* Length of TDREPORT used in TDG.MR.REPORT TDCALL */ | ||
#define TDX_REPORT_LEN 1024 | ||
|
||
/** | ||
* struct tdx_report_req - Get TDREPORT using REPORTDATA as input. | ||
* | ||
* @reportdata: User-defined REPORTDATA to be included into TDREPORT. | ||
* Typically it can be some nonce provided by attestation service, | ||
* so the generated TDREPORT can be uniquely verified. | ||
* @tdreport: TDREPORT output from TDCALL[TDG.MR.REPORT]. | ||
* @rpd_len: Length of the REPORTDATA (fixed as 64 bytes by the TDX | ||
* Module specification, but a parameter is added to handle future | ||
* extension). | ||
* @tdr_len: Length of the TDREPORT (fixed as 1024 bytes by the TDX | ||
* Module specification, but a parameter is added to accommodate | ||
* future extension). | ||
* @subtype: Subtype of TDREPORT (fixed as 0 by the TDX Module specification, | ||
* but added a parameter to handle future extension). | ||
* @reserved: Reserved entries to handle future requirements. Should be | ||
* filled with zeroes. | ||
* | ||
* Used in TDX_CMD_GET_REPORT IOCTL request. | ||
*/ | ||
struct tdx_report_req { | ||
__u64 reportdata; | ||
__u64 tdreport; | ||
__u32 rpd_len; | ||
__u32 tdr_len; | ||
__u8 subtype; | ||
__u8 reserved[7]; | ||
}; | ||
|
||
/* | ||
* TDX_CMD_GET_REPORT - Get TDREPORT using TDCALL[TDG.MR.REPORT] | ||
* | ||
* Return 0 on success, -EIO on TDCALL execution failure, and | ||
* standard errno on other general error cases. | ||
*/ | ||
#define TDX_CMD_GET_REPORT _IOWR('T', 1, struct tdx_report_req) | ||
|
||
#endif /* _UAPI_LINUX_TDX_GUEST_H_ */ |