Skip to content

Commit 7f9ec7d

Browse files
committed
Merge tag 'x86-urgent-2023-03-05' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 updates from Thomas Gleixner: "A small set of updates for x86: - Return -EIO instead of success when the certificate buffer for SEV guests is not large enough - Allow STIPB to be enabled with legacy IBSR. Legacy IBRS is cleared on return to userspace for performance reasons, but the leaves user space vulnerable to cross-thread attacks which STIBP prevents. Update the documentation accordingly" * tag 'x86-urgent-2023-03-05' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: virt/sev-guest: Return -EIO if certificate buffer is not large enough Documentation/hw-vuln: Document the interaction between IBRS and STIBP x86/speculation: Allow enabling STIBP with legacy IBRS
2 parents 4e9c542 + dd093fb commit 7f9ec7d

File tree

3 files changed

+51
-15
lines changed

3 files changed

+51
-15
lines changed

Documentation/admin-guide/hw-vuln/spectre.rst

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -479,8 +479,16 @@ Spectre variant 2
479479
On Intel Skylake-era systems the mitigation covers most, but not all,
480480
cases. See :ref:`[3] <spec_ref3>` for more details.
481481

482-
On CPUs with hardware mitigation for Spectre variant 2 (e.g. Enhanced
483-
IBRS on x86), retpoline is automatically disabled at run time.
482+
On CPUs with hardware mitigation for Spectre variant 2 (e.g. IBRS
483+
or enhanced IBRS on x86), retpoline is automatically disabled at run time.
484+
485+
Systems which support enhanced IBRS (eIBRS) enable IBRS protection once at
486+
boot, by setting the IBRS bit, and they're automatically protected against
487+
Spectre v2 variant attacks, including cross-thread branch target injections
488+
on SMT systems (STIBP). In other words, eIBRS enables STIBP too.
489+
490+
Legacy IBRS systems clear the IBRS bit on exit to userspace and
491+
therefore explicitly enable STIBP for that
484492

485493
The retpoline mitigation is turned on by default on vulnerable
486494
CPUs. It can be forced on or off by the administrator
@@ -504,9 +512,12 @@ Spectre variant 2
504512
For Spectre variant 2 mitigation, individual user programs
505513
can be compiled with return trampolines for indirect branches.
506514
This protects them from consuming poisoned entries in the branch
507-
target buffer left by malicious software. Alternatively, the
508-
programs can disable their indirect branch speculation via prctl()
509-
(See :ref:`Documentation/userspace-api/spec_ctrl.rst <set_spec_ctrl>`).
515+
target buffer left by malicious software.
516+
517+
On legacy IBRS systems, at return to userspace, implicit STIBP is disabled
518+
because the kernel clears the IBRS bit. In this case, the userspace programs
519+
can disable indirect branch speculation via prctl() (See
520+
:ref:`Documentation/userspace-api/spec_ctrl.rst <set_spec_ctrl>`).
510521
On x86, this will turn on STIBP to guard against attacks from the
511522
sibling thread when the user program is running, and use IBPB to
512523
flush the branch target buffer when switching to/from the program.

arch/x86/kernel/cpu/bugs.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,14 +1133,18 @@ spectre_v2_parse_user_cmdline(void)
11331133
return SPECTRE_V2_USER_CMD_AUTO;
11341134
}
11351135

1136-
static inline bool spectre_v2_in_ibrs_mode(enum spectre_v2_mitigation mode)
1136+
static inline bool spectre_v2_in_eibrs_mode(enum spectre_v2_mitigation mode)
11371137
{
1138-
return mode == SPECTRE_V2_IBRS ||
1139-
mode == SPECTRE_V2_EIBRS ||
1138+
return mode == SPECTRE_V2_EIBRS ||
11401139
mode == SPECTRE_V2_EIBRS_RETPOLINE ||
11411140
mode == SPECTRE_V2_EIBRS_LFENCE;
11421141
}
11431142

1143+
static inline bool spectre_v2_in_ibrs_mode(enum spectre_v2_mitigation mode)
1144+
{
1145+
return spectre_v2_in_eibrs_mode(mode) || mode == SPECTRE_V2_IBRS;
1146+
}
1147+
11441148
static void __init
11451149
spectre_v2_user_select_mitigation(void)
11461150
{
@@ -1203,12 +1207,19 @@ spectre_v2_user_select_mitigation(void)
12031207
}
12041208

12051209
/*
1206-
* If no STIBP, IBRS or enhanced IBRS is enabled, or SMT impossible,
1207-
* STIBP is not required.
1210+
* If no STIBP, enhanced IBRS is enabled, or SMT impossible, STIBP
1211+
* is not required.
1212+
*
1213+
* Enhanced IBRS also protects against cross-thread branch target
1214+
* injection in user-mode as the IBRS bit remains always set which
1215+
* implicitly enables cross-thread protections. However, in legacy IBRS
1216+
* mode, the IBRS bit is set only on kernel entry and cleared on return
1217+
* to userspace. This disables the implicit cross-thread protection,
1218+
* so allow for STIBP to be selected in that case.
12081219
*/
12091220
if (!boot_cpu_has(X86_FEATURE_STIBP) ||
12101221
!smt_possible ||
1211-
spectre_v2_in_ibrs_mode(spectre_v2_enabled))
1222+
spectre_v2_in_eibrs_mode(spectre_v2_enabled))
12121223
return;
12131224

12141225
/*
@@ -2340,7 +2351,7 @@ static ssize_t mmio_stale_data_show_state(char *buf)
23402351

23412352
static char *stibp_state(void)
23422353
{
2343-
if (spectre_v2_in_ibrs_mode(spectre_v2_enabled))
2354+
if (spectre_v2_in_eibrs_mode(spectre_v2_enabled))
23442355
return "";
23452356

23462357
switch (spectre_v2_user_stibp) {

drivers/virt/coco/sev-guest/sev-guest.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -377,9 +377,26 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in
377377
snp_dev->input.data_npages = certs_npages;
378378
}
379379

380+
/*
381+
* Increment the message sequence number. There is no harm in doing
382+
* this now because decryption uses the value stored in the response
383+
* structure and any failure will wipe the VMPCK, preventing further
384+
* use anyway.
385+
*/
386+
snp_inc_msg_seqno(snp_dev);
387+
380388
if (fw_err)
381389
*fw_err = err;
382390

391+
/*
392+
* If an extended guest request was issued and the supplied certificate
393+
* buffer was not large enough, a standard guest request was issued to
394+
* prevent IV reuse. If the standard request was successful, return -EIO
395+
* back to the caller as would have originally been returned.
396+
*/
397+
if (!rc && err == SNP_GUEST_REQ_INVALID_LEN)
398+
return -EIO;
399+
383400
if (rc) {
384401
dev_alert(snp_dev->dev,
385402
"Detected error from ASP request. rc: %d, fw_err: %llu\n",
@@ -395,9 +412,6 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in
395412
goto disable_vmpck;
396413
}
397414

398-
/* Increment to new message sequence after payload decryption was successful. */
399-
snp_inc_msg_seqno(snp_dev);
400-
401415
return 0;
402416

403417
disable_vmpck:

0 commit comments

Comments
 (0)