[PATCH v4 14/16] x86/traps: Communicate a LASS violation in #GP message

From: Alexander Shishkin
Date: Wed Jul 10 2024 - 12:14:22 EST


Provide a more helpful message on #GP when a kernel side LASS violation
is detected.

Signed-off-by: Alexander Shishkin <alexander.shishkin@xxxxxxxxxxxxxxx>
---
arch/x86/kernel/traps.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index c70d75769b1a..42c032106024 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -488,7 +488,8 @@ DEFINE_IDTENTRY(exc_bounds)
enum kernel_gp_hint {
GP_NO_HINT,
GP_NON_CANONICAL,
- GP_CANONICAL
+ GP_CANONICAL,
+ GP_LASS_VIOLATION
};

/*
@@ -524,6 +525,8 @@ static enum kernel_gp_hint get_kernel_gp_address(struct pt_regs *regs,
if (*addr < ~__VIRTUAL_MASK &&
*addr + insn.opnd_bytes - 1 > __VIRTUAL_MASK)
return GP_NON_CANONICAL;
+ else if (*addr < ~__VIRTUAL_MASK && cpu_feature_enabled(X86_FEATURE_LASS))
+ return GP_LASS_VIOLATION;
#endif

return GP_CANONICAL;
@@ -647,6 +650,11 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
char desc[sizeof(GPFSTR) + 50 + 2*sizeof(unsigned long) + 1] = GPFSTR;
enum kernel_gp_hint hint = GP_NO_HINT;
unsigned long gp_addr;
+ static char *help[] = {
+ [GP_NON_CANONICAL] = "probably for non-canonical address",
+ [GP_CANONICAL] = "maybe for address",
+ [GP_LASS_VIOLATION] = "LASS prevented access to address"
+ };

if (user_mode(regs) && try_fixup_enqcmd_gp())
return;
@@ -686,9 +694,7 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
hint = get_kernel_gp_address(regs, &gp_addr);

if (hint != GP_NO_HINT)
- snprintf(desc, sizeof(desc), GPFSTR ", %s 0x%lx",
- (hint == GP_NON_CANONICAL) ? "probably for non-canonical address"
- : "maybe for address",
+ snprintf(desc, sizeof(desc), GPFSTR ", %s 0x%lx", help[hint],
gp_addr);

/*
--
2.43.0