Revision 61f01dd941ba9e06d2bf05994450ecc3d61b6b8b authored by Andy Lutomirski on 26 April 2015, 23:47:59 UTC, committed by Linus Torvalds on 27 April 2015, 00:57:38 UTC
AMD CPUs don't reinitialize the SS descriptor on SYSRET, so SYSRET with
SS == 0 results in an invalid usermode state in which SS is apparently
equal to __USER_DS but causes #SS if used.

Work around the issue by setting SS to __KERNEL_DS __switch_to, thus
ensuring that SYSRET never happens with SS set to NULL.

This was exposed by a recent vDSO cleanup.

Fixes: e7d6eefaaa44 x86/vdso32/syscall.S: Do not load __USER32_DS to %ss
Signed-off-by: Andy Lutomirski <luto@kernel.org>
Cc: Peter Anvin <hpa@zytor.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Denys Vlasenko <vda.linux@googlemail.com>
Cc: Brian Gerst <brgerst@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 1190944
Raw File
head.S
;
;  Port on Texas Instruments TMS320C6x architecture
;
;  Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
;  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
;
;  This program is free software; you can redistribute it and/or modify
;  it under the terms of the GNU General Public License version 2 as
;  published by the Free Software Foundation.
;
#include <linux/linkage.h>
#include <linux/of_fdt.h>
#include <asm/asm-offsets.h>

	__HEAD
ENTRY(_c_int00)
	;; Save magic and pointer
	MV	.S1	A4,A10
	MV	.S2	B4,B10
	MVKL	.S2	__bss_start,B5
	MVKH	.S2	__bss_start,B5
	MVKL	.S2	__bss_stop,B6
	MVKH	.S2	__bss_stop,B6
	SUB	.L2	B6,B5,B6 ; bss size

	;; Set the stack pointer
	MVKL	.S2	current_ksp,B0
	MVKH	.S2	current_ksp,B0
	LDW	.D2T2	*B0,B15

	;; clear bss
	SHR	.S2	B6,3,B0	  ; number of dwords to clear
	ZERO	.L2	B13
	ZERO	.L2	B12
bss_loop:
	BDEC	.S2	bss_loop,B0
	NOP	3
	CMPLT	.L2	B0,0,B1
 [!B1]	STDW	.D2T2	B13:B12,*B5++[1]

	NOP	4
	AND	.D2	~7,B15,B15

	;; Clear GIE and PGIE
	MVC	.S2	CSR,B2
	CLR	.S2	B2,0,1,B2
	MVC	.S2	B2,CSR
	MVC	.S2	TSR,B2
	CLR	.S2	B2,0,1,B2
	MVC	.S2	B2,TSR
	MVC	.S2	ITSR,B2
	CLR	.S2	B2,0,1,B2
	MVC	.S2	B2,ITSR
	MVC	.S2	NTSR,B2
	CLR	.S2	B2,0,1,B2
	MVC	.S2	B2,NTSR

	;; pass DTB pointer to machine_init (or zero if none)
	MVKL	.S1	OF_DT_HEADER,A0
	MVKH	.S1	OF_DT_HEADER,A0
	CMPEQ	.L1	A10,A0,A0
  [A0]	MV	.S1X	B10,A4
  [!A0] MVK	.S1	0,A4

#ifdef CONFIG_C6X_BIG_KERNEL
	MVKL	.S1	machine_init,A0
	MVKH	.S1	machine_init,A0
	B	.S2X	A0
	ADDKPC  .S2     0f,B3,4
0:
#else
	CALLP	.S2	machine_init,B3
#endif

	;; Jump to Linux init
#ifdef CONFIG_C6X_BIG_KERNEL
	MVKL	.S1	start_kernel,A0
	MVKH	.S1	start_kernel,A0
	B	.S2X	A0
#else
	B	.S2	start_kernel
#endif
	NOP	5
L1:	BNOP	.S2	L1,5
back to top