Commit d31a04f8 authored by Andy Whitcroft's avatar Andy Whitcroft Committed by Khalid Elmously

UBUNTU: SAUCE: turn off IBPB when full retpoline is present

CVE-2017-5715 (Spectre v2 Intel)

When we have full retpoline enabled then we do not actually require IBPB
flushes when entering the kernel.  Add a new use_ibpb bit to represent
when we have retpoline enabled.  Further split the enable bit into two
0x1 representing whether entry IBPB is enabled and 0x10 representing
whether kernel flushes for userspace/VMs etc are applied.
Signed-off-by: default avatarAndy Whitcroft <apw@canonical.com>
Acked-by: default avatarColin Ian King <colin.king@canonical.com>
Acked-by: default avatarKamal Mostafa <kamal@canonical.com>
Signed-off-by: default avatarKhalid Elmously <khalid.elmously@canonical.com>
parent 0d4deafc
......@@ -212,6 +212,17 @@ static void __init spectre_v2_select_mitigation(void)
spectre_v2_enabled = mode;
pr_info("%s\n", spectre_v2_strings[mode]);
/*
* If we have a full retpoline mode and then disable IBPB in kernel mode
* we do not require both.
*/
if (mode == SPECTRE_V2_RETPOLINE_AMD ||
mode == SPECTRE_V2_RETPOLINE_GENERIC)
{
pr_info("Retpoline compiled kernel disabling IBPB in kernel");
set_ibpb_retpoline_enabled();
}
}
#undef pr_fmt
......@@ -249,6 +260,7 @@ ssize_t cpu_show_spectre_v2(struct device *dev,
if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2))
return sprintf(buf, "Not affected\n");
return sprintf(buf, "%s\n", spectre_v2_strings[spectre_v2_enabled]);
return sprintf(buf, "%s%s\n", spectre_v2_strings[spectre_v2_enabled],
ibpb_enabled_user ? ", IBPB (Intel v4)" : "");
}
#endif
......@@ -97,20 +97,26 @@ static inline void clear_ibrs_disabled(void)
/* indicate usage of IBPB to control execution speculation */
extern int use_ibpb;
extern u32 sysctl_ibpb_enabled;
/* ibpb_enabled_kernel (use_ibpb & 0x1) */
#define ibpb_supported (use_ibpb & 0x2)
#define ibpb_disabled (use_ibpb & 0x4)
static inline void set_ibpb_inuse(void)
#define ibpb_retpoline_enabled (use_ibpb & 0x8)
#define ibpb_enabled_user (use_ibpb & 0x10)
static inline void sync_ibpb_inuse(void)
{
if (ibpb_supported)
use_ibpb |= 0x1;
}
static inline void clear_ibpb_inuse(void)
{
use_ibpb &= ~0x1;
if (ibpb_supported && !ibpb_disabled) {
use_ibpb |= 0x10; /* Enable flushing on context/VM switch. */
if (!ibpb_retpoline_enabled)
use_ibpb |= 0x1; /* Enable for kernel proper (entry). */
else
use_ibpb &= ~0x1;
} else {
use_ibpb &= ~(0x10|0x1);
}
}
static inline int check_ibpb_inuse(void)
{
if (use_ibpb & 0x1)
if (use_ibpb & 0x10)
return 1;
else
/* rmb to prevent wrong speculation for security */
......@@ -120,19 +126,22 @@ static inline int check_ibpb_inuse(void)
static inline void set_ibpb_supported(void)
{
use_ibpb |= 0x2;
if (!ibpb_disabled)
set_ibpb_inuse();
sync_ibpb_inuse();
}
static inline void set_ibpb_disabled(void)
{
use_ibpb |= 0x4;
if (check_ibpb_inuse())
clear_ibpb_inuse();
sync_ibpb_inuse();
}
static inline void clear_ibpb_disabled(void)
{
use_ibpb &= ~0x4;
set_ibpb_inuse();
sync_ibpb_inuse();
}
static inline void set_ibpb_retpoline_enabled(void)
{
use_ibpb |= 0x8;
sync_ibpb_inuse();
}
#define ibpb_inuse (check_ibpb_inuse())
#endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment