Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 387c9643 authored by Kevin Hilman's avatar Kevin Hilman
Browse files

Merge branch 'linux-linaro-lsk-v3.18' into linux-linaro-lsk-v3.18-android

Conflicts:
	arch/arm64/Kconfig
	arch/arm64/include/asm/cputype.h
	arch/arm64/kernel/Makefile
	arch/arm64/kernel/armv8_deprecated.c
	arch/arm64/kernel/cpuinfo.c
parents 689cc2a6 abacc500
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -514,6 +514,20 @@ config FORCE_MAX_ZONEORDER
	default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE)
	default "11"

config ARM64_PAN
	bool "Enable support for Privileged Access Never (PAN)"
	default y
	help
	 Privileged Access Never (PAN; part of the ARMv8.1 Extensions)
	 prevents the kernel or hypervisor from accessing user-space (EL0)
	 memory directly.

	 Choosing this option will cause any unprotected (not using
	 copy_to_user et al) memory access to fail with a permission fault.

	 The feature is detected at runtime, and will remain as a 'nop'
	 instruction if the cpu does not implement the feature.

menuconfig ARMV8_DEPRECATED
	bool "Emulate deprecated/obsolete ARMv8 instructions"
	depends on COMPAT
+0 −29
Original line number Diff line number Diff line
#ifndef __ASM_ALTERNATIVE_ASM_H
#define __ASM_ALTERNATIVE_ASM_H

#ifdef __ASSEMBLY__

.macro altinstruction_entry orig_offset alt_offset feature orig_len alt_len
	.word \orig_offset - .
	.word \alt_offset - .
	.hword \feature
	.byte \orig_len
	.byte \alt_len
.endm

.macro alternative_insn insn1 insn2 cap
661:	\insn1
662:	.pushsection .altinstructions, "a"
	altinstruction_entry 661b, 663f, \cap, 662b-661b, 664f-663f
	.popsection
	.pushsection .altinstr_replacement, "ax"
663:	\insn2
664:	.popsection
	.if ((664b-663b) != (662b-661b))
		.error "Alternatives instruction length mismatch"
	.endif
.endm

#endif  /*  __ASSEMBLY__  */

#endif /* __ASM_ALTERNATIVE_ASM_H */
+105 −4
Original line number Diff line number Diff line
#ifndef __ASM_ALTERNATIVE_H
#define __ASM_ALTERNATIVE_H

#ifndef __ASSEMBLY__

#include <linux/kconfig.h>
#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/stringify.h>
@@ -23,8 +26,22 @@ void free_alternatives_memory(void);
	" .byte 662b-661b\n"				/* source len      */ \
	" .byte 664f-663f\n"				/* replacement len */

/* alternative assembly primitive: */
#define ALTERNATIVE(oldinstr, newinstr, feature)			\
/*
 * alternative assembly primitive:
 *
 * If any of these .org directive fail, it means that insn1 and insn2
 * don't have the same length. This used to be written as
 *
 * .if ((664b-663b) != (662b-661b))
 * 	.error "Alternatives instruction length mismatch"
 * .endif
 *
 * but most assemblers die if insn1 or insn2 have a .inst. This should
 * be fixed in a binutils release posterior to 2.25.51.0.2 (anything
 * containing commit 4e4d08cf7399b606 or c1baaddf8861).
 */
#define __ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg_enabled)	\
	".if "__stringify(cfg_enabled)" == 1\n"				\
	"661:\n\t"							\
	oldinstr "\n"							\
	"662:\n"							\
@@ -36,8 +53,92 @@ void free_alternatives_memory(void);
	newinstr "\n"							\
	"664:\n\t"							\
	".popsection\n\t"						\
	".if ((664b-663b) != (662b-661b))\n\t"				\
	"	.error \"Alternatives instruction length mismatch\"\n\t"\
	".org	. - (664b-663b) + (662b-661b)\n\t"			\
	".org	. - (662b-661b) + (664b-663b)\n"			\
	".endif\n"

#define _ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg, ...)	\
	__ALTERNATIVE_CFG(oldinstr, newinstr, feature, IS_ENABLED(cfg))

#else

.macro altinstruction_entry orig_offset alt_offset feature orig_len alt_len
	.word \orig_offset - .
	.word \alt_offset - .
	.hword \feature
	.byte \orig_len
	.byte \alt_len
.endm

.macro alternative_insn insn1, insn2, cap, enable = 1
	.if \enable
661:	\insn1
662:	.pushsection .altinstructions, "a"
	altinstruction_entry 661b, 663f, \cap, 662b-661b, 664f-663f
	.popsection
	.pushsection .altinstr_replacement, "ax"
663:	\insn2
664:	.popsection
	.org	. - (664b-663b) + (662b-661b)
	.org	. - (662b-661b) + (664b-663b)
	.endif
.endm

/*
 * Begin an alternative code sequence.
 *
 * The code that follows this macro will be assembled and linked as
 * normal. There are no restrictions on this code.
 */
.macro alternative_if_not cap
	.pushsection .altinstructions, "a"
	altinstruction_entry 661f, 663f, \cap, 662f-661f, 664f-663f
	.popsection
661:
.endm

/*
 * Provide the alternative code sequence.
 *
 * The code that follows this macro is assembled into a special
 * section to be used for dynamic patching. Code that follows this
 * macro must:
 *
 * 1. Be exactly the same length (in bytes) as the default code
 *    sequence.
 *
 * 2. Not contain a branch target that is used outside of the
 *    alternative sequence it is defined in (branches into an
 *    alternative sequence are not fixed up).
 */
.macro alternative_else
662:	.pushsection .altinstr_replacement, "ax"
663:
.endm

/*
 * Complete an alternative code sequence.
 */
.macro alternative_endif
664:	.popsection
	.org	. - (664b-663b) + (662b-661b)
	.org	. - (662b-661b) + (664b-663b)
.endm

#define _ALTERNATIVE_CFG(insn1, insn2, cap, cfg, ...)	\
	alternative_insn insn1, insn2, cap, IS_ENABLED(cfg)


#endif  /*  __ASSEMBLY__  */

/*
 * Usage: asm(ALTERNATIVE(oldinstr, newinstr, feature));
 *
 * Usage: asm(ALTERNATIVE(oldinstr, newinstr, feature, CONFIG_FOO));
 * N.B. If CONFIG_FOO is specified, but not selected, the whole block
 *      will be omitted, including oldinstr.
 */
#define ALTERNATIVE(oldinstr, newinstr, ...)   \
	_ALTERNATIVE_CFG(oldinstr, newinstr, __VA_ARGS__, 1)

#endif /* __ASM_ALTERNATIVE_H */
+37 −5
Original line number Diff line number Diff line
@@ -24,12 +24,32 @@
#define ARM64_WORKAROUND_CLEAN_CACHE		0
#define ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE	1
#define ARM64_WORKAROUND_845719			2
#define ARM64_HAS_SYSREG_GIC_CPUIF		3
#define ARM64_HAS_PAN				4

#define NCAPS					3
#define ARM64_NCAPS				5

#ifndef __ASSEMBLY__

extern DECLARE_BITMAP(cpu_hwcaps, NCAPS);
struct arm64_cpu_capabilities {
	const char *desc;
	u16 capability;
	bool (*matches)(const struct arm64_cpu_capabilities *);
	void (*enable)(void);
	union {
		struct {	/* To be used for erratum handling only */
			u32 midr_model;
			u32 midr_range_min, midr_range_max;
		};

		struct {	/* Feature register checking */
			int field_pos;
			int min_field_value;
		};
	};
};

extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);

static inline bool cpu_have_feature(unsigned int num)
{
@@ -38,21 +58,33 @@ static inline bool cpu_have_feature(unsigned int num)

static inline bool cpus_have_cap(unsigned int num)
{
	if (num >= NCAPS)
	if (num >= ARM64_NCAPS)
		return false;
	return test_bit(num, cpu_hwcaps);
}

static inline void cpus_set_cap(unsigned int num)
{
	if (num >= NCAPS)
	if (num >= ARM64_NCAPS)
		pr_warn("Attempt to set an illegal CPU capability (%d >= %d)\n",
			num, NCAPS);
			num, ARM64_NCAPS);
	else
		__set_bit(num, cpu_hwcaps);
}

static inline int __attribute_const__ cpuid_feature_extract_field(u64 features,
								  int field)
{
	return (s64)(features << (64 - 4 - field)) >> (64 - 4);
}


void check_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
			    const char *info);
void check_local_cpu_errata(void);
void check_local_cpu_features(void);
bool cpu_supports_mixed_endian_el0(void);
bool system_supports_mixed_endian_el0(void);

bool cpu_supports_mixed_endian_el0(void);
bool system_supports_mixed_endian_el0(void);
+0 −3
Original line number Diff line number Diff line
@@ -81,9 +81,6 @@
#define ID_AA64MMFR0_BIGEND(mmfr0)	\
	(((mmfr0) & ID_AA64MMFR0_BIGEND_MASK) >> ID_AA64MMFR0_BIGEND_SHIFT)

#define SCTLR_EL1_CP15BEN	(0x1 << 5)
#define SCTLR_EL1_SED		(0x1 << 8)

#ifndef __ASSEMBLY__

/*
Loading