From: Yury Norov Date: Mon, 27 Apr 2026 21:41:19 +0000 (-0400) Subject: x86/extable: switch to using FIELD_GET_SIGNED() X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=d3d4233c7cf4fb399bd10a7d0ecb08e448783b75;p=thirdparty%2Fkernel%2Flinux.git x86/extable: switch to using FIELD_GET_SIGNED() The EX_DATA register is laid out such that EX_DATA_IMM occupied MSB. It's done to make sure that FIELD_GET() will sign-extend the IMM field during extraction. To enforce that, all EX_DATA masks are made signed integers. This works, but relies on the particular implementation of FIELD_GET(), i.e. masking then shifting, not vice versa; and the particular placement of the fields in the register. Switch to using the dedicated FIELD_GET_SIGNED(), and relax those limitations. Acked-by: Peter Zijlstra (Intel) Signed-off-by: Yury Norov --- diff --git a/arch/x86/include/asm/extable_fixup_types.h b/arch/x86/include/asm/extable_fixup_types.h index 906b0d5541e89..fd0cfb4721039 100644 --- a/arch/x86/include/asm/extable_fixup_types.h +++ b/arch/x86/include/asm/extable_fixup_types.h @@ -2,15 +2,10 @@ #ifndef _ASM_X86_EXTABLE_FIXUP_TYPES_H #define _ASM_X86_EXTABLE_FIXUP_TYPES_H -/* - * Our IMM is signed, as such it must live at the top end of the word. Also, - * since C99 hex constants are of ambiguous type, force cast the mask to 'int' - * so that FIELD_GET() will DTRT and sign extend the value when it extracts it. - */ -#define EX_DATA_TYPE_MASK ((int)0x000000FF) -#define EX_DATA_REG_MASK ((int)0x00000F00) -#define EX_DATA_FLAG_MASK ((int)0x0000F000) -#define EX_DATA_IMM_MASK ((int)0xFFFF0000) +#define EX_DATA_TYPE_MASK (0x000000FF) +#define EX_DATA_REG_MASK (0x00000F00) +#define EX_DATA_FLAG_MASK (0x0000F000) +#define EX_DATA_IMM_MASK (0xFFFF0000) #define EX_DATA_REG_SHIFT 8 #define EX_DATA_FLAG_SHIFT 12 diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c index 6b9ff1c6cafa2..ceb8d03191ab2 100644 --- a/arch/x86/mm/extable.c +++ b/arch/x86/mm/extable.c @@ -322,7 +322,7 @@ int fixup_exception(struct pt_regs *regs, int trapnr, unsigned long error_code, type = FIELD_GET(EX_DATA_TYPE_MASK, e->data); reg = FIELD_GET(EX_DATA_REG_MASK, e->data); - imm = FIELD_GET(EX_DATA_IMM_MASK, e->data); + imm = FIELD_GET_SIGNED(EX_DATA_IMM_MASK, e->data); switch (type) { case EX_TYPE_DEFAULT: