Re: [PATCH v3] MIPS: kernel: elf: Improve the overall ABI and FPU mode checks

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Markos Chandras <markos.chandras@xxxxxxxxxx> writes:

> The previous implementation did not cover all possible FPU combinations
> and it silently allowed ABI incompatible objects to be loaded with the
> wrong ABI. For example, the previous logic would set the FP_64 ABI as
> the matching ABI for an FP_XX object combined with an FP_64A object.
> This was wrong, and the matching ABI should have been FP_64A.
> The previous logic is now replaced with a new one which determines
> the appropriate FPU mode to be used rather than the FP ABI. This has
> the advantage that the entire logic is much simpler since it is the FPU
> mode we are interested in rather than the FP ABI resulting to code
> simplifications.
>
> Cc: Matthew Fortune <Matthew.Fortune@xxxxxxxxxx>
> Cc: Paul Burton <paul.burton@xxxxxxxxxx>
> Signed-off-by: Markos Chandras <markos.chandras@xxxxxxxxxx>
> ---
>  arch/mips/include/asm/elf.h |  10 +-
>  arch/mips/kernel/elf.c      | 303 +++++++++++++++++++++++++++-----------------
>  2 files changed, 194 insertions(+), 119 deletions(-)

This patch (well, the variant that made it into 4.0-rc1) breaks
MIPS_ABI_FP_DOUBLE (the gcc default) apps on MIPS32.

> +void mips_set_personality_fp(struct arch_elf_state *state)
> +{
> +	/*
> +	 * This function is only ever called for O32 ELFs so we should
> +	 * not be worried about N32/N64 binaries.
> +	 */
>
> -	case MIPS_ABI_FP_XX:
> -	case MIPS_ABI_FP_ANY:
> -		if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT))
> -			set_thread_flag(TIF_32BIT_FPREGS);
> -		else
> -			clear_thread_flag(TIF_32BIT_FPREGS);
> +	if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT))
> +		return;

The problem is here.  In a 32-bit configuration, MIPS_O32_FP64_SUPPORT
is always disabled, so the FP mode doesn't get set.  Simply deleting
those two lines makes things work again, but that's probably not the
right fix.

> -		clear_thread_flag(TIF_HYBRID_FPREGS);
> +	switch (state->overall_fp_mode) {
> +	case FP_FRE:
> +		set_thread_fp_mode(1, 0);
> +		break;
> +	case FP_FR0:
> +		set_thread_fp_mode(0, 1);
> +		break;
> +	case FP_FR1:
> +		set_thread_fp_mode(0, 0);
>  		break;
> -
>  	default:
> -	case FP_ERROR:
>  		BUG();
>  	}
>  }
> -- 
> 2.2.2
>

-- 
Måns Rullgård
mans@xxxxxxxxx





[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux