History

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

Linus Torvalds committed 3 years ago

Commit a89ef2a2 parents 2da68a7 00e07cf15 files · +469 −0Browse files

Unified · Split

15 files
  1. Documentation/virt/coco/tdx-guest.rst +52 −0
  2. Documentation/virt/index.rst +1 −0
  3. Documentation/x86/tdx.rst +43 −0
  4. arch/x86/coco/tdx/tdx.c +40 −0
  5. arch/x86/include/asm/tdx.h +2 −0
  6. drivers/virt/Kconfig +2 −0
  7. drivers/virt/Makefile +1 −0
  8. drivers/virt/coco/tdx-guest/Kconfig +10 −0
  9. drivers/virt/coco/tdx-guest/Makefile +2 −0
  10. drivers/virt/coco/tdx-guest/tdx-guest.c +102 −0
  11. include/uapi/linux/tdx-guest.h +42 −0
  12. tools/testing/selftests/Makefile +1 −0
  13. tools/testing/selftests/tdx/Makefile +7 −0
  14. tools/testing/selftests/tdx/config +1 −0
  15. tools/testing/selftests/tdx/tdx_guest_test.c +163 −0
Documentation/virt/coco/tdx-guest.rst+52−0
@@ -0,0 +1,52 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3===================================================================
4TDX Guest API Documentation
5===================================================================
6
71. General description
8======================
9
10The TDX guest driver exposes IOCTL interfaces via the /dev/tdx-guest misc
11device to allow userspace to get certain TDX guest-specific details.
12
132. API description
14==================
15
16In this section, for each supported IOCTL, the following information is
17provided along with a generic description.
18
19:Input parameters: Parameters passed to the IOCTL and related details.
20:Output: Details about output data and return value (with details about
21 the non common error values).
22
232.1 TDX_CMD_GET_REPORT0
24-----------------------
25
26:Input parameters: struct tdx_report_req
27:Output: Upon successful execution, TDREPORT data is copied to
28 tdx_report_req.tdreport and return 0. Return -EINVAL for invalid
29 operands, -EIO on TDCALL failure or standard error number on other
30 common failures.
31
32The TDX_CMD_GET_REPORT0 IOCTL can be used by the attestation software to get
33the TDREPORT0 (a.k.a. TDREPORT subtype 0) from the TDX module using
34TDCALL[TDG.MR.REPORT].
35
36A subtype index is added at the end of this IOCTL CMD to uniquely identify the
37subtype-specific TDREPORT request. Although the subtype option is mentioned in
38the TDX Module v1.0 specification, section titled "TDG.MR.REPORT", it is not
39currently used, and it expects this value to be 0. So to keep the IOCTL
40implementation simple, the subtype option was not included as part of the input
41ABI. However, in the future, if the TDX Module supports more than one subtype,
42a new IOCTL CMD will be created to handle it. To keep the IOCTL naming
43consistent, a subtype index is added as part of the IOCTL CMD.
44
45Reference
46---------
47
48TDX reference material is collected here:
49
50https://www.intel.com/content/www/us/en/developer/articles/technical/intel-trust-domain-extensions.html
51
52The driver is based on TDX module specification v1.0 and TDX GHCI specification v1.0.
Documentation/virt/index.rst+1−0
@@ -14,6 +14,7 @@ Linux Virtualization Support · 13 unmodified lines
14 ne_overview14 ne_overview
15 acrn/index15 acrn/index
16 coco/sev-guest16 coco/sev-guest
17 coco/tdx-guest
17 hyperv/index18 hyperv/index
18 19
19.. only:: html and subproject20.. only:: html and subproject
Documentation/x86/tdx.rst+43−0
@@ -210,6 +210,49 @@ converted to shared on boot. · 209 unmodified lines
210For coherent DMA allocation, the DMA buffer gets converted on the210For coherent DMA allocation, the DMA buffer gets converted on the
211allocation. Check force_dma_unencrypted() for details.211allocation. Check force_dma_unencrypted() for details.
212 212
213Attestation
214===========
215
216Attestation is used to verify the TDX guest trustworthiness to other
217entities before provisioning secrets to the guest. For example, a key
218server may want to use attestation to verify that the guest is the
219desired one before releasing the encryption keys to mount the encrypted
220rootfs or a secondary drive.
221
222The TDX module records the state of the TDX guest in various stages of
223the guest boot process using the build time measurement register (MRTD)
224and runtime measurement registers (RTMR). Measurements related to the
225guest initial configuration and firmware image are recorded in the MRTD
226register. Measurements related to initial state, kernel image, firmware
227image, command line options, initrd, ACPI tables, etc are recorded in
228RTMR registers. For more details, as an example, please refer to TDX
229Virtual Firmware design specification, section titled "TD Measurement".
230At TDX guest runtime, the attestation process is used to attest to these
231measurements.
232
233The attestation process consists of two steps: TDREPORT generation and
234Quote generation.
235
236TDX guest uses TDCALL[TDG.MR.REPORT] to get the TDREPORT (TDREPORT_STRUCT)
237from the TDX module. TDREPORT is a fixed-size data structure generated by
238the TDX module which contains guest-specific information (such as build
239and boot measurements), platform security version, and the MAC to protect
240the integrity of the TDREPORT. A user-provided 64-Byte REPORTDATA is used
241as input and included in the TDREPORT. Typically it can be some nonce
242provided by attestation service so the TDREPORT can be verified uniquely.
243More details about the TDREPORT can be found in Intel TDX Module
244specification, section titled "TDG.MR.REPORT Leaf".
245
246After getting the TDREPORT, the second step of the attestation process
247is to send it to the Quoting Enclave (QE) to generate the Quote. TDREPORT
248by design can only be verified on the local platform as the MAC key is
249bound to the platform. To support remote verification of the TDREPORT,
250TDX leverages Intel SGX Quoting Enclave to verify the TDREPORT locally
251and convert it to a remotely verifiable Quote. Method of sending TDREPORT
252to QE is implementation specific. Attestation software can choose
253whatever communication channel available (i.e. vsock or TCP/IP) to
254send the TDREPORT to QE and receive the Quote.
255
213References256References
214==========257==========
215 258
arch/x86/coco/tdx/tdx.c+40−0
@@ -5,6 +5,8 @@ · 4 unmodified lines
5#define pr_fmt(fmt) "tdx: " fmt5#define pr_fmt(fmt) "tdx: " fmt
6 6
7#include <linux/cpufeature.h>7#include <linux/cpufeature.h>
8#include <linux/export.h>
9#include <linux/io.h>
8#include <asm/coco.h>10#include <asm/coco.h>
9#include <asm/tdx.h>11#include <asm/tdx.h>
10#include <asm/vmx.h>12#include <asm/vmx.h>
@@ -15,6 +17,7 @@ · 4 unmodified lines
15/* TDX module Call Leaf IDs */17/* TDX module Call Leaf IDs */
16#define TDX_GET_INFO 118#define TDX_GET_INFO 1
17#define TDX_GET_VEINFO 319#define TDX_GET_VEINFO 3
20#define TDX_GET_REPORT 4
18#define TDX_ACCEPT_PAGE 621#define TDX_ACCEPT_PAGE 6
19 22
20/* TDX hypercall Leaf IDs */23/* TDX hypercall Leaf IDs */
@@ -36,6 +39,12 @@ · 15 unmodified lines
36 39
37#define ATTR_SEPT_VE_DISABLE BIT(28)40#define ATTR_SEPT_VE_DISABLE BIT(28)
38 41
42/* TDX Module call error codes */
43#define TDCALL_RETURN_CODE(a) ((a) >> 32)
44#define TDCALL_INVALID_OPERAND 0xc0000100
45
46#define TDREPORT_SUBTYPE_0 0
47
39/*48/*
40 * Wrapper for standard use of __tdx_hypercall with no output aside from49 * Wrapper for standard use of __tdx_hypercall with no output aside from
41 * return code.50 * return code.
@@ -100,6 +109,37 @@ static inline void tdx_module_call(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9, · 58 unmodified lines
100 panic("TDCALL %lld failed (Buggy TDX module!)\n", fn);109 panic("TDCALL %lld failed (Buggy TDX module!)\n", fn);
101}110}
102 111
112/**
113 * tdx_mcall_get_report0() - Wrapper to get TDREPORT0 (a.k.a. TDREPORT
114 * subtype 0) using TDG.MR.REPORT TDCALL.
115 * @reportdata: Address of the input buffer which contains user-defined
116 * REPORTDATA to be included into TDREPORT.
117 * @tdreport: Address of the output buffer to store TDREPORT.
118 *
119 * Refer to section titled "TDG.MR.REPORT leaf" in the TDX Module
120 * v1.0 specification for more information on TDG.MR.REPORT TDCALL.
121 * It is used in the TDX guest driver module to get the TDREPORT0.
122 *
123 * Return 0 on success, -EINVAL for invalid operands, or -EIO on
124 * other TDCALL failures.
125 */
126int tdx_mcall_get_report0(u8 *reportdata, u8 *tdreport)
127{
128 u64 ret;
129
130 ret = __tdx_module_call(TDX_GET_REPORT, virt_to_phys(tdreport),
131 virt_to_phys(reportdata), TDREPORT_SUBTYPE_0,
132 0, NULL);
133 if (ret) {
134 if (TDCALL_RETURN_CODE(ret) == TDCALL_INVALID_OPERAND)
135 return -EINVAL;
136 return -EIO;
137 }
138
139 return 0;
140}
141EXPORT_SYMBOL_GPL(tdx_mcall_get_report0);
142
103static void tdx_parse_tdinfo(u64 *cc_mask)143static void tdx_parse_tdinfo(u64 *cc_mask)
104{144{
105 struct tdx_module_output out;145 struct tdx_module_output out;
arch/x86/include/asm/tdx.h+2−0
@@ -67,6 +67,8 @@ void tdx_safe_halt(void); · 66 unmodified lines
67 67
68bool tdx_early_handle_ve(struct pt_regs *regs);68bool tdx_early_handle_ve(struct pt_regs *regs);
69 69
70int tdx_mcall_get_report0(u8 *reportdata, u8 *tdreport);
71
70#else72#else
71 73
72static inline void tdx_early_init(void) { };74static inline void tdx_early_init(void) { };
drivers/virt/Kconfig+2−0
@@ -52,4 +52,6 @@ source "drivers/virt/coco/efi_secret/Kconfig" · 51 unmodified lines
52 52
53source "drivers/virt/coco/sev-guest/Kconfig"53source "drivers/virt/coco/sev-guest/Kconfig"
54 54
55source "drivers/virt/coco/tdx-guest/Kconfig"
56
55endif57endif
drivers/virt/Makefile+1−0
@@ -11,3 +11,4 @@ obj-$(CONFIG_NITRO_ENCLAVES) += nitro_enclaves/ · 10 unmodified lines
11obj-$(CONFIG_ACRN_HSM) += acrn/11obj-$(CONFIG_ACRN_HSM) += acrn/
12obj-$(CONFIG_EFI_SECRET) += coco/efi_secret/12obj-$(CONFIG_EFI_SECRET) += coco/efi_secret/
13obj-$(CONFIG_SEV_GUEST) += coco/sev-guest/13obj-$(CONFIG_SEV_GUEST) += coco/sev-guest/
14obj-$(CONFIG_INTEL_TDX_GUEST) += coco/tdx-guest/
drivers/virt/coco/tdx-guest/Kconfig+10−0
@@ -0,0 +1,10 @@
1config TDX_GUEST_DRIVER
2 tristate "TDX Guest driver"
3 depends on INTEL_TDX_GUEST
4 help
5 The driver provides userspace interface to communicate with
6 the TDX module to request the TDX guest details like attestation
7 report.
8
9 To compile this driver as module, choose M here. The module will
10 be called tdx-guest.
drivers/virt/coco/tdx-guest/Makefile+2−0
@@ -0,0 +1,2 @@
1# SPDX-License-Identifier: GPL-2.0
2obj-$(CONFIG_TDX_GUEST_DRIVER) += tdx-guest.o
drivers/virt/coco/tdx-guest/tdx-guest.c+102−0
@@ -0,0 +1,102 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * TDX guest user interface driver
4 *
5 * Copyright (C) 2022 Intel Corporation
6 */
7
8#include <linux/kernel.h>
9#include <linux/miscdevice.h>
10#include <linux/mm.h>
11#include <linux/module.h>
12#include <linux/mod_devicetable.h>
13#include <linux/string.h>
14#include <linux/uaccess.h>
15
16#include <uapi/linux/tdx-guest.h>
17
18#include <asm/cpu_device_id.h>
19#include <asm/tdx.h>
20
21static long tdx_get_report0(struct tdx_report_req __user *req)
22{
23 u8 *reportdata, *tdreport;
24 long ret;
25
26 reportdata = kmalloc(TDX_REPORTDATA_LEN, GFP_KERNEL);
27 if (!reportdata)
28 return -ENOMEM;
29
30 tdreport = kzalloc(TDX_REPORT_LEN, GFP_KERNEL);
31 if (!tdreport) {
32 ret = -ENOMEM;
33 goto out;
34 }
35
36 if (copy_from_user(reportdata, req->reportdata, TDX_REPORTDATA_LEN)) {
37 ret = -EFAULT;
38 goto out;
39 }
40
41 /* Generate TDREPORT0 using "TDG.MR.REPORT" TDCALL */
42 ret = tdx_mcall_get_report0(reportdata, tdreport);
43 if (ret)
44 goto out;
45
46 if (copy_to_user(req->tdreport, tdreport, TDX_REPORT_LEN))
47 ret = -EFAULT;
48
49out:
50 kfree(reportdata);
51 kfree(tdreport);
52
53 return ret;
54}
55
56static long tdx_guest_ioctl(struct file *file, unsigned int cmd,
57 unsigned long arg)
58{
59 switch (cmd) {
60 case TDX_CMD_GET_REPORT0:
61 return tdx_get_report0((struct tdx_report_req __user *)arg);
62 default:
63 return -ENOTTY;
64 }
65}
66
67static const struct file_operations tdx_guest_fops = {
68 .owner = THIS_MODULE,
69 .unlocked_ioctl = tdx_guest_ioctl,
70 .llseek = no_llseek,
71};
72
73static struct miscdevice tdx_misc_dev = {
74 .name = KBUILD_MODNAME,
75 .minor = MISC_DYNAMIC_MINOR,
76 .fops = &tdx_guest_fops,
77};
78
79static const struct x86_cpu_id tdx_guest_ids[] = {
80 X86_MATCH_FEATURE(X86_FEATURE_TDX_GUEST, NULL),
81 {}
82};
83MODULE_DEVICE_TABLE(x86cpu, tdx_guest_ids);
84
85static int __init tdx_guest_init(void)
86{
87 if (!x86_match_cpu(tdx_guest_ids))
88 return -ENODEV;
89
90 return misc_register(&tdx_misc_dev);
91}
92module_init(tdx_guest_init);
93
94static void __exit tdx_guest_exit(void)
95{
96 misc_deregister(&tdx_misc_dev);
97}
98module_exit(tdx_guest_exit);
99
100MODULE_AUTHOR("Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>");
101MODULE_DESCRIPTION("TDX Guest Driver");
102MODULE_LICENSE("GPL");
include/uapi/linux/tdx-guest.h+42−0
@@ -0,0 +1,42 @@
1/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2/*
3 * Userspace interface for TDX guest driver
4 *
5 * Copyright (C) 2022 Intel Corporation
6 */
7
8#ifndef _UAPI_LINUX_TDX_GUEST_H_
9#define _UAPI_LINUX_TDX_GUEST_H_
10
11#include <linux/ioctl.h>
12#include <linux/types.h>
13
14/* Length of the REPORTDATA used in TDG.MR.REPORT TDCALL */
15#define TDX_REPORTDATA_LEN 64
16
17/* Length of TDREPORT used in TDG.MR.REPORT TDCALL */
18#define TDX_REPORT_LEN 1024
19
20/**
21 * struct tdx_report_req - Request struct for TDX_CMD_GET_REPORT0 IOCTL.
22 *
23 * @reportdata: User buffer with REPORTDATA to be included into TDREPORT.
24 * Typically it can be some nonce provided by attestation
25 * service, so the generated TDREPORT can be uniquely verified.
26 * @tdreport: User buffer to store TDREPORT output from TDCALL[TDG.MR.REPORT].
27 */
28struct tdx_report_req {
29 __u8 reportdata[TDX_REPORTDATA_LEN];
30 __u8 tdreport[TDX_REPORT_LEN];
31};
32
33/*
34 * TDX_CMD_GET_REPORT0 - Get TDREPORT0 (a.k.a. TDREPORT subtype 0) using
35 * TDCALL[TDG.MR.REPORT]
36 *
37 * Return 0 on success, -EIO on TDCALL execution failure, and
38 * standard errno on other general error cases.
39 */
40#define TDX_CMD_GET_REPORT0 _IOWR('T', 1, struct tdx_report_req)
41
42#endif /* _UAPI_LINUX_TDX_GUEST_H_ */
tools/testing/selftests/Makefile+1−0
@@ -74,6 +74,7 @@ TARGETS += sync · 73 unmodified lines
74TARGETS += syscall_user_dispatch74TARGETS += syscall_user_dispatch
75TARGETS += sysctl75TARGETS += sysctl
76TARGETS += tc-testing76TARGETS += tc-testing
77TARGETS += tdx
77TARGETS += timens78TARGETS += timens
78ifneq (1, $(quicktest))79ifneq (1, $(quicktest))
79TARGETS += timers80TARGETS += timers
tools/testing/selftests/tdx/Makefile+7−0
@@ -0,0 +1,7 @@
1# SPDX-License-Identifier: GPL-2.0
2
3CFLAGS += -O3 -Wl,-no-as-needed -Wall -static
4
5TEST_GEN_PROGS := tdx_guest_test
6
7include ../lib.mk
tools/testing/selftests/tdx/config+1−0
@@ -0,0 +1 @@
1CONFIG_TDX_GUEST_DRIVER=y
tools/testing/selftests/tdx/tdx_guest_test.c+163−0
@@ -0,0 +1,163 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Test TDX guest features
4 *
5 * Copyright (C) 2022 Intel Corporation.
6 *
7 * Author: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
8 */
9
10#include <sys/ioctl.h>
11
12#include <errno.h>
13#include <fcntl.h>
14
15#include "../kselftest_harness.h"
16#include "../../../../include/uapi/linux/tdx-guest.h"
17
18#define TDX_GUEST_DEVNAME "/dev/tdx_guest"
19#define HEX_DUMP_SIZE 8
20#define DEBUG 0
21
22/**
23 * struct tdreport_type - Type header of TDREPORT_STRUCT.
24 * @type: Type of the TDREPORT (0 - SGX, 81 - TDX, rest are reserved)
25 * @sub_type: Subtype of the TDREPORT (Default value is 0).
26 * @version: TDREPORT version (Default value is 0).
27 * @reserved: Added for future extension.
28 *
29 * More details can be found in TDX v1.0 module specification, sec
30 * titled "REPORTTYPE".
31 */
32struct tdreport_type {
33 __u8 type;
34 __u8 sub_type;
35 __u8 version;
36 __u8 reserved;
37};
38
39/**
40 * struct reportmac - TDX guest report data, MAC and TEE hashes.
41 * @type: TDREPORT type header.
42 * @reserved1: Reserved for future extension.
43 * @cpu_svn: CPU security version.
44 * @tee_tcb_info_hash: SHA384 hash of TEE TCB INFO.
45 * @tee_td_info_hash: SHA384 hash of TDINFO_STRUCT.
46 * @reportdata: User defined unique data passed in TDG.MR.REPORT request.
47 * @reserved2: Reserved for future extension.
48 * @mac: CPU MAC ID.
49 *
50 * It is MAC-protected and contains hashes of the remainder of the
51 * report structure along with user provided report data. More details can
52 * be found in TDX v1.0 Module specification, sec titled "REPORTMACSTRUCT"
53 */
54struct reportmac {
55 struct tdreport_type type;
56 __u8 reserved1[12];
57 __u8 cpu_svn[16];
58 __u8 tee_tcb_info_hash[48];
59 __u8 tee_td_info_hash[48];
60 __u8 reportdata[64];
61 __u8 reserved2[32];
62 __u8 mac[32];
63};
64
65/**
66 * struct td_info - TDX guest measurements and configuration.
67 * @attr: TDX Guest attributes (like debug, spet_disable, etc).
68 * @xfam: Extended features allowed mask.
69 * @mrtd: Build time measurement register.
70 * @mrconfigid: Software-defined ID for non-owner-defined configuration
71 * of the guest - e.g., run-time or OS configuration.
72 * @mrowner: Software-defined ID for the guest owner.
73 * @mrownerconfig: Software-defined ID for owner-defined configuration of
74 * the guest - e.g., specific to the workload.
75 * @rtmr: Run time measurement registers.
76 * @reserved: Added for future extension.
77 *
78 * It contains the measurements and initial configuration of the TDX guest
79 * that was locked at initialization and a set of measurement registers
80 * that are run-time extendable. More details can be found in TDX v1.0
81 * Module specification, sec titled "TDINFO_STRUCT".
82 */
83struct td_info {
84 __u8 attr[8];
85 __u64 xfam;
86 __u64 mrtd[6];
87 __u64 mrconfigid[6];
88 __u64 mrowner[6];
89 __u64 mrownerconfig[6];
90 __u64 rtmr[24];
91 __u64 reserved[14];
92};
93
94/*
95 * struct tdreport - Output of TDCALL[TDG.MR.REPORT].
96 * @reportmac: Mac protected header of size 256 bytes.
97 * @tee_tcb_info: Additional attestable elements in the TCB are not
98 * reflected in the reportmac.
99 * @reserved: Added for future extension.
100 * @tdinfo: Measurements and configuration data of size 512 bytes.
101 *
102 * More details can be found in TDX v1.0 Module specification, sec
103 * titled "TDREPORT_STRUCT".
104 */
105struct tdreport {
106 struct reportmac reportmac;
107 __u8 tee_tcb_info[239];
108 __u8 reserved[17];
109 struct td_info tdinfo;
110};
111
112static void print_array_hex(const char *title, const char *prefix_str,
113 const void *buf, int len)
114{
115 int i, j, line_len, rowsize = HEX_DUMP_SIZE;
116 const __u8 *ptr = buf;
117
118 printf("\t\t%s", title);
119
120 for (j = 0; j < len; j += rowsize) {
121 line_len = rowsize < (len - j) ? rowsize : (len - j);
122 printf("%s%.8x:", prefix_str, j);
123 for (i = 0; i < line_len; i++)
124 printf(" %.2x", ptr[j + i]);
125 printf("\n");
126 }
127
128 printf("\n");
129}
130
131TEST(verify_report)
132{
133 struct tdx_report_req req;
134 struct tdreport *tdreport;
135 int devfd, i;
136
137 devfd = open(TDX_GUEST_DEVNAME, O_RDWR | O_SYNC);
138 ASSERT_LT(0, devfd);
139
140 /* Generate sample report data */
141 for (i = 0; i < TDX_REPORTDATA_LEN; i++)
142 req.reportdata[i] = i;
143
144 /* Get TDREPORT */
145 ASSERT_EQ(0, ioctl(devfd, TDX_CMD_GET_REPORT0, &req));
146
147 if (DEBUG) {
148 print_array_hex("\n\t\tTDX report data\n", "",
149 req.reportdata, sizeof(req.reportdata));
150
151 print_array_hex("\n\t\tTDX tdreport data\n", "",
152 req.tdreport, sizeof(req.tdreport));
153 }
154
155 /* Make sure TDREPORT data includes the REPORTDATA passed */
156 tdreport = (struct tdreport *)req.tdreport;
157 ASSERT_EQ(0, memcmp(&tdreport->reportmac.reportdata[0],
158 req.reportdata, sizeof(req.reportdata)));
159
160 ASSERT_EQ(0, close(devfd));
161}
162
163TEST_HARNESS_MAIN

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t