...
...
34
- a recent version of Coconut SVSM [4] containing an ephemeral vTPM
34
- a recent version of Coconut SVSM [4] containing an ephemeral vTPM
35
- a PoC [5] containing a stateful vTPM used for sealing/unsealing a LUKS key
35
- a PoC [5] containing a stateful vTPM used for sealing/unsealing a LUKS key
36
36
37
Changelog:
37
Changelog:
38
38
39
v5 -> v6
39
v6 -> v7:
40
- Moved snp_svsm_vtpm_probe() call from the driver to sev/core.c to register
41
the device only when it's really available [Borislav]
42
- s/device/devices in pr_info [Tom]
43
- Added Jarkko's R-b on patches 3 and 4
44
- Updated some commit descriptions to reflect the current implementation
45
46
v5 -> v6: https://lore.kernel.org/linux-integrity/20250403100943.120738-1-sgarzare@redhat.com/
40
- Removed the `locality` field (set to 0) and the FIXME comment [Jarkko]
47
- Removed the `locality` field (set to 0) and the FIXME comment [Jarkko]
41
- Added Tom's R-b on patch 4
48
- Added Tom's R-b on patch 4
42
49
43
v4 -> v5: https://lore.kernel.org/linux-integrity/20250331103900.92701-1-sgarzare@redhat.com/
50
v4 -> v5: https://lore.kernel.org/linux-integrity/20250331103900.92701-1-sgarzare@redhat.com/
44
- Added stubs when !CONFIG_AMD_MEM_ENCRYPT [Dionna]
51
- Added stubs when !CONFIG_AMD_MEM_ENCRYPT [Dionna]
...
...
106
x86/sev: add SVSM vTPM probe/send_command functions
113
x86/sev: add SVSM vTPM probe/send_command functions
107
svsm: add header with SVSM_VTPM_CMD helpers
114
svsm: add header with SVSM_VTPM_CMD helpers
108
tpm: add SNP SVSM vTPM driver
115
tpm: add SNP SVSM vTPM driver
109
x86/sev: register tpm-svsm platform device
116
x86/sev: register tpm-svsm platform device
110
117
111
arch/x86/include/asm/sev.h | 9 +++
118
arch/x86/include/asm/sev.h | 7 ++
112
include/linux/tpm_svsm.h | 149 ++++++++++++++++++++++++++++++++++++
119
include/linux/tpm_svsm.h | 149 ++++++++++++++++++++++++++++++++++++
113
arch/x86/coco/sev/core.c | 67 ++++++++++++++++
120
arch/x86/coco/sev/core.c | 69 ++++++++++++++++-
114
drivers/char/tpm/tpm_svsm.c | 128 +++++++++++++++++++++++++++++++
121
drivers/char/tpm/tpm_svsm.c | 125 ++++++++++++++++++++++++++++++
115
drivers/char/tpm/Kconfig | 10 +++
122
drivers/char/tpm/Kconfig | 10 +++
116
drivers/char/tpm/Makefile | 1 +
123
drivers/char/tpm/Makefile | 1 +
117
6 files changed, 364 insertions(+)
124
6 files changed, 360 insertions(+), 1 deletion(-)
118
create mode 100644 include/linux/tpm_svsm.h
125
create mode 100644 include/linux/tpm_svsm.h
119
create mode 100644 drivers/char/tpm/tpm_svsm.c
126
create mode 100644 drivers/char/tpm/tpm_svsm.c
120
127
121
--
128
--
122
2.49.0
129
2.49.0
diff view generated by jsdifflib
1
From: Stefano Garzarella <sgarzare@redhat.com>
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
2
3
Add two new functions to probe and send commands to the SVSM vTPM.
3
Add two new functions to probe and send commands to the SVSM vTPM.
4
They leverage the two calls defined by the AMD SVSM specification [1]
4
They leverage the two calls defined by the AMD SVSM specification [1]
5
for the vTPM protocol: SVSM_VTPM_QUERY and SVSM_VTPM_CMD.
5
for the vTPM protocol: SVSM_VTPM_QUERY and SVSM_VTPM_CMD.
6
6
7
Expose these functions to be used by other modules such as a tpm
7
Expose snp_svsm_vtpm_send_command() to be used by a tpm driver.
8
driver.
9
8
10
[1] "Secure VM Service Module for SEV-SNP Guests"
9
[1] "Secure VM Service Module for SEV-SNP Guests"
11
Publication # 58019 Revision: 1.00
10
Publication # 58019 Revision: 1.00
12
11
13
Co-developed-by: James Bottomley <James.Bottomley@HansenPartnership.com>
12
Co-developed-by: James Bottomley <James.Bottomley@HansenPartnership.com>
...
...
16
Signed-off-by: Claudio Carvalho <cclaudio@linux.ibm.com>
15
Signed-off-by: Claudio Carvalho <cclaudio@linux.ibm.com>
17
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
16
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
18
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
17
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
19
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
18
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
20
---
19
---
20
v7:
21
- avoided exporting snp_svsm_vtpm_probe() because we will only use it
22
internally
21
v5:
23
v5:
22
- added stubs when !CONFIG_AMD_MEM_ENCRYPT [Dionna]
24
- added stubs when !CONFIG_AMD_MEM_ENCRYPT [Dionna]
23
- added Jarkko's R-b
25
- added Jarkko's R-b
24
v4:
26
v4:
25
- added Tom's R-b
27
- added Tom's R-b
...
...
30
- squashed "x86/sev: add SVSM call macros for the vTPM protocol" patch
32
- squashed "x86/sev: add SVSM call macros for the vTPM protocol" patch
31
in this one [Borislav]
33
in this one [Borislav]
32
- slimmed down snp_svsm_vtpm_probe() [Borislav]
34
- slimmed down snp_svsm_vtpm_probe() [Borislav]
33
- removed features check and any print related [Tom]
35
- removed features check and any print related [Tom]
34
---
36
---
35
arch/x86/include/asm/sev.h | 9 ++++++
37
arch/x86/include/asm/sev.h | 7 +++++
36
arch/x86/coco/sev/core.c | 59 ++++++++++++++++++++++++++++++++++++++
38
arch/x86/coco/sev/core.c | 58 ++++++++++++++++++++++++++++++++++++++
37
2 files changed, 68 insertions(+)
39
2 files changed, 65 insertions(+)
38
40
39
diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
41
diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
40
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
41
--- a/arch/x86/include/asm/sev.h
43
--- a/arch/x86/include/asm/sev.h
42
+++ b/arch/x86/include/asm/sev.h
44
+++ b/arch/x86/include/asm/sev.h
...
...
53
extern u8 snp_vmpl;
55
extern u8 snp_vmpl;
54
@@ -XXX,XX +XXX,XX @@ void snp_msg_free(struct snp_msg_desc *mdesc);
56
@@ -XXX,XX +XXX,XX @@ void snp_msg_free(struct snp_msg_desc *mdesc);
55
int snp_send_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_req *req,
57
int snp_send_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_req *req,
56
             struct snp_guest_request_ioctl *rio);
58
             struct snp_guest_request_ioctl *rio);
57
59
58
+bool snp_svsm_vtpm_probe(void);
59
+int snp_svsm_vtpm_send_command(u8 *buffer);
60
+int snp_svsm_vtpm_send_command(u8 *buffer);
60
+
61
+
61
void __init snp_secure_tsc_prepare(void);
62
void __init snp_secure_tsc_prepare(void);
62
void __init snp_secure_tsc_init(void);
63
void __init snp_secure_tsc_init(void);
63
64
64
@@ -XXX,XX +XXX,XX @@ static inline struct snp_msg_desc *snp_msg_alloc(void) { return NULL; }
65
@@ -XXX,XX +XXX,XX @@ static inline struct snp_msg_desc *snp_msg_alloc(void) { return NULL; }
65
static inline void snp_msg_free(struct snp_msg_desc *mdesc) { }
66
static inline void snp_msg_free(struct snp_msg_desc *mdesc) { }
66
static inline int snp_send_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_req *req,
67
static inline int snp_send_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_req *req,
67
                     struct snp_guest_request_ioctl *rio) { return -ENODEV; }
68
                     struct snp_guest_request_ioctl *rio) { return -ENODEV; }
68
+static inline bool snp_svsm_vtpm_probe(void) { return false; }
69
+static inline int snp_svsm_vtpm_send_command(u8 *buffer) { return -ENODEV; }
69
+static inline int snp_svsm_vtpm_send_command(u8 *buffer) { return -ENODEV; }
70
static inline void __init snp_secure_tsc_prepare(void) { }
70
static inline void __init snp_secure_tsc_prepare(void) { }
71
static inline void __init snp_secure_tsc_init(void) { }
71
static inline void __init snp_secure_tsc_init(void) { }
72
72
73
diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c
73
diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c
...
...
84
+ * This function checks that there is SVSM and that it supports at least
84
+ * This function checks that there is SVSM and that it supports at least
85
+ * TPM_SEND_COMMAND which is the only request we use so far.
85
+ * TPM_SEND_COMMAND which is the only request we use so far.
86
+ *
86
+ *
87
+ * Return: true if the platform provides a vTPM SVSM device, false otherwise.
87
+ * Return: true if the platform provides a vTPM SVSM device, false otherwise.
88
+ */
88
+ */
89
+bool snp_svsm_vtpm_probe(void)
89
+static bool snp_svsm_vtpm_probe(void)
90
+{
90
+{
91
+    struct svsm_call call = {};
91
+    struct svsm_call call = {};
92
+
92
+
93
+    /* The vTPM device is available only if a SVSM is present */
93
+    /* The vTPM device is available only if a SVSM is present */
94
+    if (!snp_vmpl)
94
+    if (!snp_vmpl)
...
...
101
+        return false;
101
+        return false;
102
+
102
+
103
+    /* Check platform commands contains TPM_SEND_COMMAND - platform command 8 */
103
+    /* Check platform commands contains TPM_SEND_COMMAND - platform command 8 */
104
+    return call.rcx_out & BIT_ULL(8);
104
+    return call.rcx_out & BIT_ULL(8);
105
+}
105
+}
106
+EXPORT_SYMBOL_GPL(snp_svsm_vtpm_probe);
107
+
106
+
108
+/**
107
+/**
109
+ * snp_svsm_vtpm_send_command() - execute a vTPM operation on SVSM
108
+ * snp_svsm_vtpm_send_command() - execute a vTPM operation on SVSM
110
+ * @buffer: A buffer used to both send the command and receive the response.
109
+ * @buffer: A buffer used to both send the command and receive the response.
111
+ *
110
+ *
...
...
diff view generated by jsdifflib
1
From: Stefano Garzarella <sgarzare@redhat.com>
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
2
3
Helpers for the SVSM_VTPM_CMD calls used by the vTPM protocol defined by
3
Helpers for the SVSM_VTPM_CMD calls used by the vTPM protocol defined by
4
the AMD SVSM spec [1].
4
the AMD SVSM spec [1].
5
5
6
The vTPM protocol follows the Official TPM 2.0 Reference Implementation
6
The vTPM protocol follows the Official TPM 2.0 Reference Implementation
7
(originally by Microsoft, now part of the TCG) simulator protocol.
7
(originally by Microsoft, now part of the TCG) simulator protocol.
8
8
9
[1] "Secure VM Service Module for SEV-SNP Guests"
9
[1] "Secure VM Service Module for SEV-SNP Guests"
10
Publication # 58019 Revision: 1.00
10
Publication # 58019 Revision: 1.00
11
11
12
Co-developed-by: James Bottomley <James.Bottomley@HansenPartnership.com>
12
Co-developed-by: James Bottomley <James.Bottomley@HansenPartnership.com>
13
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
13
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
14
Co-developed-by: Claudio Carvalho <cclaudio@linux.ibm.com>
14
Co-developed-by: Claudio Carvalho <cclaudio@linux.ibm.com>
15
Signed-off-by: Claudio Carvalho <cclaudio@linux.ibm.com>
15
Signed-off-by: Claudio Carvalho <cclaudio@linux.ibm.com>
16
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
16
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
17
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
17
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
18
---
18
---
19
v5:
19
v5:
20
- added Jarkko's R-b
20
- added Jarkko's R-b
21
v4:
21
v4:
22
- used svsm_vtpm_ prefix consistently [Jarkko]
22
- used svsm_vtpm_ prefix consistently [Jarkko]
23
- removed __packed where not needed [Jarkko]
23
- removed __packed where not needed [Jarkko]
24
- expanded headers to avoid obfuscation [Jarkko]
24
- expanded headers to avoid obfuscation [Jarkko]
25
- used `buf` instead of `inbuf`/`outbuf` [Jarkko]
25
- used `buf` instead of `inbuf`/`outbuf` [Jarkko]
26
- added more documentation quoting the specification
26
- added more documentation quoting the specification
27
- removed TPM_* macros since we only use TPM_SEND_COMMAND in one place
27
- removed TPM_* macros since we only use TPM_SEND_COMMAND in one place
28
and don't want dependencies on external headers, but put the value
28
and don't want dependencies on external headers, but put the value
29
directly as specified in the AMD SVSM specification
29
directly as specified in the AMD SVSM specification
30
- header renamed in tpm_svsm.h so it will fall under TPM DEVICE DRIVER
30
- header renamed in tpm_svsm.h so it will fall under TPM DEVICE DRIVER
31
section [Borislav, Jarkko]
31
section [Borislav, Jarkko]
32
v3:
32
v3:
33
- renamed header and prefix to make clear it's related to the SVSM vTPM
33
- renamed header and prefix to make clear it's related to the SVSM vTPM
34
protocol
34
protocol
35
- renamed fill/parse functions [Tom]
35
- renamed fill/parse functions [Tom]
36
- removed link to the spec because those URLs are unstable [Borislav]
36
- removed link to the spec because those URLs are unstable [Borislav]
37
---
37
---
38
include/linux/tpm_svsm.h | 149 +++++++++++++++++++++++++++++++++++++++
38
include/linux/tpm_svsm.h | 149 +++++++++++++++++++++++++++++++++++++++
39
1 file changed, 149 insertions(+)
39
1 file changed, 149 insertions(+)
40
create mode 100644 include/linux/tpm_svsm.h
40
create mode 100644 include/linux/tpm_svsm.h
41
41
42
diff --git a/include/linux/tpm_svsm.h b/include/linux/tpm_svsm.h
42
diff --git a/include/linux/tpm_svsm.h b/include/linux/tpm_svsm.h
43
new file mode 100644
43
new file mode 100644
44
index XXXXXXX..XXXXXXX
44
index XXXXXXX..XXXXXXX
45
--- /dev/null
45
--- /dev/null
46
+++ b/include/linux/tpm_svsm.h
46
+++ b/include/linux/tpm_svsm.h
47
@@ -XXX,XX +XXX,XX @@
47
@@ -XXX,XX +XXX,XX @@
48
+/* SPDX-License-Identifier: GPL-2.0-only */
48
+/* SPDX-License-Identifier: GPL-2.0-only */
49
+/*
49
+/*
50
+ * Copyright (C) 2023 James.Bottomley@HansenPartnership.com
50
+ * Copyright (C) 2023 James.Bottomley@HansenPartnership.com
51
+ * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
51
+ * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
52
+ *
52
+ *
53
+ * Helpers for the SVSM_VTPM_CMD calls used by the vTPM protocol defined by the
53
+ * Helpers for the SVSM_VTPM_CMD calls used by the vTPM protocol defined by the
54
+ * AMD SVSM spec [1].
54
+ * AMD SVSM spec [1].
55
+ *
55
+ *
56
+ * The vTPM protocol follows the Official TPM 2.0 Reference Implementation
56
+ * The vTPM protocol follows the Official TPM 2.0 Reference Implementation
57
+ * (originally by Microsoft, now part of the TCG) simulator protocol.
57
+ * (originally by Microsoft, now part of the TCG) simulator protocol.
58
+ *
58
+ *
59
+ * [1] "Secure VM Service Module for SEV-SNP Guests"
59
+ * [1] "Secure VM Service Module for SEV-SNP Guests"
60
+ * Publication # 58019 Revision: 1.00
60
+ * Publication # 58019 Revision: 1.00
61
+ */
61
+ */
62
+#ifndef _TPM_SVSM_H_
62
+#ifndef _TPM_SVSM_H_
63
+#define _TPM_SVSM_H_
63
+#define _TPM_SVSM_H_
64
+
64
+
65
+#include <linux/errno.h>
65
+#include <linux/errno.h>
66
+#include <linux/string.h>
66
+#include <linux/string.h>
67
+#include <linux/types.h>
67
+#include <linux/types.h>
68
+
68
+
69
+#define SVSM_VTPM_MAX_BUFFER        4096 /* max req/resp buffer size */
69
+#define SVSM_VTPM_MAX_BUFFER        4096 /* max req/resp buffer size */
70
+
70
+
71
+/**
71
+/**
72
+ * struct svsm_vtpm_request - Generic request for single word command
72
+ * struct svsm_vtpm_request - Generic request for single word command
73
+ * @cmd:    The command to send
73
+ * @cmd:    The command to send
74
+ *
74
+ *
75
+ * Defined by AMD SVSM spec [1] in section "8.2 SVSM_VTPM_CMD Call" -
75
+ * Defined by AMD SVSM spec [1] in section "8.2 SVSM_VTPM_CMD Call" -
76
+ * Table 15: vTPM Common Request/Response Structure
76
+ * Table 15: vTPM Common Request/Response Structure
77
+ * Byte Size     In/Out    Description
77
+ * Byte Size     In/Out    Description
78
+ * Offset    (Bytes)
78
+ * Offset    (Bytes)
79
+ * 0x000     4          In        Platform command
79
+ * 0x000     4          In        Platform command
80
+ *                         Out       Platform command response size
80
+ *                         Out       Platform command response size
81
+ */
81
+ */
82
+struct svsm_vtpm_request {
82
+struct svsm_vtpm_request {
83
+    u32 cmd;
83
+    u32 cmd;
84
+};
84
+};
85
+
85
+
86
+/**
86
+/**
87
+ * struct svsm_vtpm_response - Generic response
87
+ * struct svsm_vtpm_response - Generic response
88
+ * @size:    The response size (zero if nothing follows)
88
+ * @size:    The response size (zero if nothing follows)
89
+ *
89
+ *
90
+ * Defined by AMD SVSM spec [1] in section "8.2 SVSM_VTPM_CMD Call" -
90
+ * Defined by AMD SVSM spec [1] in section "8.2 SVSM_VTPM_CMD Call" -
91
+ * Table 15: vTPM Common Request/Response Structure
91
+ * Table 15: vTPM Common Request/Response Structure
92
+ * Byte Size     In/Out    Description
92
+ * Byte Size     In/Out    Description
93
+ * Offset    (Bytes)
93
+ * Offset    (Bytes)
94
+ * 0x000     4          In        Platform command
94
+ * 0x000     4          In        Platform command
95
+ *                         Out       Platform command response size
95
+ *                         Out       Platform command response size
96
+ *
96
+ *
97
+ * Note: most TCG Simulator commands simply return zero here with no indication
97
+ * Note: most TCG Simulator commands simply return zero here with no indication
98
+ * of success or failure.
98
+ * of success or failure.
99
+ */
99
+ */
100
+struct svsm_vtpm_response {
100
+struct svsm_vtpm_response {
101
+    u32 size;
101
+    u32 size;
102
+};
102
+};
103
+
103
+
104
+/**
104
+/**
105
+ * struct svsm_vtpm_cmd_request - Structure for a TPM_SEND_COMMAND request
105
+ * struct svsm_vtpm_cmd_request - Structure for a TPM_SEND_COMMAND request
106
+ * @cmd:    The command to send (must be TPM_SEND_COMMAND)
106
+ * @cmd:    The command to send (must be TPM_SEND_COMMAND)
107
+ * @locality:    The locality
107
+ * @locality:    The locality
108
+ * @buf_size:    The size of the input buffer following
108
+ * @buf_size:    The size of the input buffer following
109
+ * @buf:    A buffer of size buf_size
109
+ * @buf:    A buffer of size buf_size
110
+ *
110
+ *
111
+ * Defined by AMD SVSM spec [1] in section "8.2 SVSM_VTPM_CMD Call" -
111
+ * Defined by AMD SVSM spec [1] in section "8.2 SVSM_VTPM_CMD Call" -
112
+ * Table 16: TPM_SEND_COMMAND Request Structure
112
+ * Table 16: TPM_SEND_COMMAND Request Structure
113
+ * Byte Size Meaning
113
+ * Byte Size Meaning
114
+ * Offset    (Bytes)
114
+ * Offset    (Bytes)
115
+ * 0x000     4          Platform command (8)
115
+ * 0x000     4          Platform command (8)
116
+ * 0x004     1          Locality (must-be-0)
116
+ * 0x004     1          Locality (must-be-0)
117
+ * 0x005     4          TPM Command size (in bytes)
117
+ * 0x005     4          TPM Command size (in bytes)
118
+ * 0x009     Variable   TPM Command
118
+ * 0x009     Variable   TPM Command
119
+ *
119
+ *
120
+ * Note: the TCG Simulator expects @buf_size to be equal to the size of the
120
+ * Note: the TCG Simulator expects @buf_size to be equal to the size of the
121
+ * specific TPM command, otherwise an TPM_RC_COMMAND_SIZE error is returned.
121
+ * specific TPM command, otherwise an TPM_RC_COMMAND_SIZE error is returned.
122
+ */
122
+ */
123
+struct svsm_vtpm_cmd_request {
123
+struct svsm_vtpm_cmd_request {
124
+    u32 cmd;
124
+    u32 cmd;
125
+    u8 locality;
125
+    u8 locality;
126
+    u32 buf_size;
126
+    u32 buf_size;
127
+    u8 buf[];
127
+    u8 buf[];
128
+} __packed;
128
+} __packed;
129
+
129
+
130
+/**
130
+/**
131
+ * struct svsm_vtpm_cmd_response - Structure for a TPM_SEND_COMMAND response
131
+ * struct svsm_vtpm_cmd_response - Structure for a TPM_SEND_COMMAND response
132
+ * @buf_size:    The size of the output buffer following
132
+ * @buf_size:    The size of the output buffer following
133
+ * @buf:    A buffer of size buf_size
133
+ * @buf:    A buffer of size buf_size
134
+ *
134
+ *
135
+ * Defined by AMD SVSM spec [1] in section "8.2 SVSM_VTPM_CMD Call" -
135
+ * Defined by AMD SVSM spec [1] in section "8.2 SVSM_VTPM_CMD Call" -
136
+ * Table 17: TPM_SEND_COMMAND Response Structure
136
+ * Table 17: TPM_SEND_COMMAND Response Structure
137
+ * Byte Size Meaning
137
+ * Byte Size Meaning
138
+ * Offset    (Bytes)
138
+ * Offset    (Bytes)
139
+ * 0x000     4          Response size (in bytes)
139
+ * 0x000     4          Response size (in bytes)
140
+ * 0x004     Variable   Response
140
+ * 0x004     Variable   Response
141
+ */
141
+ */
142
+struct svsm_vtpm_cmd_response {
142
+struct svsm_vtpm_cmd_response {
143
+    u32 buf_size;
143
+    u32 buf_size;
144
+    u8 buf[];
144
+    u8 buf[];
145
+};
145
+};
146
+
146
+
147
+/**
147
+/**
148
+ * svsm_vtpm_cmd_request_fill() - Fill a TPM_SEND_COMMAND request to be sent to SVSM
148
+ * svsm_vtpm_cmd_request_fill() - Fill a TPM_SEND_COMMAND request to be sent to SVSM
149
+ * @req: The struct svsm_vtpm_cmd_request to fill
149
+ * @req: The struct svsm_vtpm_cmd_request to fill
150
+ * @locality: The locality
150
+ * @locality: The locality
151
+ * @buf: The buffer from where to copy the payload of the command
151
+ * @buf: The buffer from where to copy the payload of the command
152
+ * @len: The size of the buffer
152
+ * @len: The size of the buffer
153
+ *
153
+ *
154
+ * Return: 0 on success, negative error code on failure.
154
+ * Return: 0 on success, negative error code on failure.
155
+ */
155
+ */
156
+static inline int
156
+static inline int
157
+svsm_vtpm_cmd_request_fill(struct svsm_vtpm_cmd_request *req, u8 locality,
157
+svsm_vtpm_cmd_request_fill(struct svsm_vtpm_cmd_request *req, u8 locality,
158
+             const u8 *buf, size_t len)
158
+             const u8 *buf, size_t len)
159
+{
159
+{
160
+    if (len > SVSM_VTPM_MAX_BUFFER - sizeof(*req))
160
+    if (len > SVSM_VTPM_MAX_BUFFER - sizeof(*req))
161
+        return -EINVAL;
161
+        return -EINVAL;
162
+
162
+
163
+    req->cmd = 8; /* TPM_SEND_COMMAND */
163
+    req->cmd = 8; /* TPM_SEND_COMMAND */
164
+    req->locality = locality;
164
+    req->locality = locality;
165
+    req->buf_size = len;
165
+    req->buf_size = len;
166
+
166
+
167
+    memcpy(req->buf, buf, len);
167
+    memcpy(req->buf, buf, len);
168
+
168
+
169
+    return 0;
169
+    return 0;
170
+}
170
+}
171
+
171
+
172
+/**
172
+/**
173
+ * svsm_vtpm_cmd_response_parse() - Parse a TPM_SEND_COMMAND response received from SVSM
173
+ * svsm_vtpm_cmd_response_parse() - Parse a TPM_SEND_COMMAND response received from SVSM
174
+ * @resp: The struct svsm_vtpm_cmd_response to parse
174
+ * @resp: The struct svsm_vtpm_cmd_response to parse
175
+ * @buf: The buffer where to copy the response
175
+ * @buf: The buffer where to copy the response
176
+ * @len: The size of the buffer
176
+ * @len: The size of the buffer
177
+ *
177
+ *
178
+ * Return: buffer size filled with the response on success, negative error
178
+ * Return: buffer size filled with the response on success, negative error
179
+ * code on failure.
179
+ * code on failure.
180
+ */
180
+ */
181
+static inline int
181
+static inline int
182
+svsm_vtpm_cmd_response_parse(const struct svsm_vtpm_cmd_response *resp, u8 *buf,
182
+svsm_vtpm_cmd_response_parse(const struct svsm_vtpm_cmd_response *resp, u8 *buf,
183
+             size_t len)
183
+             size_t len)
184
+{
184
+{
185
+    if (len < resp->buf_size)
185
+    if (len < resp->buf_size)
186
+        return -E2BIG;
186
+        return -E2BIG;
187
+
187
+
188
+    if (resp->buf_size > SVSM_VTPM_MAX_BUFFER - sizeof(*resp))
188
+    if (resp->buf_size > SVSM_VTPM_MAX_BUFFER - sizeof(*resp))
189
+        return -EINVAL; // Invalid response from the platform TPM
189
+        return -EINVAL; // Invalid response from the platform TPM
190
+
190
+
191
+    memcpy(buf, resp->buf, resp->buf_size);
191
+    memcpy(buf, resp->buf, resp->buf_size);
192
+
192
+
193
+    return resp->buf_size;
193
+    return resp->buf_size;
194
+}
194
+}
195
+
195
+
196
+#endif /* _TPM_SVSM_H_ */
196
+#endif /* _TPM_SVSM_H_ */
197
--
197
--
198
2.49.0
198
2.49.0
199
199
diff view generated by jsdifflib
...
...
4
4
5
The specification defines a protocol that a SEV-SNP guest OS can use to
5
The specification defines a protocol that a SEV-SNP guest OS can use to
6
discover and talk to a vTPM emulated by the Secure VM Service Module (SVSM)
6
discover and talk to a vTPM emulated by the Secure VM Service Module (SVSM)
7
in the guest context, but at a more privileged level (VMPL0).
7
in the guest context, but at a more privileged level (VMPL0).
8
8
9
The new tpm-svsm platform driver uses two functions exposed by x86/sev
9
The new tpm-svsm platform driver uses API exposed by x86/sev to send
10
to verify that the device is actually emulated by the platform and to
10
commands and receive responses.
11
send commands and receive responses.
12
11
13
The device cannot be hot-plugged/unplugged as it is emulated by the
12
The device cannot be hot-plugged/unplugged as it is emulated by the
14
platform, so we can use module_platform_driver_probe(). The probe
13
platform, so we can use module_platform_driver_probe(). The device will
15
function will only check whether in the current runtime configuration,
14
be registered by the platform only when it's available, so the probe
16
SVSM is present and provides a vTPM.
15
function just needs to setup the tpm_chip.
17
16
18
This device does not support interrupts and sends responses to commands
17
This device does not support interrupts and sends responses to commands
19
synchronously. In order to have .recv() called just after .send() in
18
synchronously.
20
tpm_try_transmit(), the .status() callback returns 0, and both
19
In order to have .recv() called just after .send() in tpm_try_transmit(),
21
.req_complete_mask and .req_complete_val are set to 0.
20
the .status() callback is not implemented as recently supported by
21
commit 980a573621ea ("tpm: Make chip->{status,cancel,req_canceled} opt").
22
22
23
[1] "Secure VM Service Module for SEV-SNP Guests"
23
[1] "Secure VM Service Module for SEV-SNP Guests"
24
Publication # 58019 Revision: 1.00
24
Publication # 58019 Revision: 1.00
25
25
26
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
26
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
27
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
27
---
28
---
29
v7:
30
- added Jarkko's R-b
31
- avoided to call snp_svsm_vtpm_probe() since the device will be
32
registered by SEV core only if the device is detected [Borislav]
33
- updated commit description
28
v6:
34
v6:
29
- removed the `locality` field (set to 0) and the FIXME comment [Jarkko]
35
- removed the `locality` field (set to 0) and the FIXME comment [Jarkko]
30
v5:
36
v5:
31
- removed cancel/status/req_* ops after rebase on master that cotains
37
- removed cancel/status/req_* ops after rebase on master that cotains
32
commit 980a573621ea ("tpm: Make chip->{status,cancel,req_canceled} opt")
38
commit 980a573621ea ("tpm: Make chip->{status,cancel,req_canceled} opt")
...
...
36
v3:
42
v3:
37
- removed send_recv() ops and followed the ftpm driver implementing .status,
43
- removed send_recv() ops and followed the ftpm driver implementing .status,
38
.req_complete_mask, .req_complete_val, etc. [Jarkko]
44
.req_complete_mask, .req_complete_val, etc. [Jarkko]
39
- removed link to the spec because those URLs are unstable [Borislav]
45
- removed link to the spec because those URLs are unstable [Borislav]
40
---
46
---
41
drivers/char/tpm/tpm_svsm.c | 128 ++++++++++++++++++++++++++++++++++++
47
drivers/char/tpm/tpm_svsm.c | 125 ++++++++++++++++++++++++++++++++++++
42
drivers/char/tpm/Kconfig | 10 +++
48
drivers/char/tpm/Kconfig | 10 +++
43
drivers/char/tpm/Makefile | 1 +
49
drivers/char/tpm/Makefile | 1 +
44
3 files changed, 139 insertions(+)
50
3 files changed, 136 insertions(+)
45
create mode 100644 drivers/char/tpm/tpm_svsm.c
51
create mode 100644 drivers/char/tpm/tpm_svsm.c
46
52
47
diff --git a/drivers/char/tpm/tpm_svsm.c b/drivers/char/tpm/tpm_svsm.c
53
diff --git a/drivers/char/tpm/tpm_svsm.c b/drivers/char/tpm/tpm_svsm.c
48
new file mode 100644
54
new file mode 100644
49
index XXXXXXX..XXXXXXX
55
index XXXXXXX..XXXXXXX
...
...
116
+    struct device *dev = &pdev->dev;
122
+    struct device *dev = &pdev->dev;
117
+    struct tpm_svsm_priv *priv;
123
+    struct tpm_svsm_priv *priv;
118
+    struct tpm_chip *chip;
124
+    struct tpm_chip *chip;
119
+    int err;
125
+    int err;
120
+
126
+
121
+    if (!snp_svsm_vtpm_probe())
122
+        return -ENODEV;
123
+
124
+    priv = devm_kmalloc(dev, sizeof(*priv), GFP_KERNEL);
127
+    priv = devm_kmalloc(dev, sizeof(*priv), GFP_KERNEL);
125
+    if (!priv)
128
+    if (!priv)
126
+        return -ENOMEM;
129
+        return -ENOMEM;
127
+
130
+
128
+    /*
131
+    /*
...
...
diff view generated by jsdifflib
...
...
3
SNP platform can provide a vTPM device emulated by SVSM.
3
SNP platform can provide a vTPM device emulated by SVSM.
4
4
5
The "tpm-svsm" device can be handled by the platform driver added
5
The "tpm-svsm" device can be handled by the platform driver added
6
by the previous commit in drivers/char/tpm/tpm_svsm.c
6
by the previous commit in drivers/char/tpm/tpm_svsm.c
7
7
8
Register the device unconditionally. The support check (e.g. SVSM, cmd)
8
Register the platform device only when SVSM is available and it
9
is in snp_svsm_vtpm_probe(), keeping all logic in one place.
9
supports vTPM commands as checked by snp_svsm_vtpm_probe().
10
This function is called during the driver's probe along with other
11
setup tasks like memory allocation.
12
10
13
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
11
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
12
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
14
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
13
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
15
---
14
---
15
v7:
16
- added Jarkko's R-b
17
- call snp_svsm_vtpm_probe() before registering the device [Borislav]
18
- s/device/devices in pr_info [Tom]
19
- updated commit description
16
v6:
20
v6:
17
- added Tom's R-b
21
- added Tom's R-b
18
v4:
22
v4:
19
- explained better why we register it anyway in the commit message
23
- explained better why we register it anyway in the commit message
20
---
24
---
21
arch/x86/coco/sev/core.c | 8 ++++++++
25
arch/x86/coco/sev/core.c | 11 ++++++++++-
22
1 file changed, 8 insertions(+)
26
1 file changed, 10 insertions(+), 1 deletion(-)
23
27
24
diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c
28
diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c
25
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
26
--- a/arch/x86/coco/sev/core.c
30
--- a/arch/x86/coco/sev/core.c
27
+++ b/arch/x86/coco/sev/core.c
31
+++ b/arch/x86/coco/sev/core.c
...
...
39
    if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP))
43
    if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP))
40
@@ -XXX,XX +XXX,XX @@ static int __init snp_init_platform_device(void)
44
@@ -XXX,XX +XXX,XX @@ static int __init snp_init_platform_device(void)
41
    if (platform_device_register(&sev_guest_device))
45
    if (platform_device_register(&sev_guest_device))
42
        return -ENODEV;
46
        return -ENODEV;
43
47
44
+    if (platform_device_register(&tpm_svsm_device))
48
-    pr_info("SNP guest platform device initialized.\n");
49
+    if (snp_svsm_vtpm_probe() &&
50
+     platform_device_register(&tpm_svsm_device))
45
+        return -ENODEV;
51
+        return -ENODEV;
46
+
52
+
47
    pr_info("SNP guest platform device initialized.\n");
53
+    pr_info("SNP guest platform devices initialized.\n");
48
    return 0;
54
    return 0;
49
}
55
}
56
device_initcall(snp_init_platform_device);
50
--
57
--
51
2.49.0
58
2.49.0
diff view generated by jsdifflib