Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 4083235

Browse files
committed
Merge tag 'x86_sev_for_v6.11_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 SEV updates from Borislav Petkov: - Add support for running the kernel in a SEV-SNP guest, over a Secure VM Service Module (SVSM). When running over a SVSM, different services can run at different protection levels, apart from the guest OS but still within the secure SNP environment. They can provide services to the guest, like a vTPM, for example. This series adds the required facilities to interface with such a SVSM module. - The usual fixlets, refactoring and cleanups [ And as always: "SEV" is AMD's "Secure Encrypted Virtualization". I can't be the only one who gets all the newer x86 TLA's confused, can I? - Linus ] * tag 'x86_sev_for_v6.11_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: Documentation/ABI/configfs-tsm: Fix an unexpected indentation silly x86/sev: Do RMP memory coverage check after max_pfn has been set x86/sev: Move SEV compilation units virt: sev-guest: Mark driver struct with __refdata to prevent section mismatch x86/sev: Allow non-VMPL0 execution when an SVSM is present x86/sev: Extend the config-fs attestation support for an SVSM x86/sev: Take advantage of configfs visibility support in TSM fs/configfs: Add a callback to determine attribute visibility sev-guest: configfs-tsm: Allow the privlevel_floor attribute to be updated virt: sev-guest: Choose the VMPCK key based on executing VMPL x86/sev: Provide guest VMPL level to userspace x86/sev: Provide SVSM discovery support x86/sev: Use the SVSM to create a vCPU when not in VMPL0 x86/sev: Perform PVALIDATE using the SVSM when not at VMPL0 x86/sev: Use kernel provided SVSM Calling Areas x86/sev: Check for the presence of an SVSM in the SNP secrets page x86/irqflags: Provide native versions of the local_irq_save()/restore()
2 parents b84b338 + 5fa96c7 commit 4083235

File tree

24 files changed

+1658
-189
lines changed

24 files changed

+1658
-189
lines changed

Documentation/ABI/testing/configfs-tsm

Lines changed: 63 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+
Contact: linux-coco@lists.linux.dev
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,54 @@ Contact: linux-coco@lists.linux.dev
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+
Contact: linux-coco@lists.linux.dev
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+
The only currently supported service provider is "svsm".
107+
108+
For the "svsm" service provider, see the Secure VM Service Module
109+
for SEV-SNP Guests v1.00 Section 7. For the doc, search for
110+
"site:amd.com "Secure VM Service Module for SEV-SNP
111+
Guests", docID: 58019"
112+
113+
What: /sys/kernel/config/tsm/report/$name/service_guid
114+
Date: January, 2024
115+
KernelVersion: v6.10
116+
Contact: linux-coco@lists.linux.dev
117+
Description:
118+
(WO) Attribute is visible if a TSM implementation provider
119+
supports the concept of attestation reports from a service
120+
provider for TVMs, like SEV-SNP running under an SVSM.
121+
Specifying an empty/null GUID (00000000-0000-0000-0000-000000)
122+
requests all active services within the service provider be
123+
part of the attestation report. Specifying a GUID request
124+
an attestation report of just the specified service using the
125+
manifest form specified by the service_manifest_version
126+
attribute.
127+
128+
See 'service_provider' for information on the format of the
129+
service guid.
130+
131+
What: /sys/kernel/config/tsm/report/$name/service_manifest_version
132+
Date: January, 2024
133+
KernelVersion: v6.10
134+
Contact: linux-coco@lists.linux.dev
135+
Description:
136+
(WO) Attribute is visible if a TSM implementation provider
137+
supports the concept of attestation reports from a service
138+
provider for TVMs, like SEV-SNP running under an SVSM.
139+
Indicates the service manifest version requested for the
140+
attestation report (default 0). If this field is not set by
141+
the user, the default manifest version of the service (the
142+
service's initial/first manifest version) is returned.
143+
144+
See 'service_provider' for information on the format of the
145+
service manifest version.

Documentation/ABI/testing/sysfs-devices-system-cpu

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,18 @@ Description: Umwait control
605605
Note that a value of zero means there is no limit.
606606
Low order two bits must be zero.
607607

608+
What: /sys/devices/system/cpu/sev
609+
/sys/devices/system/cpu/sev/vmpl
610+
Date: May 2024
611+
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
612+
Description: Secure Encrypted Virtualization (SEV) information
613+
614+
This directory is only present when running as an SEV-SNP guest.
615+
616+
vmpl: Reports the Virtual Machine Privilege Level (VMPL) at which
617+
the SEV-SNP guest is running.
618+
619+
608620
What: /sys/devices/system/cpu/svm
609621
Date: August 2019
610622
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>

Documentation/arch/x86/amd-memory-encryption.rst

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,31 @@ SNP feature support.
130130

131131
More details in AMD64 APM[1] Vol 2: 15.34.10 SEV_STATUS MSR
132132

133-
[1] https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/programmer-references/24593.pdf
133+
Secure VM Service Module (SVSM)
134+
===============================
135+
SNP provides a feature called Virtual Machine Privilege Levels (VMPL) which
136+
defines four privilege levels at which guest software can run. The most
137+
privileged level is 0 and numerically higher numbers have lesser privileges.
138+
More details in the AMD64 APM Vol 2, section "15.35.7 Virtual Machine
139+
Privilege Levels", docID: 24593.
140+
141+
When using that feature, different services can run at different protection
142+
levels, apart from the guest OS but still within the secure SNP environment.
143+
They can provide services to the guest, like a vTPM, for example.
144+
145+
When a guest is not running at VMPL0, it needs to communicate with the software
146+
running at VMPL0 to perform privileged operations or to interact with secure
147+
services. An example fur such a privileged operation is PVALIDATE which is
148+
*required* to be executed at VMPL0.
149+
150+
In this scenario, the software running at VMPL0 is usually called a Secure VM
151+
Service Module (SVSM). Discovery of an SVSM and the API used to communicate
152+
with it is documented in "Secure VM Service Module for SEV-SNP Guests", docID:
153+
58019.
154+
155+
(Latest versions of the above-mentioned documents can be found by using
156+
a search engine like duckduckgo.com and typing in:
157+
158+
site:amd.com "Secure VM Service Module for SEV-SNP Guests", docID: 58019
159+
160+
for example.)

Documentation/virt/coco/sev-guest.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,17 @@ has taken care to make use of the SEV-SNP CPUID throughout all stages of boot.
204204
Otherwise, guest owner attestation provides no assurance that the kernel wasn't
205205
fed incorrect values at some point during boot.
206206

207+
4. SEV Guest Driver Communication Key
208+
=====================================
209+
210+
Communication between an SEV guest and the SEV firmware in the AMD Secure
211+
Processor (ASP, aka PSP) is protected by a VM Platform Communication Key
212+
(VMPCK). By default, the sev-guest driver uses the VMPCK associated with the
213+
VM Privilege Level (VMPL) at which the guest is running. Should this key be
214+
wiped by the sev-guest driver (see the driver for reasons why a VMPCK can be
215+
wiped), a different key can be used by reloading the sev-guest driver and
216+
specifying the desired key using the vmpck_id module parameter.
217+
207218

208219
Reference
209220
---------

arch/x86/boot/compressed/sev.c

Lines changed: 70 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,35 @@ static bool fault_in_kernel_space(unsigned long address)
127127
#include "../../lib/insn.c"
128128

129129
/* Include code for early handlers */
130-
#include "../../kernel/sev-shared.c"
130+
#include "../../coco/sev/shared.c"
131+
132+
static struct svsm_ca *svsm_get_caa(void)
133+
{
134+
return boot_svsm_caa;
135+
}
136+
137+
static u64 svsm_get_caa_pa(void)
138+
{
139+
return boot_svsm_caa_pa;
140+
}
141+
142+
static int svsm_perform_call_protocol(struct svsm_call *call)
143+
{
144+
struct ghcb *ghcb;
145+
int ret;
146+
147+
if (boot_ghcb)
148+
ghcb = boot_ghcb;
149+
else
150+
ghcb = NULL;
151+
152+
do {
153+
ret = ghcb ? svsm_perform_ghcb_protocol(ghcb, call)
154+
: svsm_perform_msr_protocol(call);
155+
} while (ret == -EAGAIN);
156+
157+
return ret;
158+
}
131159

132160
bool sev_snp_enabled(void)
133161
{
@@ -145,8 +173,8 @@ static void __page_state_change(unsigned long paddr, enum psc_op op)
145173
* If private -> shared then invalidate the page before requesting the
146174
* state change in the RMP table.
147175
*/
148-
if (op == SNP_PAGE_STATE_SHARED && pvalidate(paddr, RMP_PG_SIZE_4K, 0))
149-
sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PVALIDATE);
176+
if (op == SNP_PAGE_STATE_SHARED)
177+
pvalidate_4k_page(paddr, paddr, false);
150178

151179
/* Issue VMGEXIT to change the page state in RMP table. */
152180
sev_es_wr_ghcb_msr(GHCB_MSR_PSC_REQ_GFN(paddr >> PAGE_SHIFT, op));
@@ -161,8 +189,8 @@ static void __page_state_change(unsigned long paddr, enum psc_op op)
161189
* Now that page state is changed in the RMP table, validate it so that it is
162190
* consistent with the RMP entry.
163191
*/
164-
if (op == SNP_PAGE_STATE_PRIVATE && pvalidate(paddr, RMP_PG_SIZE_4K, 1))
165-
sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PVALIDATE);
192+
if (op == SNP_PAGE_STATE_PRIVATE)
193+
pvalidate_4k_page(paddr, paddr, true);
166194
}
167195

168196
void snp_set_page_private(unsigned long paddr)
@@ -255,6 +283,16 @@ void sev_es_shutdown_ghcb(void)
255283
if (!sev_es_check_cpu_features())
256284
error("SEV-ES CPU Features missing.");
257285

286+
/*
287+
* This denotes whether to use the GHCB MSR protocol or the GHCB
288+
* shared page to perform a GHCB request. Since the GHCB page is
289+
* being changed to encrypted, it can't be used to perform GHCB
290+
* requests. Clear the boot_ghcb variable so that the GHCB MSR
291+
* protocol is used to change the GHCB page over to an encrypted
292+
* page.
293+
*/
294+
boot_ghcb = NULL;
295+
258296
/*
259297
* GHCB Page must be flushed from the cache and mapped encrypted again.
260298
* Otherwise the running kernel will see strange cache effects when
@@ -462,6 +500,13 @@ static bool early_snp_init(struct boot_params *bp)
462500
*/
463501
setup_cpuid_table(cc_info);
464502

503+
/*
504+
* Record the SVSM Calling Area (CA) address if the guest is not
505+
* running at VMPL0. The CA will be used to communicate with the
506+
* SVSM and request its services.
507+
*/
508+
svsm_setup_ca(cc_info);
509+
465510
/*
466511
* Pass run-time kernel a pointer to CC info via boot_params so EFI
467512
* config table doesn't need to be searched again during early startup
@@ -565,22 +610,31 @@ void sev_enable(struct boot_params *bp)
565610
* features.
566611
*/
567612
if (sev_status & MSR_AMD64_SEV_SNP_ENABLED) {
568-
if (!(get_hv_features() & GHCB_HV_FT_SNP))
613+
u64 hv_features;
614+
int ret;
615+
616+
hv_features = get_hv_features();
617+
if (!(hv_features & GHCB_HV_FT_SNP))
569618
sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
570619

571620
/*
572-
* Enforce running at VMPL0.
573-
*
574-
* RMPADJUST modifies RMP permissions of a lesser-privileged (numerically
575-
* higher) privilege level. Here, clear the VMPL1 permission mask of the
576-
* GHCB page. If the guest is not running at VMPL0, this will fail.
621+
* Enforce running at VMPL0 or with an SVSM.
577622
*
578-
* If the guest is running at VMPL0, it will succeed. Even if that operation
579-
* modifies permission bits, it is still ok to do so currently because Linux
580-
* SNP guests running at VMPL0 only run at VMPL0, so VMPL1 or higher
581-
* permission mask changes are a don't-care.
623+
* Use RMPADJUST (see the rmpadjust() function for a description of
624+
* what the instruction does) to update the VMPL1 permissions of a
625+
* page. If the guest is running at VMPL0, this will succeed. If the
626+
* guest is running at any other VMPL, this will fail. Linux SNP guests
627+
* only ever run at a single VMPL level so permission mask changes of a
628+
* lesser-privileged VMPL are a don't-care.
629+
*/
630+
ret = rmpadjust((unsigned long)&boot_ghcb_page, RMP_PG_SIZE_4K, 1);
631+
632+
/*
633+
* Running at VMPL0 is not required if an SVSM is present and the hypervisor
634+
* supports the required SVSM GHCB events.
582635
*/
583-
if (rmpadjust((unsigned long)&boot_ghcb_page, RMP_PG_SIZE_4K, 1))
636+
if (ret &&
637+
!(snp_vmpl && (hv_features & GHCB_HV_FT_SNP_MULTI_VMPL)))
584638
sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_NOT_VMPL0);
585639
}
586640

arch/x86/coco/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ CFLAGS_core.o += -fno-stack-protector
66
obj-y += core.o
77

88
obj-$(CONFIG_INTEL_TDX_GUEST) += tdx/
9+
obj-$(CONFIG_AMD_MEM_ENCRYPT) += sev/

arch/x86/coco/sev/Makefile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
3+
obj-y += core.o
4+
5+
ifdef CONFIG_FUNCTION_TRACER
6+
CFLAGS_REMOVE_core.o = -pg
7+
endif
8+
9+
KASAN_SANITIZE_core.o := n
10+
KMSAN_SANITIZE_core.o := n
11+
KCOV_INSTRUMENT_core.o := n
12+
13+
# With some compiler versions the generated code results in boot hangs, caused
14+
# by several compilation units. To be safe, disable all instrumentation.
15+
KCSAN_SANITIZE := n

0 commit comments

Comments
 (0)