Re: [PATCH v2 2/9] x86/extable: switch to using FIELD_GET_SIGNED()

From: Peter Zijlstra

Date: Tue Apr 28 2026 - 06:17:20 EST


On Mon, Apr 27, 2026 at 05:41:19PM -0400, Yury Norov wrote:
> 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.
>
> Signed-off-by: Yury Norov <ynorov@xxxxxxxxxx>

Acked-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx>

> ---
> arch/x86/include/asm/extable_fixup_types.h | 13 ++++---------
> arch/x86/mm/extable.c | 2 +-
> 2 files changed, 5 insertions(+), 10 deletions(-)
>
> diff --git a/arch/x86/include/asm/extable_fixup_types.h b/arch/x86/include/asm/extable_fixup_types.h
> index 906b0d5541e8..fd0cfb472103 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 6b9ff1c6cafa..ceb8d03191ab 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:
> --
> 2.51.0
>