Skip to content

Commit 627dc67

Browse files
tlendackybp3tk0v
authored andcommitted
x86/sev: Extend the config-fs attestation support for an SVSM
When an SVSM is present, the guest can also request attestation reports from it. These SVSM attestation reports can be used to attest the SVSM and any services running within the SVSM. Extend the config-fs attestation support to provide such. This involves creating four new config-fs attributes: - 'service-provider' (input) This attribute is used to determine whether the attestation request should be sent to the specified service provider or to the SEV firmware. The SVSM service provider is represented by the value 'svsm'. - 'service_guid' (input) Used for requesting the attestation of a single service within the service provider. A null GUID implies that the SVSM_ATTEST_SERVICES call should be used to request the attestation report. A non-null GUID implies that the SVSM_ATTEST_SINGLE_SERVICE call should be used. - 'service_manifest_version' (input) Used with the SVSM_ATTEST_SINGLE_SERVICE call, the service version represents a specific service manifest version be used for the attestation report. - 'manifestblob' (output) Used to return the service manifest associated with the attestation report. Only display these new attributes when running under an SVSM. [ bp: Massage. - s/svsm_attestation_call/svsm_attest_call/g ] Signed-off-by: Tom Lendacky <[email protected]> Signed-off-by: Borislav Petkov (AMD) <[email protected]> Link: https://lore.kernel.org/r/965015dce3c76bb8724839d50c5dea4e4b5d598f.1717600736.git.thomas.lendacky@amd.com
1 parent 20dfee9 commit 627dc67

File tree

6 files changed

+433
-3
lines changed

6 files changed

+433
-3
lines changed

Documentation/ABI/testing/configfs-tsm

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,18 @@ Description:
3131
Standardization v2.03 Section 4.1.8.1 MSG_REPORT_REQ.
3232
https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/56421.pdf
3333

34+
What: /sys/kernel/config/tsm/report/$name/manifestblob
35+
Date: January, 2024
36+
KernelVersion: v6.10
37+
38+
Description:
39+
(RO) Optional supplemental data that a TSM may emit, visibility
40+
of this attribute depends on TSM, and may be empty if no
41+
manifest data is available.
42+
43+
See 'service_provider' for information on the format of the
44+
manifest blob.
45+
3446
What: /sys/kernel/config/tsm/report/$name/provider
3547
Date: September, 2023
3648
KernelVersion: v6.7
@@ -80,3 +92,55 @@ Contact: [email protected]
8092
Description:
8193
(RO) Indicates the minimum permissible value that can be written
8294
to @privlevel.
95+
96+
What: /sys/kernel/config/tsm/report/$name/service_provider
97+
Date: January, 2024
98+
KernelVersion: v6.10
99+
100+
Description:
101+
(WO) Attribute is visible if a TSM implementation provider
102+
supports the concept of attestation reports from a service
103+
provider for TVMs, like SEV-SNP running under an SVSM.
104+
Specifying the service provider via this attribute will create
105+
an attestation report as specified by the service provider.
106+
Currently supported service-providers are:
107+
svsm
108+
109+
For the "svsm" service provider, see the Secure VM Service Module
110+
for SEV-SNP Guests v1.00 Section 7. For the doc, search for
111+
"site:amd.com "Secure VM Service Module for SEV-SNP
112+
Guests", docID: 58019"
113+
114+
What: /sys/kernel/config/tsm/report/$name/service_guid
115+
Date: January, 2024
116+
KernelVersion: v6.10
117+
118+
Description:
119+
(WO) Attribute is visible if a TSM implementation provider
120+
supports the concept of attestation reports from a service
121+
provider for TVMs, like SEV-SNP running under an SVSM.
122+
Specifying an empty/null GUID (00000000-0000-0000-0000-000000)
123+
requests all active services within the service provider be
124+
part of the attestation report. Specifying a GUID request
125+
an attestation report of just the specified service using the
126+
manifest form specified by the service_manifest_version
127+
attribute.
128+
129+
See 'service_provider' for information on the format of the
130+
service guid.
131+
132+
What: /sys/kernel/config/tsm/report/$name/service_manifest_version
133+
Date: January, 2024
134+
KernelVersion: v6.10
135+
136+
Description:
137+
(WO) Attribute is visible if a TSM implementation provider
138+
supports the concept of attestation reports from a service
139+
provider for TVMs, like SEV-SNP running under an SVSM.
140+
Indicates the service manifest version requested for the
141+
attestation report (default 0). If this field is not set by
142+
the user, the default manifest version of the service (the
143+
service's initial/first manifest version) is returned.
144+
145+
See 'service_provider' for information on the format of the
146+
service manifest version.

arch/x86/include/asm/sev.h

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,27 @@ struct svsm_pvalidate_call {
213213
offsetof(struct svsm_pvalidate_call, entry)) / \
214214
sizeof(struct svsm_pvalidate_entry))
215215

216+
/*
217+
* The SVSM Attestation related structures
218+
*/
219+
struct svsm_loc_entry {
220+
u64 pa;
221+
u32 len;
222+
u8 rsvd[4];
223+
};
224+
225+
struct svsm_attest_call {
226+
struct svsm_loc_entry report_buf;
227+
struct svsm_loc_entry nonce;
228+
struct svsm_loc_entry manifest_buf;
229+
struct svsm_loc_entry certificates_buf;
230+
231+
/* For attesting a single service */
232+
u8 service_guid[16];
233+
u32 service_manifest_ver;
234+
u8 rsvd[4];
235+
};
236+
216237
/*
217238
* SVSM protocol structure
218239
*/
@@ -236,6 +257,10 @@ struct svsm_call {
236257
#define SVSM_CORE_CREATE_VCPU 2
237258
#define SVSM_CORE_DELETE_VCPU 3
238259

260+
#define SVSM_ATTEST_CALL(x) ((1ULL << 32) | (x))
261+
#define SVSM_ATTEST_SERVICES 0
262+
#define SVSM_ATTEST_SINGLE_SERVICE 1
263+
239264
#ifdef CONFIG_AMD_MEM_ENCRYPT
240265

241266
extern u8 snp_vmpl;
@@ -317,6 +342,7 @@ bool snp_init(struct boot_params *bp);
317342
void __noreturn snp_abort(void);
318343
void snp_dmi_setup(void);
319344
int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, struct snp_guest_request_ioctl *rio);
345+
int snp_issue_svsm_attest_req(u64 call_id, struct svsm_call *call, struct svsm_attest_call *input);
320346
void snp_accept_memory(phys_addr_t start, phys_addr_t end);
321347
u64 snp_get_unsupported_features(u64 status);
322348
u64 sev_get_status(void);
@@ -349,7 +375,10 @@ static inline int snp_issue_guest_request(u64 exit_code, struct snp_req_data *in
349375
{
350376
return -ENOTTY;
351377
}
352-
378+
static inline int snp_issue_svsm_attest_req(u64 call_id, struct svsm_call *call, struct svsm_attest_call *input)
379+
{
380+
return -ENOTTY;
381+
}
353382
static inline void snp_accept_memory(phys_addr_t start, phys_addr_t end) { }
354383
static inline u64 snp_get_unsupported_features(u64 status) { return 0; }
355384
static inline u64 sev_get_status(void) { return 0; }

arch/x86/kernel/sev.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2387,6 +2387,56 @@ static int __init init_sev_config(char *str)
23872387
}
23882388
__setup("sev=", init_sev_config);
23892389

2390+
static void update_attest_input(struct svsm_call *call, struct svsm_attest_call *input)
2391+
{
2392+
/* If (new) lengths have been returned, propagate them up */
2393+
if (call->rcx_out != call->rcx)
2394+
input->manifest_buf.len = call->rcx_out;
2395+
2396+
if (call->rdx_out != call->rdx)
2397+
input->certificates_buf.len = call->rdx_out;
2398+
2399+
if (call->r8_out != call->r8)
2400+
input->report_buf.len = call->r8_out;
2401+
}
2402+
2403+
int snp_issue_svsm_attest_req(u64 call_id, struct svsm_call *call,
2404+
struct svsm_attest_call *input)
2405+
{
2406+
struct svsm_attest_call *ac;
2407+
unsigned long flags;
2408+
u64 attest_call_pa;
2409+
int ret;
2410+
2411+
if (!snp_vmpl)
2412+
return -EINVAL;
2413+
2414+
local_irq_save(flags);
2415+
2416+
call->caa = svsm_get_caa();
2417+
2418+
ac = (struct svsm_attest_call *)call->caa->svsm_buffer;
2419+
attest_call_pa = svsm_get_caa_pa() + offsetof(struct svsm_ca, svsm_buffer);
2420+
2421+
*ac = *input;
2422+
2423+
/*
2424+
* Set input registers for the request and set RDX and R8 to known
2425+
* values in order to detect length values being returned in them.
2426+
*/
2427+
call->rax = call_id;
2428+
call->rcx = attest_call_pa;
2429+
call->rdx = -1;
2430+
call->r8 = -1;
2431+
ret = svsm_perform_call_protocol(call);
2432+
update_attest_input(call, input);
2433+
2434+
local_irq_restore(flags);
2435+
2436+
return ret;
2437+
}
2438+
EXPORT_SYMBOL_GPL(snp_issue_svsm_attest_req);
2439+
23902440
int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, struct snp_guest_request_ioctl *rio)
23912441
{
23922442
struct ghcb_state state;

0 commit comments

Comments
 (0)