mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-24 19:40:21 +09:00
Merge branch 'android-4.9' into amlogic-4.9-dev
Signed-off-by: Victor Wan <victor.wan@amlogic.com> Conflicts: drivers/md/dm-bufio.c drivers/media/dvb-core/dvb_frontend.c drivers/usb/dwc3/core.c drivers/usb/gadget/function/f_fs.c
This commit is contained in:
@@ -355,6 +355,7 @@ What: /sys/devices/system/cpu/vulnerabilities
|
||||
/sys/devices/system/cpu/vulnerabilities/meltdown
|
||||
/sys/devices/system/cpu/vulnerabilities/spectre_v1
|
||||
/sys/devices/system/cpu/vulnerabilities/spectre_v2
|
||||
/sys/devices/system/cpu/vulnerabilities/spec_store_bypass
|
||||
Date: January 2018
|
||||
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
|
||||
Description: Information about CPU vulnerabilities
|
||||
|
||||
@@ -101,6 +101,7 @@ Date: February 2015
|
||||
Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
|
||||
Description:
|
||||
Controls the trimming rate in batch mode.
|
||||
<deprecated>
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/cp_interval
|
||||
Date: October 2015
|
||||
|
||||
@@ -54,6 +54,7 @@ stable kernels.
|
||||
| ARM | Cortex-A57 | #852523 | N/A |
|
||||
| ARM | Cortex-A57 | #834220 | ARM64_ERRATUM_834220 |
|
||||
| ARM | Cortex-A72 | #853709 | N/A |
|
||||
| ARM | Cortex-A55 | #1024718 | ARM64_ERRATUM_1024718 |
|
||||
| ARM | MMU-500 | #841119,#826419 | N/A |
|
||||
| | | | |
|
||||
| Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 |
|
||||
|
||||
@@ -112,9 +112,11 @@ $low_water_mark is expressed in blocks of size $data_block_size. If
|
||||
free space on the data device drops below this level then a dm event
|
||||
will be triggered which a userspace daemon should catch allowing it to
|
||||
extend the pool device. Only one such event will be sent.
|
||||
Resuming a device with a new table itself triggers an event so the
|
||||
userspace daemon can use this to detect a situation where a new table
|
||||
already exceeds the threshold.
|
||||
|
||||
No special event is triggered if a just resumed device's free space is below
|
||||
the low water mark. However, resuming a device always triggers an
|
||||
event; a userspace daemon should verify that free space exceeds the low
|
||||
water mark when handling this event.
|
||||
|
||||
A low water mark for the metadata device is maintained in the kernel and
|
||||
will trigger a dm event if free space on the metadata device drops below
|
||||
|
||||
@@ -11,7 +11,11 @@ Required properties:
|
||||
interrupts.
|
||||
|
||||
Optional properties:
|
||||
- clocks: Optional reference to the clock used by the XOR engine.
|
||||
- clocks: Optional reference to the clocks used by the XOR engine.
|
||||
- clock-names: mandatory if there is a second clock, in this case the
|
||||
name must be "core" for the first clock and "reg" for the second
|
||||
one
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ Required properties:
|
||||
"brcm,bcm53128"
|
||||
"brcm,bcm5365"
|
||||
"brcm,bcm5395"
|
||||
"brcm,bcm5389"
|
||||
"brcm,bcm5397"
|
||||
"brcm,bcm5398"
|
||||
|
||||
|
||||
@@ -179,13 +179,15 @@ whint_mode=%s Control which write hints are passed down to block
|
||||
passes down hints with its policy.
|
||||
alloc_mode=%s Adjust block allocation policy, which supports "reuse"
|
||||
and "default".
|
||||
fsync_mode=%s Control the policy of fsync. Currently supports "posix"
|
||||
and "strict". In "posix" mode, which is default, fsync
|
||||
will follow POSIX semantics and does a light operation
|
||||
to improve the filesystem performance. In "strict" mode,
|
||||
fsync will be heavy and behaves in line with xfs, ext4
|
||||
and btrfs, where xfstest generic/342 will pass, but the
|
||||
performance will regress.
|
||||
fsync_mode=%s Control the policy of fsync. Currently supports "posix",
|
||||
"strict", and "nobarrier". In "posix" mode, which is
|
||||
default, fsync will follow POSIX semantics and does a
|
||||
light operation to improve the filesystem performance.
|
||||
In "strict" mode, fsync will be heavy and behaves in line
|
||||
with xfs, ext4 and btrfs, where xfstest generic/342 will
|
||||
pass, but the performance will regress. "nobarrier" is
|
||||
based on "posix", but doesn't issue flush command for
|
||||
non-atomic files likewise "nobarrier" mount option.
|
||||
test_dummy_encryption Enable dummy encryption, which provides a fake fscrypt
|
||||
context. The fake fscrypt context is used by xfstests.
|
||||
|
||||
|
||||
@@ -2711,6 +2711,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
allow data leaks with this option, which is equivalent
|
||||
to spectre_v2=off.
|
||||
|
||||
nospec_store_bypass_disable
|
||||
[HW] Disable all mitigations for the Speculative Store Bypass vulnerability
|
||||
|
||||
noxsave [BUGS=X86] Disables x86 extended register state save
|
||||
and restore using xsave. The kernel will fallback to
|
||||
enabling legacy floating-point and sse state.
|
||||
@@ -3985,6 +3988,48 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
Not specifying this option is equivalent to
|
||||
spectre_v2=auto.
|
||||
|
||||
spec_store_bypass_disable=
|
||||
[HW] Control Speculative Store Bypass (SSB) Disable mitigation
|
||||
(Speculative Store Bypass vulnerability)
|
||||
|
||||
Certain CPUs are vulnerable to an exploit against a
|
||||
a common industry wide performance optimization known
|
||||
as "Speculative Store Bypass" in which recent stores
|
||||
to the same memory location may not be observed by
|
||||
later loads during speculative execution. The idea
|
||||
is that such stores are unlikely and that they can
|
||||
be detected prior to instruction retirement at the
|
||||
end of a particular speculation execution window.
|
||||
|
||||
In vulnerable processors, the speculatively forwarded
|
||||
store can be used in a cache side channel attack, for
|
||||
example to read memory to which the attacker does not
|
||||
directly have access (e.g. inside sandboxed code).
|
||||
|
||||
This parameter controls whether the Speculative Store
|
||||
Bypass optimization is used.
|
||||
|
||||
on - Unconditionally disable Speculative Store Bypass
|
||||
off - Unconditionally enable Speculative Store Bypass
|
||||
auto - Kernel detects whether the CPU model contains an
|
||||
implementation of Speculative Store Bypass and
|
||||
picks the most appropriate mitigation. If the
|
||||
CPU is not vulnerable, "off" is selected. If the
|
||||
CPU is vulnerable the default mitigation is
|
||||
architecture and Kconfig dependent. See below.
|
||||
prctl - Control Speculative Store Bypass per thread
|
||||
via prctl. Speculative Store Bypass is enabled
|
||||
for a process by default. The state of the control
|
||||
is inherited on fork.
|
||||
seccomp - Same as "prctl" above, but all seccomp threads
|
||||
will disable SSB unless they explicitly opt out.
|
||||
|
||||
Not specifying this option is equivalent to
|
||||
spec_store_bypass_disable=auto.
|
||||
|
||||
Default mitigations:
|
||||
X86: If CONFIG_SECCOMP=y "seccomp", otherwise "prctl"
|
||||
|
||||
spia_io_base= [HW,MTD]
|
||||
spia_fio_base=
|
||||
spia_pedr=
|
||||
|
||||
@@ -168,6 +168,15 @@ A: No. See above answer. In short, if you think it really belongs in
|
||||
dash marker line as described in Documentation/SubmittingPatches to
|
||||
temporarily embed that information into the patch that you send.
|
||||
|
||||
Q: Are all networking bug fixes backported to all stable releases?
|
||||
|
||||
A: Due to capacity, Dave could only take care of the backports for the last
|
||||
2 stable releases. For earlier stable releases, each stable branch maintainer
|
||||
is supposed to take care of them. If you find any patch is missing from an
|
||||
earlier stable branch, please notify stable@vger.kernel.org with either a
|
||||
commit ID or a formal patch backported, and CC Dave and other relevant
|
||||
networking developers.
|
||||
|
||||
Q: Someone said that the comment style and coding convention is different
|
||||
for the networking content. Is this true?
|
||||
|
||||
|
||||
@@ -279,11 +279,10 @@ struct clk:
|
||||
|
||||
%pC pll1
|
||||
%pCn pll1
|
||||
%pCr 1560000000
|
||||
|
||||
For printing struct clk structures. '%pC' and '%pCn' print the name
|
||||
(Common Clock Framework) or address (legacy clock framework) of the
|
||||
structure; '%pCr' prints the current clock rate.
|
||||
structure.
|
||||
|
||||
Passed by reference.
|
||||
|
||||
|
||||
94
Documentation/spec_ctrl.txt
Normal file
94
Documentation/spec_ctrl.txt
Normal file
@@ -0,0 +1,94 @@
|
||||
===================
|
||||
Speculation Control
|
||||
===================
|
||||
|
||||
Quite some CPUs have speculation-related misfeatures which are in
|
||||
fact vulnerabilities causing data leaks in various forms even across
|
||||
privilege domains.
|
||||
|
||||
The kernel provides mitigation for such vulnerabilities in various
|
||||
forms. Some of these mitigations are compile-time configurable and some
|
||||
can be supplied on the kernel command line.
|
||||
|
||||
There is also a class of mitigations which are very expensive, but they can
|
||||
be restricted to a certain set of processes or tasks in controlled
|
||||
environments. The mechanism to control these mitigations is via
|
||||
:manpage:`prctl(2)`.
|
||||
|
||||
There are two prctl options which are related to this:
|
||||
|
||||
* PR_GET_SPECULATION_CTRL
|
||||
|
||||
* PR_SET_SPECULATION_CTRL
|
||||
|
||||
PR_GET_SPECULATION_CTRL
|
||||
-----------------------
|
||||
|
||||
PR_GET_SPECULATION_CTRL returns the state of the speculation misfeature
|
||||
which is selected with arg2 of prctl(2). The return value uses bits 0-3 with
|
||||
the following meaning:
|
||||
|
||||
==== ===================== ===================================================
|
||||
Bit Define Description
|
||||
==== ===================== ===================================================
|
||||
0 PR_SPEC_PRCTL Mitigation can be controlled per task by
|
||||
PR_SET_SPECULATION_CTRL.
|
||||
1 PR_SPEC_ENABLE The speculation feature is enabled, mitigation is
|
||||
disabled.
|
||||
2 PR_SPEC_DISABLE The speculation feature is disabled, mitigation is
|
||||
enabled.
|
||||
3 PR_SPEC_FORCE_DISABLE Same as PR_SPEC_DISABLE, but cannot be undone. A
|
||||
subsequent prctl(..., PR_SPEC_ENABLE) will fail.
|
||||
==== ===================== ===================================================
|
||||
|
||||
If all bits are 0 the CPU is not affected by the speculation misfeature.
|
||||
|
||||
If PR_SPEC_PRCTL is set, then the per-task control of the mitigation is
|
||||
available. If not set, prctl(PR_SET_SPECULATION_CTRL) for the speculation
|
||||
misfeature will fail.
|
||||
|
||||
PR_SET_SPECULATION_CTRL
|
||||
-----------------------
|
||||
|
||||
PR_SET_SPECULATION_CTRL allows to control the speculation misfeature, which
|
||||
is selected by arg2 of :manpage:`prctl(2)` per task. arg3 is used to hand
|
||||
in the control value, i.e. either PR_SPEC_ENABLE or PR_SPEC_DISABLE or
|
||||
PR_SPEC_FORCE_DISABLE.
|
||||
|
||||
Common error codes
|
||||
------------------
|
||||
======= =================================================================
|
||||
Value Meaning
|
||||
======= =================================================================
|
||||
EINVAL The prctl is not implemented by the architecture or unused
|
||||
prctl(2) arguments are not 0.
|
||||
|
||||
ENODEV arg2 is selecting a not supported speculation misfeature.
|
||||
======= =================================================================
|
||||
|
||||
PR_SET_SPECULATION_CTRL error codes
|
||||
-----------------------------------
|
||||
======= =================================================================
|
||||
Value Meaning
|
||||
======= =================================================================
|
||||
0 Success
|
||||
|
||||
ERANGE arg3 is incorrect, i.e. it's neither PR_SPEC_ENABLE nor
|
||||
PR_SPEC_DISABLE nor PR_SPEC_FORCE_DISABLE.
|
||||
|
||||
ENXIO Control of the selected speculation misfeature is not possible.
|
||||
See PR_GET_SPECULATION_CTRL.
|
||||
|
||||
EPERM Speculation was disabled with PR_SPEC_FORCE_DISABLE and caller
|
||||
tried to enable it again.
|
||||
======= =================================================================
|
||||
|
||||
Speculation misfeature controls
|
||||
-------------------------------
|
||||
- PR_SPEC_STORE_BYPASS: Speculative Store Bypass
|
||||
|
||||
Invocations:
|
||||
* prctl(PR_GET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, 0, 0, 0);
|
||||
* prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_ENABLE, 0, 0);
|
||||
* prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_DISABLE, 0, 0);
|
||||
* prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_FORCE_DISABLE, 0, 0);
|
||||
@@ -30,6 +30,7 @@ Currently, these files are in /proc/sys/vm:
|
||||
- dirty_writeback_centisecs
|
||||
- drop_caches
|
||||
- extfrag_threshold
|
||||
- extra_free_kbytes
|
||||
- hugepages_treat_as_movable
|
||||
- hugetlb_shm_group
|
||||
- laptop_mode
|
||||
@@ -240,6 +241,21 @@ fragmentation index is <= extfrag_threshold. The default value is 500.
|
||||
|
||||
==============================================================
|
||||
|
||||
extra_free_kbytes
|
||||
|
||||
This parameter tells the VM to keep extra free memory between the threshold
|
||||
where background reclaim (kswapd) kicks in, and the threshold where direct
|
||||
reclaim (by allocating processes) kicks in.
|
||||
|
||||
This is useful for workloads that require low latency memory allocations
|
||||
and have a bounded burstiness in memory allocations, for example a
|
||||
realtime application that receives and transmits network traffic
|
||||
(causing in-kernel memory allocations) with a maximum total message burst
|
||||
size of 200MB may need 200MB of extra free memory to avoid direct reclaim
|
||||
related latencies.
|
||||
|
||||
==============================================================
|
||||
|
||||
hugepages_treat_as_movable
|
||||
|
||||
This parameter controls whether we can allocate hugepages from ZONE_MOVABLE
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 9
|
||||
SUBLEVEL = 99
|
||||
SUBLEVEL = 113
|
||||
EXTRAVERSION =
|
||||
NAME = Roaring Lionus
|
||||
|
||||
|
||||
@@ -29,18 +29,10 @@
|
||||
: "r" (uaddr), "r"(oparg) \
|
||||
: "memory")
|
||||
|
||||
static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
|
||||
static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
|
||||
u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret;
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
@@ -66,17 +58,9 @@ static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
|
||||
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
|
||||
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
|
||||
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
|
||||
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
|
||||
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
|
||||
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
|
||||
default: ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
* Atomic exchange.
|
||||
* Since it can be used to implement critical sections
|
||||
* it must clobber "memory" (also for interrupts in UP).
|
||||
*
|
||||
* The leading and the trailing memory barriers guarantee that these
|
||||
* operations are fully ordered.
|
||||
*
|
||||
*/
|
||||
|
||||
static inline unsigned long
|
||||
@@ -18,6 +22,7 @@ ____xchg(_u8, volatile char *m, unsigned long val)
|
||||
{
|
||||
unsigned long ret, tmp, addr64;
|
||||
|
||||
smp_mb();
|
||||
__asm__ __volatile__(
|
||||
" andnot %4,7,%3\n"
|
||||
" insbl %1,%4,%1\n"
|
||||
@@ -42,6 +47,7 @@ ____xchg(_u16, volatile short *m, unsigned long val)
|
||||
{
|
||||
unsigned long ret, tmp, addr64;
|
||||
|
||||
smp_mb();
|
||||
__asm__ __volatile__(
|
||||
" andnot %4,7,%3\n"
|
||||
" inswl %1,%4,%1\n"
|
||||
@@ -66,6 +72,7 @@ ____xchg(_u32, volatile int *m, unsigned long val)
|
||||
{
|
||||
unsigned long dummy;
|
||||
|
||||
smp_mb();
|
||||
__asm__ __volatile__(
|
||||
"1: ldl_l %0,%4\n"
|
||||
" bis $31,%3,%1\n"
|
||||
@@ -86,6 +93,7 @@ ____xchg(_u64, volatile long *m, unsigned long val)
|
||||
{
|
||||
unsigned long dummy;
|
||||
|
||||
smp_mb();
|
||||
__asm__ __volatile__(
|
||||
"1: ldq_l %0,%4\n"
|
||||
" bis $31,%3,%1\n"
|
||||
@@ -127,10 +135,12 @@ ____xchg(, volatile void *ptr, unsigned long x, int size)
|
||||
* store NEW in MEM. Return the initial value in MEM. Success is
|
||||
* indicated by comparing RETURN with OLD.
|
||||
*
|
||||
* The memory barrier should be placed in SMP only when we actually
|
||||
* make the change. If we don't change anything (so if the returned
|
||||
* prev is equal to old) then we aren't acquiring anything new and
|
||||
* we don't need any memory barrier as far I can tell.
|
||||
* The leading and the trailing memory barriers guarantee that these
|
||||
* operations are fully ordered.
|
||||
*
|
||||
* The trailing memory barrier is placed in SMP unconditionally, in
|
||||
* order to guarantee that dependency ordering is preserved when a
|
||||
* dependency is headed by an unsuccessful operation.
|
||||
*/
|
||||
|
||||
static inline unsigned long
|
||||
@@ -138,6 +148,7 @@ ____cmpxchg(_u8, volatile char *m, unsigned char old, unsigned char new)
|
||||
{
|
||||
unsigned long prev, tmp, cmp, addr64;
|
||||
|
||||
smp_mb();
|
||||
__asm__ __volatile__(
|
||||
" andnot %5,7,%4\n"
|
||||
" insbl %1,%5,%1\n"
|
||||
@@ -149,8 +160,8 @@ ____cmpxchg(_u8, volatile char *m, unsigned char old, unsigned char new)
|
||||
" or %1,%2,%2\n"
|
||||
" stq_c %2,0(%4)\n"
|
||||
" beq %2,3f\n"
|
||||
__ASM__MB
|
||||
"2:\n"
|
||||
__ASM__MB
|
||||
".subsection 2\n"
|
||||
"3: br 1b\n"
|
||||
".previous"
|
||||
@@ -165,6 +176,7 @@ ____cmpxchg(_u16, volatile short *m, unsigned short old, unsigned short new)
|
||||
{
|
||||
unsigned long prev, tmp, cmp, addr64;
|
||||
|
||||
smp_mb();
|
||||
__asm__ __volatile__(
|
||||
" andnot %5,7,%4\n"
|
||||
" inswl %1,%5,%1\n"
|
||||
@@ -176,8 +188,8 @@ ____cmpxchg(_u16, volatile short *m, unsigned short old, unsigned short new)
|
||||
" or %1,%2,%2\n"
|
||||
" stq_c %2,0(%4)\n"
|
||||
" beq %2,3f\n"
|
||||
__ASM__MB
|
||||
"2:\n"
|
||||
__ASM__MB
|
||||
".subsection 2\n"
|
||||
"3: br 1b\n"
|
||||
".previous"
|
||||
@@ -192,6 +204,7 @@ ____cmpxchg(_u32, volatile int *m, int old, int new)
|
||||
{
|
||||
unsigned long prev, cmp;
|
||||
|
||||
smp_mb();
|
||||
__asm__ __volatile__(
|
||||
"1: ldl_l %0,%5\n"
|
||||
" cmpeq %0,%3,%1\n"
|
||||
@@ -199,8 +212,8 @@ ____cmpxchg(_u32, volatile int *m, int old, int new)
|
||||
" mov %4,%1\n"
|
||||
" stl_c %1,%2\n"
|
||||
" beq %1,3f\n"
|
||||
__ASM__MB
|
||||
"2:\n"
|
||||
__ASM__MB
|
||||
".subsection 2\n"
|
||||
"3: br 1b\n"
|
||||
".previous"
|
||||
@@ -215,6 +228,7 @@ ____cmpxchg(_u64, volatile long *m, unsigned long old, unsigned long new)
|
||||
{
|
||||
unsigned long prev, cmp;
|
||||
|
||||
smp_mb();
|
||||
__asm__ __volatile__(
|
||||
"1: ldq_l %0,%5\n"
|
||||
" cmpeq %0,%3,%1\n"
|
||||
@@ -222,8 +236,8 @@ ____cmpxchg(_u64, volatile long *m, unsigned long old, unsigned long new)
|
||||
" mov %4,%1\n"
|
||||
" stq_c %1,%2\n"
|
||||
" beq %1,3f\n"
|
||||
__ASM__MB
|
||||
"2:\n"
|
||||
__ASM__MB
|
||||
".subsection 2\n"
|
||||
"3: br 1b\n"
|
||||
".previous"
|
||||
|
||||
@@ -495,7 +495,6 @@ config ARC_CURR_IN_REG
|
||||
|
||||
config ARC_EMUL_UNALIGNED
|
||||
bool "Emulate unaligned memory access (userspace only)"
|
||||
default N
|
||||
select SYSCTL_ARCH_UNALIGN_NO_WARN
|
||||
select SYSCTL_ARCH_UNALIGN_ALLOW
|
||||
depends on ISA_ARCOMPACT
|
||||
|
||||
@@ -73,20 +73,11 @@
|
||||
|
||||
#endif
|
||||
|
||||
static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
||||
static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
|
||||
u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret;
|
||||
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
|
||||
return -EFAULT;
|
||||
|
||||
#ifndef CONFIG_ARC_HAS_LLSC
|
||||
preempt_disable(); /* to guarantee atomic r-m-w of futex op */
|
||||
#endif
|
||||
@@ -118,30 +109,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
||||
preempt_enable();
|
||||
#endif
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ:
|
||||
ret = (oldval == cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_NE:
|
||||
ret = (oldval != cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_LT:
|
||||
ret = (oldval < cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_GE:
|
||||
ret = (oldval >= cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_LE:
|
||||
ret = (oldval <= cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_GT:
|
||||
ret = (oldval > cmparg);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -146,8 +146,8 @@
|
||||
|
||||
i2s: i2s@7e203000 {
|
||||
compatible = "brcm,bcm2835-i2s";
|
||||
reg = <0x7e203000 0x20>,
|
||||
<0x7e101098 0x02>;
|
||||
reg = <0x7e203000 0x24>;
|
||||
clocks = <&clocks BCM2835_CLOCK_PCM>;
|
||||
|
||||
dmas = <&dma 2>,
|
||||
<&dma 3>;
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
memory {
|
||||
device_type = "memory";
|
||||
reg = <0x60000000 0x80000000>;
|
||||
reg = <0x60000000 0x20000000>;
|
||||
};
|
||||
|
||||
gpio-restart {
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
clocks = <&clks IMX6Q_CLK_ECSPI5>,
|
||||
<&clks IMX6Q_CLK_ECSPI5>;
|
||||
clock-names = "ipg", "per";
|
||||
dmas = <&sdma 11 7 1>, <&sdma 12 7 2>;
|
||||
dmas = <&sdma 11 8 1>, <&sdma 12 8 2>;
|
||||
dma-names = "rx", "tx";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -88,7 +88,6 @@
|
||||
clocks = <&clks IMX6QDL_CLK_CKO>;
|
||||
VDDA-supply = <®_2p5v>;
|
||||
VDDIO-supply = <®_3p3v>;
|
||||
lrclk-strength = <3>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -213,37 +213,37 @@
|
||||
&iomuxc {
|
||||
pinctrl_enet1: enet1grp {
|
||||
fsl,pins = <
|
||||
MX7D_PAD_SD2_CD_B__ENET1_MDIO 0x3
|
||||
MX7D_PAD_SD2_WP__ENET1_MDC 0x3
|
||||
MX7D_PAD_ENET1_RGMII_TXC__ENET1_RGMII_TXC 0x1
|
||||
MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0 0x1
|
||||
MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1 0x1
|
||||
MX7D_PAD_ENET1_RGMII_TD2__ENET1_RGMII_TD2 0x1
|
||||
MX7D_PAD_ENET1_RGMII_TD3__ENET1_RGMII_TD3 0x1
|
||||
MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL 0x1
|
||||
MX7D_PAD_ENET1_RGMII_RXC__ENET1_RGMII_RXC 0x1
|
||||
MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0 0x1
|
||||
MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1 0x1
|
||||
MX7D_PAD_ENET1_RGMII_RD2__ENET1_RGMII_RD2 0x1
|
||||
MX7D_PAD_ENET1_RGMII_RD3__ENET1_RGMII_RD3 0x1
|
||||
MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL 0x1
|
||||
MX7D_PAD_SD2_CD_B__ENET1_MDIO 0x30
|
||||
MX7D_PAD_SD2_WP__ENET1_MDC 0x30
|
||||
MX7D_PAD_ENET1_RGMII_TXC__ENET1_RGMII_TXC 0x11
|
||||
MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0 0x11
|
||||
MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1 0x11
|
||||
MX7D_PAD_ENET1_RGMII_TD2__ENET1_RGMII_TD2 0x11
|
||||
MX7D_PAD_ENET1_RGMII_TD3__ENET1_RGMII_TD3 0x11
|
||||
MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL 0x11
|
||||
MX7D_PAD_ENET1_RGMII_RXC__ENET1_RGMII_RXC 0x11
|
||||
MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0 0x11
|
||||
MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1 0x11
|
||||
MX7D_PAD_ENET1_RGMII_RD2__ENET1_RGMII_RD2 0x11
|
||||
MX7D_PAD_ENET1_RGMII_RD3__ENET1_RGMII_RD3 0x11
|
||||
MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL 0x11
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_enet2: enet2grp {
|
||||
fsl,pins = <
|
||||
MX7D_PAD_EPDC_GDSP__ENET2_RGMII_TXC 0x1
|
||||
MX7D_PAD_EPDC_SDCE2__ENET2_RGMII_TD0 0x1
|
||||
MX7D_PAD_EPDC_SDCE3__ENET2_RGMII_TD1 0x1
|
||||
MX7D_PAD_EPDC_GDCLK__ENET2_RGMII_TD2 0x1
|
||||
MX7D_PAD_EPDC_GDOE__ENET2_RGMII_TD3 0x1
|
||||
MX7D_PAD_EPDC_GDRL__ENET2_RGMII_TX_CTL 0x1
|
||||
MX7D_PAD_EPDC_SDCE1__ENET2_RGMII_RXC 0x1
|
||||
MX7D_PAD_EPDC_SDCLK__ENET2_RGMII_RD0 0x1
|
||||
MX7D_PAD_EPDC_SDLE__ENET2_RGMII_RD1 0x1
|
||||
MX7D_PAD_EPDC_SDOE__ENET2_RGMII_RD2 0x1
|
||||
MX7D_PAD_EPDC_SDSHR__ENET2_RGMII_RD3 0x1
|
||||
MX7D_PAD_EPDC_SDCE0__ENET2_RGMII_RX_CTL 0x1
|
||||
MX7D_PAD_EPDC_GDSP__ENET2_RGMII_TXC 0x11
|
||||
MX7D_PAD_EPDC_SDCE2__ENET2_RGMII_TD0 0x11
|
||||
MX7D_PAD_EPDC_SDCE3__ENET2_RGMII_TD1 0x11
|
||||
MX7D_PAD_EPDC_GDCLK__ENET2_RGMII_TD2 0x11
|
||||
MX7D_PAD_EPDC_GDOE__ENET2_RGMII_TD3 0x11
|
||||
MX7D_PAD_EPDC_GDRL__ENET2_RGMII_TX_CTL 0x11
|
||||
MX7D_PAD_EPDC_SDCE1__ENET2_RGMII_RXC 0x11
|
||||
MX7D_PAD_EPDC_SDCLK__ENET2_RGMII_RD0 0x11
|
||||
MX7D_PAD_EPDC_SDLE__ENET2_RGMII_RD1 0x11
|
||||
MX7D_PAD_EPDC_SDOE__ENET2_RGMII_RD2 0x11
|
||||
MX7D_PAD_EPDC_SDSHR__ENET2_RGMII_RD3 0x11
|
||||
MX7D_PAD_EPDC_SDCE0__ENET2_RGMII_RX_CTL 0x11
|
||||
>;
|
||||
};
|
||||
|
||||
|
||||
@@ -428,7 +428,7 @@
|
||||
"dclkin.0", "dclkin.1";
|
||||
|
||||
ports {
|
||||
port@1 {
|
||||
port@0 {
|
||||
endpoint {
|
||||
remote-endpoint = <&adv7511_in>;
|
||||
};
|
||||
|
||||
@@ -759,7 +759,7 @@
|
||||
timer@fffec600 {
|
||||
compatible = "arm,cortex-a9-twd-timer";
|
||||
reg = <0xfffec600 0x100>;
|
||||
interrupts = <1 13 0xf04>;
|
||||
interrupts = <1 13 0xf01>;
|
||||
clocks = <&mpu_periph_clk>;
|
||||
};
|
||||
|
||||
|
||||
@@ -534,4 +534,14 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
|
||||
#endif
|
||||
.endm
|
||||
|
||||
#ifdef CONFIG_KPROBES
|
||||
#define _ASM_NOKPROBE(entry) \
|
||||
.pushsection "_kprobe_blacklist", "aw" ; \
|
||||
.balign 4 ; \
|
||||
.long entry; \
|
||||
.popsection
|
||||
#else
|
||||
#define _ASM_NOKPROBE(entry)
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_ASSEMBLER_H__ */
|
||||
|
||||
@@ -128,20 +128,10 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
|
||||
#endif /* !SMP */
|
||||
|
||||
static inline int
|
||||
futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
|
||||
arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret, tmp;
|
||||
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
#ifndef CONFIG_SMP
|
||||
preempt_disable();
|
||||
#endif
|
||||
@@ -172,17 +162,9 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
|
||||
preempt_enable();
|
||||
#endif
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
|
||||
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
|
||||
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
|
||||
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
|
||||
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
|
||||
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
|
||||
default: ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ extern int kgdb_fault_expected;
|
||||
|
||||
#define KGDB_MAX_NO_CPUS 1
|
||||
#define BUFMAX 400
|
||||
#define NUMREGBYTES (DBG_MAX_REG_NUM << 2)
|
||||
#define NUMREGBYTES (GDB_MAX_REGS << 2)
|
||||
#define NUMCRITREGBYTES (32 << 2)
|
||||
|
||||
#define _R0 0
|
||||
|
||||
@@ -223,6 +223,22 @@ static inline unsigned int kvm_get_vmid_bits(void)
|
||||
return 8;
|
||||
}
|
||||
|
||||
/*
|
||||
* We are not in the kvm->srcu critical section most of the time, so we take
|
||||
* the SRCU read lock here. Since we copy the data from the user page, we
|
||||
* can immediately drop the lock again.
|
||||
*/
|
||||
static inline int kvm_read_guest_lock(struct kvm *kvm,
|
||||
gpa_t gpa, void *data, unsigned long len)
|
||||
{
|
||||
int srcu_idx = srcu_read_lock(&kvm->srcu);
|
||||
int ret = kvm_read_guest(kvm, gpa, data, len);
|
||||
|
||||
srcu_read_unlock(&kvm->srcu, srcu_idx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void *kvm_get_hyp_vector(void)
|
||||
{
|
||||
return kvm_ksym_ref(__kvm_hyp_vector);
|
||||
|
||||
@@ -11,8 +11,6 @@ struct mm_struct;
|
||||
|
||||
void arm_install_vdso(struct mm_struct *mm, unsigned long addr);
|
||||
|
||||
extern char vdso_start, vdso_end;
|
||||
|
||||
extern unsigned int vdso_total_pages;
|
||||
|
||||
#else /* CONFIG_VDSO */
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <linux/kdebug.h>
|
||||
#include <linux/kprobes.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kexec.h>
|
||||
#include <linux/bug.h>
|
||||
@@ -415,7 +416,8 @@ void unregister_undef_hook(struct undef_hook *hook)
|
||||
raw_spin_unlock_irqrestore(&undef_lock, flags);
|
||||
}
|
||||
|
||||
static int call_undef_hook(struct pt_regs *regs, unsigned int instr)
|
||||
static nokprobe_inline
|
||||
int call_undef_hook(struct pt_regs *regs, unsigned int instr)
|
||||
{
|
||||
struct undef_hook *hook;
|
||||
unsigned long flags;
|
||||
@@ -488,6 +490,7 @@ die_sig:
|
||||
|
||||
arm_notify_die("Oops - undefined instruction", regs, &info, 0, 6);
|
||||
}
|
||||
NOKPROBE_SYMBOL(do_undefinstr)
|
||||
|
||||
/*
|
||||
* Handle FIQ similarly to NMI on x86 systems.
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
|
||||
static struct page **vdso_text_pagelist;
|
||||
|
||||
extern char vdso_start[], vdso_end[];
|
||||
|
||||
/* Total number of pages needed for the data and text portions of the VDSO. */
|
||||
unsigned int vdso_total_pages __ro_after_init;
|
||||
|
||||
@@ -179,13 +181,13 @@ static int __init vdso_init(void)
|
||||
unsigned int text_pages;
|
||||
int i;
|
||||
|
||||
if (memcmp(&vdso_start, "\177ELF", 4)) {
|
||||
if (memcmp(vdso_start, "\177ELF", 4)) {
|
||||
pr_err("VDSO is not a valid ELF object!\n");
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
text_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT;
|
||||
pr_debug("vdso: %i text pages at base %p\n", text_pages, &vdso_start);
|
||||
text_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
|
||||
pr_debug("vdso: %i text pages at base %p\n", text_pages, vdso_start);
|
||||
|
||||
/* Allocate the VDSO text pagelist */
|
||||
vdso_text_pagelist = kcalloc(text_pages, sizeof(struct page *),
|
||||
@@ -200,7 +202,7 @@ static int __init vdso_init(void)
|
||||
for (i = 0; i < text_pages; i++) {
|
||||
struct page *page;
|
||||
|
||||
page = virt_to_page(&vdso_start + i * PAGE_SIZE);
|
||||
page = virt_to_page(vdso_start + i * PAGE_SIZE);
|
||||
vdso_text_pagelist[i] = page;
|
||||
}
|
||||
|
||||
@@ -211,7 +213,7 @@ static int __init vdso_init(void)
|
||||
|
||||
cntvct_ok = cntvct_functional();
|
||||
|
||||
patch_vdso(&vdso_start);
|
||||
patch_vdso(vdso_start);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ ENTRY(__get_user_1)
|
||||
mov r0, #0
|
||||
ret lr
|
||||
ENDPROC(__get_user_1)
|
||||
_ASM_NOKPROBE(__get_user_1)
|
||||
|
||||
ENTRY(__get_user_2)
|
||||
check_uaccess r0, 2, r1, r2, __get_user_bad
|
||||
@@ -58,6 +59,7 @@ rb .req r0
|
||||
mov r0, #0
|
||||
ret lr
|
||||
ENDPROC(__get_user_2)
|
||||
_ASM_NOKPROBE(__get_user_2)
|
||||
|
||||
ENTRY(__get_user_4)
|
||||
check_uaccess r0, 4, r1, r2, __get_user_bad
|
||||
@@ -65,6 +67,7 @@ ENTRY(__get_user_4)
|
||||
mov r0, #0
|
||||
ret lr
|
||||
ENDPROC(__get_user_4)
|
||||
_ASM_NOKPROBE(__get_user_4)
|
||||
|
||||
ENTRY(__get_user_8)
|
||||
check_uaccess r0, 8, r1, r2, __get_user_bad8
|
||||
@@ -78,6 +81,7 @@ ENTRY(__get_user_8)
|
||||
mov r0, #0
|
||||
ret lr
|
||||
ENDPROC(__get_user_8)
|
||||
_ASM_NOKPROBE(__get_user_8)
|
||||
|
||||
#ifdef __ARMEB__
|
||||
ENTRY(__get_user_32t_8)
|
||||
@@ -91,6 +95,7 @@ ENTRY(__get_user_32t_8)
|
||||
mov r0, #0
|
||||
ret lr
|
||||
ENDPROC(__get_user_32t_8)
|
||||
_ASM_NOKPROBE(__get_user_32t_8)
|
||||
|
||||
ENTRY(__get_user_64t_1)
|
||||
check_uaccess r0, 1, r1, r2, __get_user_bad8
|
||||
@@ -98,6 +103,7 @@ ENTRY(__get_user_64t_1)
|
||||
mov r0, #0
|
||||
ret lr
|
||||
ENDPROC(__get_user_64t_1)
|
||||
_ASM_NOKPROBE(__get_user_64t_1)
|
||||
|
||||
ENTRY(__get_user_64t_2)
|
||||
check_uaccess r0, 2, r1, r2, __get_user_bad8
|
||||
@@ -114,6 +120,7 @@ rb .req r0
|
||||
mov r0, #0
|
||||
ret lr
|
||||
ENDPROC(__get_user_64t_2)
|
||||
_ASM_NOKPROBE(__get_user_64t_2)
|
||||
|
||||
ENTRY(__get_user_64t_4)
|
||||
check_uaccess r0, 4, r1, r2, __get_user_bad8
|
||||
@@ -121,6 +128,7 @@ ENTRY(__get_user_64t_4)
|
||||
mov r0, #0
|
||||
ret lr
|
||||
ENDPROC(__get_user_64t_4)
|
||||
_ASM_NOKPROBE(__get_user_64t_4)
|
||||
#endif
|
||||
|
||||
__get_user_bad8:
|
||||
@@ -131,6 +139,8 @@ __get_user_bad:
|
||||
ret lr
|
||||
ENDPROC(__get_user_bad)
|
||||
ENDPROC(__get_user_bad8)
|
||||
_ASM_NOKPROBE(__get_user_bad)
|
||||
_ASM_NOKPROBE(__get_user_bad8)
|
||||
|
||||
.pushsection __ex_table, "a"
|
||||
.long 1b, __get_user_bad
|
||||
|
||||
@@ -1031,17 +1031,17 @@ static int clk_debugfs_register_one(struct clk *c)
|
||||
return -ENOMEM;
|
||||
c->dent = d;
|
||||
|
||||
d = debugfs_create_u8("usecount", S_IRUGO, c->dent, (u8 *)&c->usecount);
|
||||
d = debugfs_create_u8("usecount", S_IRUGO, c->dent, &c->usecount);
|
||||
if (!d) {
|
||||
err = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
|
||||
d = debugfs_create_ulong("rate", S_IRUGO, c->dent, &c->rate);
|
||||
if (!d) {
|
||||
err = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
|
||||
d = debugfs_create_x8("flags", S_IRUGO, c->dent, &c->flags);
|
||||
if (!d) {
|
||||
err = -ENOMEM;
|
||||
goto err_out;
|
||||
|
||||
@@ -225,7 +225,7 @@ static void omap_pm_end(void)
|
||||
cpu_idle_poll_ctrl(false);
|
||||
}
|
||||
|
||||
static void omap_pm_finish(void)
|
||||
static void omap_pm_wake(void)
|
||||
{
|
||||
if (cpu_is_omap34xx())
|
||||
omap_prcm_irq_complete();
|
||||
@@ -235,7 +235,7 @@ static const struct platform_suspend_ops omap_pm_ops = {
|
||||
.begin = omap_pm_begin,
|
||||
.end = omap_pm_end,
|
||||
.enter = omap_pm_enter,
|
||||
.finish = omap_pm_finish,
|
||||
.wake = omap_pm_wake,
|
||||
.valid = suspend_valid_only_mem,
|
||||
};
|
||||
|
||||
|
||||
@@ -136,12 +136,6 @@ static struct clock_event_device clockevent_gpt = {
|
||||
.tick_resume = omap2_gp_timer_shutdown,
|
||||
};
|
||||
|
||||
static struct property device_disabled = {
|
||||
.name = "status",
|
||||
.length = sizeof("disabled"),
|
||||
.value = "disabled",
|
||||
};
|
||||
|
||||
static const struct of_device_id omap_timer_match[] __initconst = {
|
||||
{ .compatible = "ti,omap2420-timer", },
|
||||
{ .compatible = "ti,omap3430-timer", },
|
||||
@@ -183,8 +177,17 @@ static struct device_node * __init omap_get_timer_dt(const struct of_device_id *
|
||||
of_get_property(np, "ti,timer-secure", NULL)))
|
||||
continue;
|
||||
|
||||
if (!of_device_is_compatible(np, "ti,omap-counter32k"))
|
||||
of_add_property(np, &device_disabled);
|
||||
if (!of_device_is_compatible(np, "ti,omap-counter32k")) {
|
||||
struct property *prop;
|
||||
|
||||
prop = kzalloc(sizeof(*prop), GFP_KERNEL);
|
||||
if (!prop)
|
||||
return NULL;
|
||||
prop->name = "status";
|
||||
prop->value = "disabled";
|
||||
prop->length = strlen(prop->value);
|
||||
of_add_property(np, prop);
|
||||
}
|
||||
return np;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,6 @@ config MACH_KUROBOX_PRO
|
||||
|
||||
config MACH_DNS323
|
||||
bool "D-Link DNS-323"
|
||||
select GENERIC_NET_UTILS
|
||||
select I2C_BOARDINFO if I2C
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
@@ -65,7 +64,6 @@ config MACH_DNS323
|
||||
|
||||
config MACH_TS209
|
||||
bool "QNAP TS-109/TS-209"
|
||||
select GENERIC_NET_UTILS
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
QNAP TS-109/TS-209 platform.
|
||||
@@ -107,7 +105,6 @@ config MACH_LINKSTATION_LS_HGL
|
||||
|
||||
config MACH_TS409
|
||||
bool "QNAP TS-409"
|
||||
select GENERIC_NET_UTILS
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
QNAP TS-409 platform.
|
||||
|
||||
@@ -173,10 +173,42 @@ static struct mv643xx_eth_platform_data dns323_eth_data = {
|
||||
.phy_addr = MV643XX_ETH_PHY_ADDR(8),
|
||||
};
|
||||
|
||||
/* dns323_parse_hex_*() taken from tsx09-common.c; should a common copy of these
|
||||
* functions be kept somewhere?
|
||||
*/
|
||||
static int __init dns323_parse_hex_nibble(char n)
|
||||
{
|
||||
if (n >= '0' && n <= '9')
|
||||
return n - '0';
|
||||
|
||||
if (n >= 'A' && n <= 'F')
|
||||
return n - 'A' + 10;
|
||||
|
||||
if (n >= 'a' && n <= 'f')
|
||||
return n - 'a' + 10;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int __init dns323_parse_hex_byte(const char *b)
|
||||
{
|
||||
int hi;
|
||||
int lo;
|
||||
|
||||
hi = dns323_parse_hex_nibble(b[0]);
|
||||
lo = dns323_parse_hex_nibble(b[1]);
|
||||
|
||||
if (hi < 0 || lo < 0)
|
||||
return -1;
|
||||
|
||||
return (hi << 4) | lo;
|
||||
}
|
||||
|
||||
static int __init dns323_read_mac_addr(void)
|
||||
{
|
||||
u_int8_t addr[6];
|
||||
void __iomem *mac_page;
|
||||
int i;
|
||||
char *mac_page;
|
||||
|
||||
/* MAC address is stored as a regular ol' string in /dev/mtdblock4
|
||||
* (0x007d0000-0x00800000) starting at offset 196480 (0x2ff80).
|
||||
@@ -185,8 +217,23 @@ static int __init dns323_read_mac_addr(void)
|
||||
if (!mac_page)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!mac_pton((__force const char *) mac_page, addr))
|
||||
goto error_fail;
|
||||
/* Sanity check the string we're looking at */
|
||||
for (i = 0; i < 5; i++) {
|
||||
if (*(mac_page + (i * 3) + 2) != ':') {
|
||||
goto error_fail;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
int byte;
|
||||
|
||||
byte = dns323_parse_hex_byte(mac_page + (i * 3));
|
||||
if (byte < 0) {
|
||||
goto error_fail;
|
||||
}
|
||||
|
||||
addr[i] = byte;
|
||||
}
|
||||
|
||||
iounmap(mac_page);
|
||||
printk("DNS-323: Found ethernet MAC address: %pM\n", addr);
|
||||
|
||||
@@ -53,12 +53,53 @@ struct mv643xx_eth_platform_data qnap_tsx09_eth_data = {
|
||||
.phy_addr = MV643XX_ETH_PHY_ADDR(8),
|
||||
};
|
||||
|
||||
static int __init qnap_tsx09_parse_hex_nibble(char n)
|
||||
{
|
||||
if (n >= '0' && n <= '9')
|
||||
return n - '0';
|
||||
|
||||
if (n >= 'A' && n <= 'F')
|
||||
return n - 'A' + 10;
|
||||
|
||||
if (n >= 'a' && n <= 'f')
|
||||
return n - 'a' + 10;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int __init qnap_tsx09_parse_hex_byte(const char *b)
|
||||
{
|
||||
int hi;
|
||||
int lo;
|
||||
|
||||
hi = qnap_tsx09_parse_hex_nibble(b[0]);
|
||||
lo = qnap_tsx09_parse_hex_nibble(b[1]);
|
||||
|
||||
if (hi < 0 || lo < 0)
|
||||
return -1;
|
||||
|
||||
return (hi << 4) | lo;
|
||||
}
|
||||
|
||||
static int __init qnap_tsx09_check_mac_addr(const char *addr_str)
|
||||
{
|
||||
u_int8_t addr[6];
|
||||
int i;
|
||||
|
||||
if (!mac_pton(addr_str, addr))
|
||||
return -1;
|
||||
for (i = 0; i < 6; i++) {
|
||||
int byte;
|
||||
|
||||
/*
|
||||
* Enforce "xx:xx:xx:xx:xx:xx\n" format.
|
||||
*/
|
||||
if (addr_str[(i * 3) + 2] != ((i < 5) ? ':' : '\n'))
|
||||
return -1;
|
||||
|
||||
byte = qnap_tsx09_parse_hex_byte(addr_str + (i * 3));
|
||||
if (byte < 0)
|
||||
return -1;
|
||||
addr[i] = byte;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "tsx09: found ethernet mac address %pM\n", addr);
|
||||
|
||||
@@ -77,12 +118,12 @@ void __init qnap_tsx09_find_mac_addr(u32 mem_base, u32 size)
|
||||
unsigned long addr;
|
||||
|
||||
for (addr = mem_base; addr < (mem_base + size); addr += 1024) {
|
||||
void __iomem *nor_page;
|
||||
char *nor_page;
|
||||
int ret = 0;
|
||||
|
||||
nor_page = ioremap(addr, 1024);
|
||||
if (nor_page != NULL) {
|
||||
ret = qnap_tsx09_check_mac_addr((__force const char *)nor_page);
|
||||
ret = qnap_tsx09_check_mac_addr(nor_page);
|
||||
iounmap(nor_page);
|
||||
}
|
||||
|
||||
|
||||
@@ -890,11 +890,8 @@ static int omap_dm_timer_probe(struct platform_device *pdev)
|
||||
timer->irq = irq->start;
|
||||
timer->pdev = pdev;
|
||||
|
||||
/* Skip pm_runtime_enable for OMAP1 */
|
||||
if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) {
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_irq_safe(dev);
|
||||
}
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_irq_safe(dev);
|
||||
|
||||
if (!timer->reserved) {
|
||||
ret = pm_runtime_get_sync(dev);
|
||||
|
||||
@@ -165,13 +165,14 @@ optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct kprobe *p = &op->kp;
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
struct kprobe_ctlblk *kcb;
|
||||
|
||||
/* Save skipped registers */
|
||||
regs->ARM_pc = (unsigned long)op->kp.addr;
|
||||
regs->ARM_ORIG_r0 = ~0UL;
|
||||
|
||||
local_irq_save(flags);
|
||||
kcb = get_kprobe_ctlblk();
|
||||
|
||||
if (kprobe_running()) {
|
||||
kprobes_inc_nmissed_count(&op->kp);
|
||||
@@ -191,6 +192,7 @@ optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
NOKPROBE_SYMBOL(optimized_callback)
|
||||
|
||||
int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *orig)
|
||||
{
|
||||
|
||||
@@ -429,6 +429,20 @@ config ARM64_ERRATUM_843419
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config ARM64_ERRATUM_1024718
|
||||
bool "Cortex-A55: 1024718: Update of DBM/AP bits without break before make might result in incorrect update"
|
||||
default y
|
||||
help
|
||||
This option adds work around for Arm Cortex-A55 Erratum 1024718.
|
||||
|
||||
Affected Cortex-A55 cores (r0p0, r0p1, r1p0) could cause incorrect
|
||||
update of the hardware dirty bit when the DBM/AP bits are updated
|
||||
without a break-before-make. The work around is to disable the usage
|
||||
of hardware DBM locally on the affected cores. CPUs not affected by
|
||||
erratum will continue to use the feature.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config CAVIUM_ERRATUM_22375
|
||||
bool "Cavium erratum 22375, 24313"
|
||||
default y
|
||||
|
||||
@@ -326,8 +326,8 @@
|
||||
blsp2_spi5: spi@075ba000{
|
||||
compatible = "qcom,spi-qup-v2.2.1";
|
||||
reg = <0x075ba000 0x600>;
|
||||
interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&gcc GCC_BLSP2_QUP5_SPI_APPS_CLK>,
|
||||
interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&gcc GCC_BLSP2_QUP6_SPI_APPS_CLK>,
|
||||
<&gcc GCC_BLSP2_AHB_CLK>;
|
||||
clock-names = "core", "iface";
|
||||
pinctrl-names = "default", "sleep";
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/cpufeature.h>
|
||||
#include <asm/cputype.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable-hwdef.h>
|
||||
#include <asm/ptrace.h>
|
||||
@@ -462,4 +463,43 @@ alternative_endif
|
||||
and \phys, \pte, #(((1 << (48 - PAGE_SHIFT)) - 1) << PAGE_SHIFT)
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Check the MIDR_EL1 of the current CPU for a given model and a range of
|
||||
* variant/revision. See asm/cputype.h for the macros used below.
|
||||
*
|
||||
* model: MIDR_CPU_MODEL of CPU
|
||||
* rv_min: Minimum of MIDR_CPU_VAR_REV()
|
||||
* rv_max: Maximum of MIDR_CPU_VAR_REV()
|
||||
* res: Result register.
|
||||
* tmp1, tmp2, tmp3: Temporary registers
|
||||
*
|
||||
* Corrupts: res, tmp1, tmp2, tmp3
|
||||
* Returns: 0, if the CPU id doesn't match. Non-zero otherwise
|
||||
*/
|
||||
.macro cpu_midr_match model, rv_min, rv_max, res, tmp1, tmp2, tmp3
|
||||
mrs \res, midr_el1
|
||||
mov_q \tmp1, (MIDR_REVISION_MASK | MIDR_VARIANT_MASK)
|
||||
mov_q \tmp2, MIDR_CPU_MODEL_MASK
|
||||
and \tmp3, \res, \tmp2 // Extract model
|
||||
and \tmp1, \res, \tmp1 // rev & variant
|
||||
mov_q \tmp2, \model
|
||||
cmp \tmp3, \tmp2
|
||||
cset \res, eq
|
||||
cbz \res, .Ldone\@ // Model matches ?
|
||||
|
||||
.if (\rv_min != 0) // Skip min check if rv_min == 0
|
||||
mov_q \tmp3, \rv_min
|
||||
cmp \tmp1, \tmp3
|
||||
cset \res, ge
|
||||
.endif // \rv_min != 0
|
||||
/* Skip rv_max check if rv_min == rv_max && rv_min != 0 */
|
||||
.if ((\rv_min != \rv_max) || \rv_min == 0)
|
||||
mov_q \tmp2, \rv_max
|
||||
cmp \tmp1, \tmp2
|
||||
cset \tmp2, le
|
||||
and \res, \res, \tmp2
|
||||
.endif
|
||||
.Ldone\@:
|
||||
.endm
|
||||
|
||||
#endif /* __ASM_ASSEMBLER_H */
|
||||
|
||||
@@ -117,7 +117,7 @@ static inline void atomic_and(int i, atomic_t *v)
|
||||
/* LSE atomics */
|
||||
" mvn %w[i], %w[i]\n"
|
||||
" stclr %w[i], %[v]")
|
||||
: [i] "+r" (w0), [v] "+Q" (v->counter)
|
||||
: [i] "+&r" (w0), [v] "+Q" (v->counter)
|
||||
: "r" (x1)
|
||||
: __LL_SC_CLOBBERS);
|
||||
}
|
||||
@@ -135,7 +135,7 @@ static inline int atomic_fetch_and##name(int i, atomic_t *v) \
|
||||
/* LSE atomics */ \
|
||||
" mvn %w[i], %w[i]\n" \
|
||||
" ldclr" #mb " %w[i], %w[i], %[v]") \
|
||||
: [i] "+r" (w0), [v] "+Q" (v->counter) \
|
||||
: [i] "+&r" (w0), [v] "+Q" (v->counter) \
|
||||
: "r" (x1) \
|
||||
: __LL_SC_CLOBBERS, ##cl); \
|
||||
\
|
||||
@@ -161,7 +161,7 @@ static inline void atomic_sub(int i, atomic_t *v)
|
||||
/* LSE atomics */
|
||||
" neg %w[i], %w[i]\n"
|
||||
" stadd %w[i], %[v]")
|
||||
: [i] "+r" (w0), [v] "+Q" (v->counter)
|
||||
: [i] "+&r" (w0), [v] "+Q" (v->counter)
|
||||
: "r" (x1)
|
||||
: __LL_SC_CLOBBERS);
|
||||
}
|
||||
@@ -180,7 +180,7 @@ static inline int atomic_sub_return##name(int i, atomic_t *v) \
|
||||
" neg %w[i], %w[i]\n" \
|
||||
" ldadd" #mb " %w[i], w30, %[v]\n" \
|
||||
" add %w[i], %w[i], w30") \
|
||||
: [i] "+r" (w0), [v] "+Q" (v->counter) \
|
||||
: [i] "+&r" (w0), [v] "+Q" (v->counter) \
|
||||
: "r" (x1) \
|
||||
: __LL_SC_CLOBBERS , ##cl); \
|
||||
\
|
||||
@@ -207,7 +207,7 @@ static inline int atomic_fetch_sub##name(int i, atomic_t *v) \
|
||||
/* LSE atomics */ \
|
||||
" neg %w[i], %w[i]\n" \
|
||||
" ldadd" #mb " %w[i], %w[i], %[v]") \
|
||||
: [i] "+r" (w0), [v] "+Q" (v->counter) \
|
||||
: [i] "+&r" (w0), [v] "+Q" (v->counter) \
|
||||
: "r" (x1) \
|
||||
: __LL_SC_CLOBBERS, ##cl); \
|
||||
\
|
||||
@@ -314,7 +314,7 @@ static inline void atomic64_and(long i, atomic64_t *v)
|
||||
/* LSE atomics */
|
||||
" mvn %[i], %[i]\n"
|
||||
" stclr %[i], %[v]")
|
||||
: [i] "+r" (x0), [v] "+Q" (v->counter)
|
||||
: [i] "+&r" (x0), [v] "+Q" (v->counter)
|
||||
: "r" (x1)
|
||||
: __LL_SC_CLOBBERS);
|
||||
}
|
||||
@@ -332,7 +332,7 @@ static inline long atomic64_fetch_and##name(long i, atomic64_t *v) \
|
||||
/* LSE atomics */ \
|
||||
" mvn %[i], %[i]\n" \
|
||||
" ldclr" #mb " %[i], %[i], %[v]") \
|
||||
: [i] "+r" (x0), [v] "+Q" (v->counter) \
|
||||
: [i] "+&r" (x0), [v] "+Q" (v->counter) \
|
||||
: "r" (x1) \
|
||||
: __LL_SC_CLOBBERS, ##cl); \
|
||||
\
|
||||
@@ -358,7 +358,7 @@ static inline void atomic64_sub(long i, atomic64_t *v)
|
||||
/* LSE atomics */
|
||||
" neg %[i], %[i]\n"
|
||||
" stadd %[i], %[v]")
|
||||
: [i] "+r" (x0), [v] "+Q" (v->counter)
|
||||
: [i] "+&r" (x0), [v] "+Q" (v->counter)
|
||||
: "r" (x1)
|
||||
: __LL_SC_CLOBBERS);
|
||||
}
|
||||
@@ -377,7 +377,7 @@ static inline long atomic64_sub_return##name(long i, atomic64_t *v) \
|
||||
" neg %[i], %[i]\n" \
|
||||
" ldadd" #mb " %[i], x30, %[v]\n" \
|
||||
" add %[i], %[i], x30") \
|
||||
: [i] "+r" (x0), [v] "+Q" (v->counter) \
|
||||
: [i] "+&r" (x0), [v] "+Q" (v->counter) \
|
||||
: "r" (x1) \
|
||||
: __LL_SC_CLOBBERS, ##cl); \
|
||||
\
|
||||
@@ -404,7 +404,7 @@ static inline long atomic64_fetch_sub##name(long i, atomic64_t *v) \
|
||||
/* LSE atomics */ \
|
||||
" neg %[i], %[i]\n" \
|
||||
" ldadd" #mb " %[i], %[i], %[v]") \
|
||||
: [i] "+r" (x0), [v] "+Q" (v->counter) \
|
||||
: [i] "+&r" (x0), [v] "+Q" (v->counter) \
|
||||
: "r" (x1) \
|
||||
: __LL_SC_CLOBBERS, ##cl); \
|
||||
\
|
||||
@@ -516,7 +516,7 @@ static inline long __cmpxchg_double##name(unsigned long old1, \
|
||||
" eor %[old1], %[old1], %[oldval1]\n" \
|
||||
" eor %[old2], %[old2], %[oldval2]\n" \
|
||||
" orr %[old1], %[old1], %[old2]") \
|
||||
: [old1] "+r" (x0), [old2] "+r" (x1), \
|
||||
: [old1] "+&r" (x0), [old2] "+&r" (x1), \
|
||||
[v] "+Q" (*(unsigned long *)ptr) \
|
||||
: [new1] "r" (x2), [new2] "r" (x3), [ptr] "r" (x4), \
|
||||
[oldval1] "r" (oldval1), [oldval2] "r" (oldval2) \
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
#ifndef __ASM_CPUFEATURE_H
|
||||
#define __ASM_CPUFEATURE_H
|
||||
|
||||
#include <linux/jump_label.h>
|
||||
|
||||
#include <asm/cpucaps.h>
|
||||
#include <asm/hwcap.h>
|
||||
#include <asm/sysreg.h>
|
||||
@@ -27,6 +25,8 @@
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/bug.h>
|
||||
#include <linux/jump_label.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
/* CPU feature register tracking */
|
||||
@@ -96,6 +96,7 @@ struct arm64_cpu_capabilities {
|
||||
|
||||
extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
|
||||
extern struct static_key_false cpu_hwcap_keys[ARM64_NCAPS];
|
||||
extern struct static_key_false arm64_const_caps_ready;
|
||||
|
||||
bool this_cpu_has_cap(unsigned int cap);
|
||||
|
||||
@@ -104,14 +105,27 @@ static inline bool cpu_have_feature(unsigned int num)
|
||||
return elf_hwcap & (1UL << num);
|
||||
}
|
||||
|
||||
/* System capability check for constant caps */
|
||||
static inline bool __cpus_have_const_cap(int num)
|
||||
{
|
||||
if (num >= ARM64_NCAPS)
|
||||
return false;
|
||||
return static_branch_unlikely(&cpu_hwcap_keys[num]);
|
||||
}
|
||||
|
||||
static inline bool cpus_have_cap(unsigned int num)
|
||||
{
|
||||
if (num >= ARM64_NCAPS)
|
||||
return false;
|
||||
if (__builtin_constant_p(num))
|
||||
return static_branch_unlikely(&cpu_hwcap_keys[num]);
|
||||
return test_bit(num, cpu_hwcaps);
|
||||
}
|
||||
|
||||
static inline bool cpus_have_const_cap(int num)
|
||||
{
|
||||
if (static_branch_likely(&arm64_const_caps_ready))
|
||||
return __cpus_have_const_cap(num);
|
||||
else
|
||||
return test_bit(num, cpu_hwcaps);
|
||||
return cpus_have_cap(num);
|
||||
}
|
||||
|
||||
static inline void cpus_set_cap(unsigned int num)
|
||||
@@ -121,7 +135,6 @@ static inline void cpus_set_cap(unsigned int num)
|
||||
num, ARM64_NCAPS);
|
||||
} else {
|
||||
__set_bit(num, cpu_hwcaps);
|
||||
static_branch_enable(&cpu_hwcap_keys[num]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +213,7 @@ static inline bool cpu_supports_mixed_endian_el0(void)
|
||||
|
||||
static inline bool system_supports_32bit_el0(void)
|
||||
{
|
||||
return cpus_have_cap(ARM64_HAS_32BIT_EL0);
|
||||
return cpus_have_const_cap(ARM64_HAS_32BIT_EL0);
|
||||
}
|
||||
|
||||
static inline bool system_supports_mixed_endian_el0(void)
|
||||
|
||||
@@ -56,6 +56,9 @@
|
||||
(0xf << MIDR_ARCHITECTURE_SHIFT) | \
|
||||
((partnum) << MIDR_PARTNUM_SHIFT))
|
||||
|
||||
#define MIDR_CPU_VAR_REV(var, rev) \
|
||||
(((var) << MIDR_VARIANT_SHIFT) | (rev))
|
||||
|
||||
#define MIDR_CPU_MODEL_MASK (MIDR_IMPLEMENTOR_MASK | MIDR_PARTNUM_MASK | \
|
||||
MIDR_ARCHITECTURE_MASK)
|
||||
|
||||
@@ -74,6 +77,7 @@
|
||||
|
||||
#define ARM_CPU_PART_AEM_V8 0xD0F
|
||||
#define ARM_CPU_PART_FOUNDATION 0xD00
|
||||
#define ARM_CPU_PART_CORTEX_A55 0xD05
|
||||
#define ARM_CPU_PART_CORTEX_A57 0xD07
|
||||
#define ARM_CPU_PART_CORTEX_A72 0xD08
|
||||
#define ARM_CPU_PART_CORTEX_A53 0xD03
|
||||
@@ -89,6 +93,7 @@
|
||||
#define BRCM_CPU_PART_VULCAN 0x516
|
||||
|
||||
#define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
|
||||
#define MIDR_CORTEX_A55 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A55)
|
||||
#define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
|
||||
#define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
|
||||
#define MIDR_CORTEX_A73 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A73)
|
||||
|
||||
@@ -48,20 +48,9 @@ do { \
|
||||
} while (0)
|
||||
|
||||
static inline int
|
||||
futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *_uaddr)
|
||||
arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (int)(encoded_op << 8) >> 20;
|
||||
int cmparg = (int)(encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret, tmp;
|
||||
u32 __user *uaddr = __uaccess_mask_ptr(_uaddr);
|
||||
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1U << (oparg & 0x1f);
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
@@ -92,17 +81,9 @@ futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *_uaddr)
|
||||
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
|
||||
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
|
||||
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
|
||||
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
|
||||
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
|
||||
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
|
||||
default: ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/kvm_types.h>
|
||||
#include <asm/cpufeature.h>
|
||||
#include <asm/kvm.h>
|
||||
#include <asm/kvm_asm.h>
|
||||
#include <asm/kvm_mmio.h>
|
||||
@@ -358,9 +359,12 @@ static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
|
||||
unsigned long vector_ptr)
|
||||
{
|
||||
/*
|
||||
* Call initialization code, and switch to the full blown
|
||||
* HYP code.
|
||||
* Call initialization code, and switch to the full blown HYP code.
|
||||
* If the cpucaps haven't been finalized yet, something has gone very
|
||||
* wrong, and hyp will crash and burn when it uses any
|
||||
* cpus_have_const_cap() wrapper.
|
||||
*/
|
||||
BUG_ON(!static_branch_likely(&arm64_const_caps_ready));
|
||||
__kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr);
|
||||
}
|
||||
|
||||
@@ -398,7 +402,7 @@ static inline void __cpu_init_stage2(void)
|
||||
|
||||
static inline bool kvm_arm_harden_branch_predictor(void)
|
||||
{
|
||||
return cpus_have_cap(ARM64_HARDEN_BRANCH_PREDICTOR);
|
||||
return cpus_have_const_cap(ARM64_HARDEN_BRANCH_PREDICTOR);
|
||||
}
|
||||
|
||||
#endif /* __ARM64_KVM_HOST_H__ */
|
||||
|
||||
@@ -313,6 +313,22 @@ static inline unsigned int kvm_get_vmid_bits(void)
|
||||
return (cpuid_feature_extract_unsigned_field(reg, ID_AA64MMFR1_VMIDBITS_SHIFT) == 2) ? 16 : 8;
|
||||
}
|
||||
|
||||
/*
|
||||
* We are not in the kvm->srcu critical section most of the time, so we take
|
||||
* the SRCU read lock here. Since we copy the data from the user page, we
|
||||
* can immediately drop the lock again.
|
||||
*/
|
||||
static inline int kvm_read_guest_lock(struct kvm *kvm,
|
||||
gpa_t gpa, void *data, unsigned long len)
|
||||
{
|
||||
int srcu_idx = srcu_read_lock(&kvm->srcu);
|
||||
int ret = kvm_read_guest(kvm, gpa, data, len);
|
||||
|
||||
srcu_read_unlock(&kvm->srcu, srcu_idx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
|
||||
#include <asm/mmu.h>
|
||||
|
||||
@@ -325,7 +341,7 @@ static inline void *kvm_get_hyp_vector(void)
|
||||
vect = __bp_harden_hyp_vecs_start +
|
||||
data->hyp_vectors_slot * SZ_2K;
|
||||
|
||||
if (!cpus_have_cap(ARM64_HAS_VIRT_HOST_EXTN))
|
||||
if (!cpus_have_const_cap(ARM64_HAS_VIRT_HOST_EXTN))
|
||||
vect = lm_alias(vect);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ typedef struct {
|
||||
static inline bool arm64_kernel_unmapped_at_el0(void)
|
||||
{
|
||||
return IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0) &&
|
||||
cpus_have_cap(ARM64_UNMAP_KERNEL_AT_EL0);
|
||||
cpus_have_const_cap(ARM64_UNMAP_KERNEL_AT_EL0);
|
||||
}
|
||||
|
||||
typedef void (*bp_hardening_cb_t)(void);
|
||||
|
||||
@@ -141,8 +141,8 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock)
|
||||
" cbnz %w1, 1f\n"
|
||||
" add %w1, %w0, %3\n"
|
||||
" casa %w0, %w1, %2\n"
|
||||
" and %w1, %w1, #0xffff\n"
|
||||
" eor %w1, %w1, %w0, lsr #16\n"
|
||||
" sub %w1, %w1, %3\n"
|
||||
" eor %w1, %w1, %w0\n"
|
||||
"1:")
|
||||
: "=&r" (lockval), "=&r" (tmp), "+Q" (*lock)
|
||||
: "I" (1 << TICKET_SHIFT)
|
||||
|
||||
@@ -23,7 +23,7 @@ struct stackframe {
|
||||
unsigned long sp;
|
||||
unsigned long pc;
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
unsigned int graph;
|
||||
int graph;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ static int enable_smccc_arch_workaround_1(void *data)
|
||||
case PSCI_CONDUIT_HVC:
|
||||
arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
|
||||
ARM_SMCCC_ARCH_WORKAROUND_1, &res);
|
||||
if (res.a0)
|
||||
if ((int)res.a0 < 0)
|
||||
return 0;
|
||||
cb = call_hvc_arch_workaround_1;
|
||||
smccc_start = __smccc_workaround_1_hvc_start;
|
||||
@@ -170,7 +170,7 @@ static int enable_smccc_arch_workaround_1(void *data)
|
||||
case PSCI_CONDUIT_SMC:
|
||||
arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
|
||||
ARM_SMCCC_ARCH_WORKAROUND_1, &res);
|
||||
if (res.a0)
|
||||
if ((int)res.a0 < 0)
|
||||
return 0;
|
||||
cb = call_smc_arch_workaround_1;
|
||||
smccc_start = __smccc_workaround_1_smc_start;
|
||||
|
||||
@@ -769,7 +769,7 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
|
||||
* ThunderX leads to apparent I-cache corruption of kernel text, which
|
||||
* ends as well as you might imagine. Don't even try.
|
||||
*/
|
||||
if (cpus_have_cap(ARM64_WORKAROUND_CAVIUM_27456)) {
|
||||
if (cpus_have_const_cap(ARM64_WORKAROUND_CAVIUM_27456)) {
|
||||
str = "ARM64_WORKAROUND_CAVIUM_27456";
|
||||
__kpti_forced = -1;
|
||||
}
|
||||
@@ -832,7 +832,7 @@ static int __init parse_kpti(char *str)
|
||||
__kpti_forced = enabled ? 1 : -1;
|
||||
return 0;
|
||||
}
|
||||
__setup("kpti=", parse_kpti);
|
||||
early_param("kpti", parse_kpti);
|
||||
#endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */
|
||||
|
||||
static const struct arm64_cpu_capabilities arm64_features[] = {
|
||||
@@ -1058,8 +1058,16 @@ void update_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
|
||||
*/
|
||||
void __init enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps)
|
||||
{
|
||||
for (; caps->matches; caps++)
|
||||
if (caps->enable && cpus_have_cap(caps->capability))
|
||||
for (; caps->matches; caps++) {
|
||||
unsigned int num = caps->capability;
|
||||
|
||||
if (!cpus_have_cap(num))
|
||||
continue;
|
||||
|
||||
/* Ensure cpus_have_const_cap(num) works */
|
||||
static_branch_enable(&cpu_hwcap_keys[num]);
|
||||
|
||||
if (caps->enable) {
|
||||
/*
|
||||
* Use stop_machine() as it schedules the work allowing
|
||||
* us to modify PSTATE, instead of on_each_cpu() which
|
||||
@@ -1067,6 +1075,8 @@ void __init enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps)
|
||||
* we return.
|
||||
*/
|
||||
stop_machine(caps->enable, (void *)caps, cpu_online_mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1170,6 +1180,14 @@ static void __init setup_feature_capabilities(void)
|
||||
enable_cpu_capabilities(arm64_features);
|
||||
}
|
||||
|
||||
DEFINE_STATIC_KEY_FALSE(arm64_const_caps_ready);
|
||||
EXPORT_SYMBOL(arm64_const_caps_ready);
|
||||
|
||||
static void __init mark_const_caps_ready(void)
|
||||
{
|
||||
static_branch_enable(&arm64_const_caps_ready);
|
||||
}
|
||||
|
||||
extern const struct arm64_cpu_capabilities arm64_errata[];
|
||||
|
||||
bool this_cpu_has_cap(unsigned int cap)
|
||||
@@ -1186,6 +1204,7 @@ void __init setup_cpu_features(void)
|
||||
/* Set the CPU feature capabilies */
|
||||
setup_feature_capabilities();
|
||||
enable_errata_workarounds();
|
||||
mark_const_caps_ready();
|
||||
setup_elf_hwcaps(arm64_elf_hwcaps);
|
||||
|
||||
if (system_supports_32bit_el0())
|
||||
@@ -1210,5 +1229,5 @@ void __init setup_cpu_features(void)
|
||||
static bool __maybe_unused
|
||||
cpufeature_pan_not_uao(const struct arm64_cpu_capabilities *entry, int __unused)
|
||||
{
|
||||
return (cpus_have_cap(ARM64_HAS_PAN) && !cpus_have_cap(ARM64_HAS_UAO));
|
||||
return (cpus_have_const_cap(ARM64_HAS_PAN) && !cpus_have_const_cap(ARM64_HAS_UAO));
|
||||
}
|
||||
|
||||
@@ -545,7 +545,7 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
|
||||
memset(childregs, 0, sizeof(struct pt_regs));
|
||||
childregs->pstate = PSR_MODE_EL1h;
|
||||
if (IS_ENABLED(CONFIG_ARM64_UAO) &&
|
||||
cpus_have_cap(ARM64_HAS_UAO))
|
||||
cpus_have_const_cap(ARM64_HAS_UAO))
|
||||
childregs->pstate |= PSR_UAO_BIT;
|
||||
p->thread.cpu_context.x19 = stack_start;
|
||||
p->thread.cpu_context.x20 = stk_sz;
|
||||
|
||||
@@ -73,6 +73,11 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
if (tsk->ret_stack &&
|
||||
(frame->pc == (unsigned long)return_to_handler)) {
|
||||
if (WARN_ON_ONCE(frame->graph == -1))
|
||||
return -EINVAL;
|
||||
if (frame->graph < -1)
|
||||
frame->graph += FTRACE_NOTRACE_DEPTH;
|
||||
|
||||
/*
|
||||
* This is a case where function graph tracer has
|
||||
* modified a return address (LR) in a stack frame
|
||||
|
||||
@@ -53,7 +53,7 @@ unsigned long profile_pc(struct pt_regs *regs)
|
||||
frame.sp = regs->sp;
|
||||
frame.pc = regs->pc;
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
frame.graph = -1; /* no task info */
|
||||
frame.graph = current->curr_ret_stack;
|
||||
#endif
|
||||
do {
|
||||
int ret = unwind_frame(NULL, &frame);
|
||||
|
||||
@@ -195,8 +195,9 @@ ENDPROC(idmap_cpu_replace_ttbr1)
|
||||
|
||||
.macro __idmap_kpti_put_pgtable_ent_ng, type
|
||||
orr \type, \type, #PTE_NG // Same bit for blocks and pages
|
||||
str \type, [cur_\()\type\()p] // Update the entry and ensure it
|
||||
dc civac, cur_\()\type\()p // is visible to all CPUs.
|
||||
str \type, [cur_\()\type\()p] // Update the entry and ensure
|
||||
dmb sy // that it is visible to all
|
||||
dc civac, cur_\()\type\()p // CPUs.
|
||||
.endm
|
||||
|
||||
/*
|
||||
@@ -434,6 +435,11 @@ ENTRY(__cpu_setup)
|
||||
cbz x9, 2f
|
||||
cmp x9, #2
|
||||
b.lt 1f
|
||||
#ifdef CONFIG_ARM64_ERRATUM_1024718
|
||||
/* Disable hardware DBM on Cortex-A55 r0p0, r0p1 & r1p0 */
|
||||
cpu_midr_match MIDR_CORTEX_A55, MIDR_CPU_VAR_REV(0, 0), MIDR_CPU_VAR_REV(1, 0), x1, x2, x3, x4
|
||||
cbnz x1, 1f
|
||||
#endif
|
||||
orr x10, x10, #TCR_HD // hardware Dirty flag update
|
||||
1: orr x10, x10, #TCR_HA // hardware Access flag update
|
||||
2:
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
#include <asm/errno.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
extern int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr);
|
||||
extern int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
|
||||
u32 __user *uaddr);
|
||||
|
||||
static inline int
|
||||
futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
|
||||
|
||||
@@ -186,20 +186,10 @@ static inline int atomic_futex_op_xchg_xor(int oparg, u32 __user *uaddr, int *_o
|
||||
/*
|
||||
* do the futex operations
|
||||
*/
|
||||
int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
||||
int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret;
|
||||
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
switch (op) {
|
||||
@@ -225,18 +215,9 @@ int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
||||
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
|
||||
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
|
||||
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
|
||||
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
|
||||
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
|
||||
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
|
||||
default: ret = -ENOSYS; break;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
|
||||
} /* end futex_atomic_op_inuser() */
|
||||
} /* end arch_futex_atomic_op_inuser() */
|
||||
|
||||
@@ -31,18 +31,9 @@
|
||||
|
||||
|
||||
static inline int
|
||||
futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
|
||||
arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret;
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
|
||||
return -EFAULT;
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
@@ -72,30 +63,9 @@ futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
|
||||
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ:
|
||||
ret = (oldval == cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_NE:
|
||||
ret = (oldval != cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_LT:
|
||||
ret = (oldval < cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_GE:
|
||||
ret = (oldval >= cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_LE:
|
||||
ret = (oldval <= cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_GT:
|
||||
ret = (oldval > cmparg);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,18 +45,9 @@ do { \
|
||||
} while (0)
|
||||
|
||||
static inline int
|
||||
futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
|
||||
arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret;
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
@@ -84,17 +75,9 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
|
||||
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
|
||||
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
|
||||
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
|
||||
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
|
||||
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
|
||||
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
|
||||
default: ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ store_virtual_to_phys(struct device *dev, struct device_attribute *attr,
|
||||
u64 virt_addr=simple_strtoull(buf, NULL, 16);
|
||||
int ret;
|
||||
|
||||
ret = get_user_pages(virt_addr, 1, FOLL_WRITE, NULL, NULL);
|
||||
ret = get_user_pages_fast(virt_addr, 1, FOLL_WRITE, NULL);
|
||||
if (ret<=0) {
|
||||
#ifdef ERR_INJ_DEBUG
|
||||
printk("Virtual address %lx is not existing.\n",virt_addr);
|
||||
|
||||
@@ -135,7 +135,11 @@ static struct platform_device mcf_fec0 = {
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(mcf_fec0_resources),
|
||||
.resource = mcf_fec0_resources,
|
||||
.dev.platform_data = FEC_PDATA,
|
||||
.dev = {
|
||||
.dma_mask = &mcf_fec0.dev.coherent_dma_mask,
|
||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||
.platform_data = FEC_PDATA,
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef MCFFEC_BASE1
|
||||
@@ -167,7 +171,11 @@ static struct platform_device mcf_fec1 = {
|
||||
.id = 1,
|
||||
.num_resources = ARRAY_SIZE(mcf_fec1_resources),
|
||||
.resource = mcf_fec1_resources,
|
||||
.dev.platform_data = FEC_PDATA,
|
||||
.dev = {
|
||||
.dma_mask = &mcf_fec1.dev.coherent_dma_mask,
|
||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||
.platform_data = FEC_PDATA,
|
||||
}
|
||||
};
|
||||
#endif /* MCFFEC_BASE1 */
|
||||
#endif /* CONFIG_FEC */
|
||||
|
||||
@@ -88,7 +88,8 @@ static inline void free_io_area(void *addr)
|
||||
for (p = &iolist ; (tmp = *p) ; p = &tmp->next) {
|
||||
if (tmp->addr == addr) {
|
||||
*p = tmp->next;
|
||||
__iounmap(tmp->addr, tmp->size);
|
||||
/* remove gap added in get_io_area() */
|
||||
__iounmap(tmp->addr, tmp->size - IO_SIZE);
|
||||
kfree(tmp);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -29,18 +29,9 @@
|
||||
})
|
||||
|
||||
static inline int
|
||||
futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
||||
arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret;
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
@@ -66,30 +57,9 @@ futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
||||
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ:
|
||||
ret = (oldval == cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_NE:
|
||||
ret = (oldval != cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_LT:
|
||||
ret = (oldval < cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_GE:
|
||||
ret = (oldval >= cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_LE:
|
||||
ret = (oldval <= cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_GT:
|
||||
ret = (oldval > cmparg);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -212,6 +212,12 @@ static int __init bcm47xx_cpu_fixes(void)
|
||||
*/
|
||||
if (bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4706)
|
||||
cpu_wait = NULL;
|
||||
|
||||
/*
|
||||
* BCM47XX Erratum "R10: PCIe Transactions Periodically Fail"
|
||||
* Enable ExternalSync for sync instruction to take effect
|
||||
*/
|
||||
set_c0_config7(MIPS_CONF7_ES);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2271,7 +2271,7 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node,
|
||||
|
||||
parent_irq = irq_of_parse_and_map(ciu_node, 0);
|
||||
if (!parent_irq) {
|
||||
pr_err("ERROR: Couldn't acquire parent_irq for %s\n.",
|
||||
pr_err("ERROR: Couldn't acquire parent_irq for %s\n",
|
||||
ciu_node->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -2283,7 +2283,7 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node,
|
||||
|
||||
addr = of_get_address(ciu_node, 0, NULL, NULL);
|
||||
if (!addr) {
|
||||
pr_err("ERROR: Couldn't acquire reg(0) %s\n.", ciu_node->name);
|
||||
pr_err("ERROR: Couldn't acquire reg(0) %s\n", ciu_node->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
host_data->raw_reg = (u64)phys_to_virt(
|
||||
@@ -2291,7 +2291,7 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node,
|
||||
|
||||
addr = of_get_address(ciu_node, 1, NULL, NULL);
|
||||
if (!addr) {
|
||||
pr_err("ERROR: Couldn't acquire reg(1) %s\n.", ciu_node->name);
|
||||
pr_err("ERROR: Couldn't acquire reg(1) %s\n", ciu_node->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
host_data->en_reg = (u64)phys_to_virt(
|
||||
@@ -2299,7 +2299,7 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node,
|
||||
|
||||
r = of_property_read_u32(ciu_node, "cavium,max-bits", &val);
|
||||
if (r) {
|
||||
pr_err("ERROR: Couldn't read cavium,max-bits from %s\n.",
|
||||
pr_err("ERROR: Couldn't read cavium,max-bits from %s\n",
|
||||
ciu_node->name);
|
||||
return r;
|
||||
}
|
||||
@@ -2309,7 +2309,7 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node,
|
||||
&octeon_irq_domain_cib_ops,
|
||||
host_data);
|
||||
if (!cib_domain) {
|
||||
pr_err("ERROR: Couldn't irq_domain_add_linear()\n.");
|
||||
pr_err("ERROR: Couldn't irq_domain_add_linear()\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,18 +83,9 @@
|
||||
}
|
||||
|
||||
static inline int
|
||||
futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
||||
arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret;
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
@@ -125,17 +116,9 @@ futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
||||
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
|
||||
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
|
||||
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
|
||||
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
|
||||
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
|
||||
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
|
||||
default: ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -412,6 +412,8 @@ static inline type pfx##in##bwlq##p(unsigned long port) \
|
||||
__val = *__addr; \
|
||||
slow; \
|
||||
\
|
||||
/* prevent prefetching of coherent DMA data prematurely */ \
|
||||
rmb(); \
|
||||
return pfx##ioswab##bwlq(__addr, __val); \
|
||||
}
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
#define AR71XX_AHB_DIV_MASK 0x7
|
||||
|
||||
#define AR724X_PLL_REG_CPU_CONFIG 0x00
|
||||
#define AR724X_PLL_REG_PCIE_CONFIG 0x18
|
||||
#define AR724X_PLL_REG_PCIE_CONFIG 0x10
|
||||
|
||||
#define AR724X_PLL_FB_SHIFT 0
|
||||
#define AR724X_PLL_FB_MASK 0x3ff
|
||||
|
||||
@@ -52,7 +52,7 @@ mips_machine_is_compatible(const struct mips_machine *mach, const void *fdt)
|
||||
if (!mach->matches)
|
||||
return NULL;
|
||||
|
||||
for (match = mach->matches; match->compatible; match++) {
|
||||
for (match = mach->matches; match->compatible[0]; match++) {
|
||||
if (fdt_node_check_compatible(fdt, 0, match->compatible) == 0)
|
||||
return match;
|
||||
}
|
||||
|
||||
@@ -663,6 +663,8 @@
|
||||
#define MIPS_CONF7_WII (_ULCAST_(1) << 31)
|
||||
|
||||
#define MIPS_CONF7_RPS (_ULCAST_(1) << 2)
|
||||
/* ExternalSync */
|
||||
#define MIPS_CONF7_ES (_ULCAST_(1) << 8)
|
||||
|
||||
#define MIPS_CONF7_IAR (_ULCAST_(1) << 10)
|
||||
#define MIPS_CONF7_AR (_ULCAST_(1) << 16)
|
||||
@@ -2641,6 +2643,7 @@ __BUILD_SET_C0(status)
|
||||
__BUILD_SET_C0(cause)
|
||||
__BUILD_SET_C0(config)
|
||||
__BUILD_SET_C0(config5)
|
||||
__BUILD_SET_C0(config7)
|
||||
__BUILD_SET_C0(intcontrol)
|
||||
__BUILD_SET_C0(intctl)
|
||||
__BUILD_SET_C0(srsmap)
|
||||
|
||||
@@ -116,10 +116,20 @@ ftrace_stub:
|
||||
NESTED(_mcount, PT_SIZE, ra)
|
||||
PTR_LA t1, ftrace_stub
|
||||
PTR_L t2, ftrace_trace_function /* Prepare t2 for (1) */
|
||||
bne t1, t2, static_trace
|
||||
beq t1, t2, fgraph_trace
|
||||
nop
|
||||
|
||||
MCOUNT_SAVE_REGS
|
||||
|
||||
move a0, ra /* arg1: self return address */
|
||||
jalr t2 /* (1) call *ftrace_trace_function */
|
||||
move a1, AT /* arg2: parent's return address */
|
||||
|
||||
MCOUNT_RESTORE_REGS
|
||||
|
||||
fgraph_trace:
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
PTR_LA t1, ftrace_stub
|
||||
PTR_L t3, ftrace_graph_return
|
||||
bne t1, t3, ftrace_graph_caller
|
||||
nop
|
||||
@@ -128,24 +138,11 @@ NESTED(_mcount, PT_SIZE, ra)
|
||||
bne t1, t3, ftrace_graph_caller
|
||||
nop
|
||||
#endif
|
||||
b ftrace_stub
|
||||
#ifdef CONFIG_32BIT
|
||||
addiu sp, sp, 8
|
||||
#else
|
||||
nop
|
||||
#endif
|
||||
|
||||
static_trace:
|
||||
MCOUNT_SAVE_REGS
|
||||
|
||||
move a0, ra /* arg1: self return address */
|
||||
jalr t2 /* (1) call *ftrace_trace_function */
|
||||
move a1, AT /* arg2: parent's return address */
|
||||
|
||||
MCOUNT_RESTORE_REGS
|
||||
#ifdef CONFIG_32BIT
|
||||
addiu sp, sp, 8
|
||||
#endif
|
||||
|
||||
.globl ftrace_stub
|
||||
ftrace_stub:
|
||||
RETURN_BACK
|
||||
|
||||
@@ -641,8 +641,8 @@ static void arch_dump_stack(void *info)
|
||||
|
||||
if (regs)
|
||||
show_regs(regs);
|
||||
|
||||
dump_stack();
|
||||
else
|
||||
dump_stack();
|
||||
}
|
||||
|
||||
void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self)
|
||||
@@ -699,6 +699,10 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value)
|
||||
if (value & ~known_bits)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* Setting FRE without FR is not supported. */
|
||||
if ((value & (PR_FP_MODE_FR | PR_FP_MODE_FRE)) == PR_FP_MODE_FRE)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* Avoid inadvertently triggering emulation */
|
||||
if ((value & PR_FP_MODE_FR) && raw_cpu_has_fpu &&
|
||||
!(raw_current_cpu_data.fpu_id & MIPS_FPIR_F64))
|
||||
|
||||
@@ -483,7 +483,7 @@ static int fpr_get_msa(struct task_struct *target,
|
||||
/*
|
||||
* Copy the floating-point context to the supplied NT_PRFPREG buffer.
|
||||
* Choose the appropriate helper for general registers, and then copy
|
||||
* the FCSR register separately.
|
||||
* the FCSR and FIR registers separately.
|
||||
*/
|
||||
static int fpr_get(struct task_struct *target,
|
||||
const struct user_regset *regset,
|
||||
@@ -491,6 +491,7 @@ static int fpr_get(struct task_struct *target,
|
||||
void *kbuf, void __user *ubuf)
|
||||
{
|
||||
const int fcr31_pos = NUM_FPU_REGS * sizeof(elf_fpreg_t);
|
||||
const int fir_pos = fcr31_pos + sizeof(u32);
|
||||
int err;
|
||||
|
||||
if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t))
|
||||
@@ -503,6 +504,12 @@ static int fpr_get(struct task_struct *target,
|
||||
err = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
|
||||
&target->thread.fpu.fcr31,
|
||||
fcr31_pos, fcr31_pos + sizeof(u32));
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
|
||||
&boot_cpu_data.fpu_id,
|
||||
fir_pos, fir_pos + sizeof(u32));
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -551,7 +558,8 @@ static int fpr_set_msa(struct task_struct *target,
|
||||
/*
|
||||
* Copy the supplied NT_PRFPREG buffer to the floating-point context.
|
||||
* Choose the appropriate helper for general registers, and then copy
|
||||
* the FCSR register separately.
|
||||
* the FCSR register separately. Ignore the incoming FIR register
|
||||
* contents though, as the register is read-only.
|
||||
*
|
||||
* We optimize for the case where `count % sizeof(elf_fpreg_t) == 0',
|
||||
* which is supposed to have been guaranteed by the kernel before
|
||||
@@ -565,6 +573,7 @@ static int fpr_set(struct task_struct *target,
|
||||
const void *kbuf, const void __user *ubuf)
|
||||
{
|
||||
const int fcr31_pos = NUM_FPU_REGS * sizeof(elf_fpreg_t);
|
||||
const int fir_pos = fcr31_pos + sizeof(u32);
|
||||
u32 fcr31;
|
||||
int err;
|
||||
|
||||
@@ -592,6 +601,11 @@ static int fpr_set(struct task_struct *target,
|
||||
ptrace_setfcr31(target, fcr31);
|
||||
}
|
||||
|
||||
if (count > 0)
|
||||
err = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
|
||||
fir_pos,
|
||||
fir_pos + sizeof(u32));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -813,7 +827,7 @@ long arch_ptrace(struct task_struct *child, long request,
|
||||
fregs = get_fpu_regs(child);
|
||||
|
||||
#ifdef CONFIG_32BIT
|
||||
if (test_thread_flag(TIF_32BIT_FPREGS)) {
|
||||
if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) {
|
||||
/*
|
||||
* The odd registers are actually the high
|
||||
* order bits of the values stored in the even
|
||||
@@ -824,7 +838,7 @@ long arch_ptrace(struct task_struct *child, long request,
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
tmp = get_fpr32(&fregs[addr - FPR_BASE], 0);
|
||||
tmp = get_fpr64(&fregs[addr - FPR_BASE], 0);
|
||||
break;
|
||||
case PC:
|
||||
tmp = regs->cp0_epc;
|
||||
@@ -902,7 +916,7 @@ long arch_ptrace(struct task_struct *child, long request,
|
||||
|
||||
init_fp_ctx(child);
|
||||
#ifdef CONFIG_32BIT
|
||||
if (test_thread_flag(TIF_32BIT_FPREGS)) {
|
||||
if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) {
|
||||
/*
|
||||
* The odd registers are actually the high
|
||||
* order bits of the values stored in the even
|
||||
|
||||
@@ -97,7 +97,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
||||
break;
|
||||
}
|
||||
fregs = get_fpu_regs(child);
|
||||
if (test_thread_flag(TIF_32BIT_FPREGS)) {
|
||||
if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) {
|
||||
/*
|
||||
* The odd registers are actually the high
|
||||
* order bits of the values stored in the even
|
||||
@@ -107,7 +107,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
||||
addr & 1);
|
||||
break;
|
||||
}
|
||||
tmp = get_fpr32(&fregs[addr - FPR_BASE], 0);
|
||||
tmp = get_fpr64(&fregs[addr - FPR_BASE], 0);
|
||||
break;
|
||||
case PC:
|
||||
tmp = regs->cp0_epc;
|
||||
@@ -204,7 +204,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
||||
sizeof(child->thread.fpu));
|
||||
child->thread.fpu.fcr31 = 0;
|
||||
}
|
||||
if (test_thread_flag(TIF_32BIT_FPREGS)) {
|
||||
if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) {
|
||||
/*
|
||||
* The odd registers are actually the high
|
||||
* order bits of the values stored in the even
|
||||
|
||||
@@ -351,6 +351,7 @@ static void __show_regs(const struct pt_regs *regs)
|
||||
void show_regs(struct pt_regs *regs)
|
||||
{
|
||||
__show_regs((struct pt_regs *)regs);
|
||||
dump_stack();
|
||||
}
|
||||
|
||||
void show_registers(struct pt_regs *regs)
|
||||
|
||||
@@ -42,7 +42,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
|
||||
{ "cache", VCPU_STAT(cache_exits), KVM_STAT_VCPU },
|
||||
{ "signal", VCPU_STAT(signal_exits), KVM_STAT_VCPU },
|
||||
{ "interrupt", VCPU_STAT(int_exits), KVM_STAT_VCPU },
|
||||
{ "cop_unsuable", VCPU_STAT(cop_unusable_exits), KVM_STAT_VCPU },
|
||||
{ "cop_unusable", VCPU_STAT(cop_unusable_exits), KVM_STAT_VCPU },
|
||||
{ "tlbmod", VCPU_STAT(tlbmod_exits), KVM_STAT_VCPU },
|
||||
{ "tlbmiss_ld", VCPU_STAT(tlbmiss_ld_exits), KVM_STAT_VCPU },
|
||||
{ "tlbmiss_st", VCPU_STAT(tlbmiss_st_exits), KVM_STAT_VCPU },
|
||||
|
||||
@@ -851,9 +851,12 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
|
||||
/*
|
||||
* Either no secondary cache or the available caches don't have the
|
||||
* subset property so we have to flush the primary caches
|
||||
* explicitly
|
||||
* explicitly.
|
||||
* If we would need IPI to perform an INDEX-type operation, then
|
||||
* we have to use the HIT-type alternative as IPI cannot be used
|
||||
* here due to interrupts possibly being disabled.
|
||||
*/
|
||||
if (size >= dcache_size) {
|
||||
if (!r4k_op_needs_ipi(R4K_INDEX) && size >= dcache_size) {
|
||||
r4k_blast_dcache();
|
||||
} else {
|
||||
R4600_HIT_CACHEOP_WAR_IMPL;
|
||||
@@ -890,7 +893,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
|
||||
return;
|
||||
}
|
||||
|
||||
if (size >= dcache_size) {
|
||||
if (!r4k_op_needs_ipi(R4K_INDEX) && size >= dcache_size) {
|
||||
r4k_blast_dcache();
|
||||
} else {
|
||||
R4600_HIT_CACHEOP_WAR_IMPL;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <linux/export.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
@@ -97,6 +98,20 @@ static int remap_area_pages(unsigned long address, phys_addr_t phys_addr,
|
||||
return error;
|
||||
}
|
||||
|
||||
static int __ioremap_check_ram(unsigned long start_pfn, unsigned long nr_pages,
|
||||
void *arg)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < nr_pages; i++) {
|
||||
if (pfn_valid(start_pfn + i) &&
|
||||
!PageReserved(pfn_to_page(start_pfn + i)))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generic mapping function (not visible outside):
|
||||
*/
|
||||
@@ -115,8 +130,8 @@ static int remap_area_pages(unsigned long address, phys_addr_t phys_addr,
|
||||
|
||||
void __iomem * __ioremap(phys_addr_t phys_addr, phys_addr_t size, unsigned long flags)
|
||||
{
|
||||
unsigned long offset, pfn, last_pfn;
|
||||
struct vm_struct * area;
|
||||
unsigned long offset;
|
||||
phys_addr_t last_addr;
|
||||
void * addr;
|
||||
|
||||
@@ -136,18 +151,16 @@ void __iomem * __ioremap(phys_addr_t phys_addr, phys_addr_t size, unsigned long
|
||||
return (void __iomem *) CKSEG1ADDR(phys_addr);
|
||||
|
||||
/*
|
||||
* Don't allow anybody to remap normal RAM that we're using..
|
||||
* Don't allow anybody to remap RAM that may be allocated by the page
|
||||
* allocator, since that could lead to races & data clobbering.
|
||||
*/
|
||||
if (phys_addr < virt_to_phys(high_memory)) {
|
||||
char *t_addr, *t_end;
|
||||
struct page *page;
|
||||
|
||||
t_addr = __va(phys_addr);
|
||||
t_end = t_addr + (size - 1);
|
||||
|
||||
for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
|
||||
if(!PageReserved(page))
|
||||
return NULL;
|
||||
pfn = PFN_DOWN(phys_addr);
|
||||
last_pfn = PFN_DOWN(last_addr);
|
||||
if (walk_system_ram_range(pfn, last_pfn - pfn + 1, NULL,
|
||||
__ioremap_check_ram) == 1) {
|
||||
WARN_ONCE(1, "ioremap on RAM at %pa - %pa\n",
|
||||
&phys_addr, &last_addr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -186,7 +186,7 @@ static void __init rbtx4939_update_ioc_pen(void)
|
||||
|
||||
#define RBTX4939_MAX_7SEGLEDS 8
|
||||
|
||||
#if IS_ENABLED(CONFIG_LEDS_CLASS)
|
||||
#if IS_BUILTIN(CONFIG_LEDS_CLASS)
|
||||
static u8 led_val[RBTX4939_MAX_7SEGLEDS];
|
||||
struct rbtx4939_led_data {
|
||||
struct led_classdev cdev;
|
||||
@@ -261,7 +261,7 @@ static inline void rbtx4939_led_setup(void)
|
||||
|
||||
static void __rbtx4939_7segled_putc(unsigned int pos, unsigned char val)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_LEDS_CLASS)
|
||||
#if IS_BUILTIN(CONFIG_LEDS_CLASS)
|
||||
unsigned long flags;
|
||||
local_irq_save(flags);
|
||||
/* bit7: reserved for LED class */
|
||||
|
||||
@@ -32,22 +32,12 @@ _futex_spin_unlock_irqrestore(u32 __user *uaddr, unsigned long int *flags)
|
||||
}
|
||||
|
||||
static inline int
|
||||
futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
|
||||
arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
|
||||
{
|
||||
unsigned long int flags;
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval, ret;
|
||||
u32 tmp;
|
||||
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(*uaddr)))
|
||||
return -EFAULT;
|
||||
|
||||
_futex_spin_lock_irqsave(uaddr, &flags);
|
||||
pagefault_disable();
|
||||
|
||||
@@ -85,17 +75,9 @@ out_pagefault_enable:
|
||||
pagefault_enable();
|
||||
_futex_spin_unlock_irqrestore(uaddr, &flags);
|
||||
|
||||
if (ret == 0) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
|
||||
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
|
||||
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
|
||||
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
|
||||
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
|
||||
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
|
||||
default: ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -92,7 +92,8 @@ $(addprefix $(obj)/,$(zlib-y)): \
|
||||
libfdt := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
|
||||
libfdtheader := fdt.h libfdt.h libfdt_internal.h
|
||||
|
||||
$(addprefix $(obj)/,$(libfdt) libfdt-wrapper.o simpleboot.o epapr.o opal.o): \
|
||||
$(addprefix $(obj)/,$(libfdt) libfdt-wrapper.o simpleboot.o epapr.o opal.o \
|
||||
treeboot-akebono.o treeboot-currituck.o treeboot-iss4xx.o): \
|
||||
$(addprefix $(obj)/,$(libfdtheader))
|
||||
|
||||
src-wlib-y := string.S crt0.S crtsavres.S stdio.c decompress.c main.c \
|
||||
|
||||
@@ -51,6 +51,27 @@
|
||||
#define EX_PPR 88 /* SMT thread status register (priority) */
|
||||
#define EX_CTR 96
|
||||
|
||||
#define STF_ENTRY_BARRIER_SLOT \
|
||||
STF_ENTRY_BARRIER_FIXUP_SECTION; \
|
||||
nop; \
|
||||
nop; \
|
||||
nop
|
||||
|
||||
#define STF_EXIT_BARRIER_SLOT \
|
||||
STF_EXIT_BARRIER_FIXUP_SECTION; \
|
||||
nop; \
|
||||
nop; \
|
||||
nop; \
|
||||
nop; \
|
||||
nop; \
|
||||
nop
|
||||
|
||||
/*
|
||||
* r10 must be free to use, r13 must be paca
|
||||
*/
|
||||
#define INTERRUPT_TO_KERNEL \
|
||||
STF_ENTRY_BARRIER_SLOT
|
||||
|
||||
/*
|
||||
* Macros for annotating the expected destination of (h)rfid
|
||||
*
|
||||
@@ -67,16 +88,19 @@
|
||||
rfid
|
||||
|
||||
#define RFI_TO_USER \
|
||||
STF_EXIT_BARRIER_SLOT; \
|
||||
RFI_FLUSH_SLOT; \
|
||||
rfid; \
|
||||
b rfi_flush_fallback
|
||||
|
||||
#define RFI_TO_USER_OR_KERNEL \
|
||||
STF_EXIT_BARRIER_SLOT; \
|
||||
RFI_FLUSH_SLOT; \
|
||||
rfid; \
|
||||
b rfi_flush_fallback
|
||||
|
||||
#define RFI_TO_GUEST \
|
||||
STF_EXIT_BARRIER_SLOT; \
|
||||
RFI_FLUSH_SLOT; \
|
||||
rfid; \
|
||||
b rfi_flush_fallback
|
||||
@@ -85,21 +109,25 @@
|
||||
hrfid
|
||||
|
||||
#define HRFI_TO_USER \
|
||||
STF_EXIT_BARRIER_SLOT; \
|
||||
RFI_FLUSH_SLOT; \
|
||||
hrfid; \
|
||||
b hrfi_flush_fallback
|
||||
|
||||
#define HRFI_TO_USER_OR_KERNEL \
|
||||
STF_EXIT_BARRIER_SLOT; \
|
||||
RFI_FLUSH_SLOT; \
|
||||
hrfid; \
|
||||
b hrfi_flush_fallback
|
||||
|
||||
#define HRFI_TO_GUEST \
|
||||
STF_EXIT_BARRIER_SLOT; \
|
||||
RFI_FLUSH_SLOT; \
|
||||
hrfid; \
|
||||
b hrfi_flush_fallback
|
||||
|
||||
#define HRFI_TO_UNKNOWN \
|
||||
STF_EXIT_BARRIER_SLOT; \
|
||||
RFI_FLUSH_SLOT; \
|
||||
hrfid; \
|
||||
b hrfi_flush_fallback
|
||||
@@ -225,6 +253,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
|
||||
#define __EXCEPTION_PROLOG_1(area, extra, vec) \
|
||||
OPT_SAVE_REG_TO_PACA(area+EX_PPR, r9, CPU_FTR_HAS_PPR); \
|
||||
OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR); \
|
||||
INTERRUPT_TO_KERNEL; \
|
||||
SAVE_CTR(r10, area); \
|
||||
mfcr r9; \
|
||||
extra(vec); \
|
||||
|
||||
@@ -189,6 +189,22 @@ void apply_feature_fixups(void);
|
||||
void setup_feature_keys(void);
|
||||
#endif
|
||||
|
||||
#define STF_ENTRY_BARRIER_FIXUP_SECTION \
|
||||
953: \
|
||||
.pushsection __stf_entry_barrier_fixup,"a"; \
|
||||
.align 2; \
|
||||
954: \
|
||||
FTR_ENTRY_OFFSET 953b-954b; \
|
||||
.popsection;
|
||||
|
||||
#define STF_EXIT_BARRIER_FIXUP_SECTION \
|
||||
955: \
|
||||
.pushsection __stf_exit_barrier_fixup,"a"; \
|
||||
.align 2; \
|
||||
956: \
|
||||
FTR_ENTRY_OFFSET 955b-956b; \
|
||||
.popsection;
|
||||
|
||||
#define RFI_FLUSH_FIXUP_SECTION \
|
||||
951: \
|
||||
.pushsection __rfi_flush_fixup,"a"; \
|
||||
@@ -200,6 +216,9 @@ void setup_feature_keys(void);
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
extern long stf_barrier_fallback;
|
||||
extern long __start___stf_entry_barrier_fixup, __stop___stf_entry_barrier_fixup;
|
||||
extern long __start___stf_exit_barrier_fixup, __stop___stf_exit_barrier_fixup;
|
||||
extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,18 +31,10 @@
|
||||
: "b" (uaddr), "i" (-EFAULT), "r" (oparg) \
|
||||
: "cr0", "memory")
|
||||
|
||||
static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
|
||||
static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
|
||||
u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret;
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
@@ -68,17 +60,9 @@ static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
|
||||
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
|
||||
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
|
||||
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
|
||||
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
|
||||
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
|
||||
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
|
||||
default: ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -313,6 +313,9 @@
|
||||
#define H_CPU_CHAR_L1D_FLUSH_ORI30 (1ull << 61) // IBM bit 2
|
||||
#define H_CPU_CHAR_L1D_FLUSH_TRIG2 (1ull << 60) // IBM bit 3
|
||||
#define H_CPU_CHAR_L1D_THREAD_PRIV (1ull << 59) // IBM bit 4
|
||||
#define H_CPU_CHAR_BRANCH_HINTS_HONORED (1ull << 58) // IBM bit 5
|
||||
#define H_CPU_CHAR_THREAD_RECONFIG_CTRL (1ull << 57) // IBM bit 6
|
||||
#define H_CPU_CHAR_COUNT_CACHE_DISABLED (1ull << 56) // IBM bit 7
|
||||
|
||||
#define H_CPU_BEHAV_FAVOUR_SECURITY (1ull << 63) // IBM bit 0
|
||||
#define H_CPU_BEHAV_L1D_FLUSH_PR (1ull << 62) // IBM bit 1
|
||||
|
||||
@@ -5,5 +5,6 @@ static inline bool arch_irq_work_has_interrupt(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
extern void arch_irq_work_raise(void);
|
||||
|
||||
#endif /* _ASM_POWERPC_IRQ_WORK_H */
|
||||
|
||||
85
arch/powerpc/include/asm/security_features.h
Normal file
85
arch/powerpc/include/asm/security_features.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Security related feature bit definitions.
|
||||
*
|
||||
* Copyright 2018, Michael Ellerman, IBM Corporation.
|
||||
*/
|
||||
|
||||
#ifndef _ASM_POWERPC_SECURITY_FEATURES_H
|
||||
#define _ASM_POWERPC_SECURITY_FEATURES_H
|
||||
|
||||
|
||||
extern unsigned long powerpc_security_features;
|
||||
extern bool rfi_flush;
|
||||
|
||||
/* These are bit flags */
|
||||
enum stf_barrier_type {
|
||||
STF_BARRIER_NONE = 0x1,
|
||||
STF_BARRIER_FALLBACK = 0x2,
|
||||
STF_BARRIER_EIEIO = 0x4,
|
||||
STF_BARRIER_SYNC_ORI = 0x8,
|
||||
};
|
||||
|
||||
void setup_stf_barrier(void);
|
||||
void do_stf_barrier_fixups(enum stf_barrier_type types);
|
||||
|
||||
static inline void security_ftr_set(unsigned long feature)
|
||||
{
|
||||
powerpc_security_features |= feature;
|
||||
}
|
||||
|
||||
static inline void security_ftr_clear(unsigned long feature)
|
||||
{
|
||||
powerpc_security_features &= ~feature;
|
||||
}
|
||||
|
||||
static inline bool security_ftr_enabled(unsigned long feature)
|
||||
{
|
||||
return !!(powerpc_security_features & feature);
|
||||
}
|
||||
|
||||
|
||||
// Features indicating support for Spectre/Meltdown mitigations
|
||||
|
||||
// The L1-D cache can be flushed with ori r30,r30,0
|
||||
#define SEC_FTR_L1D_FLUSH_ORI30 0x0000000000000001ull
|
||||
|
||||
// The L1-D cache can be flushed with mtspr 882,r0 (aka SPRN_TRIG2)
|
||||
#define SEC_FTR_L1D_FLUSH_TRIG2 0x0000000000000002ull
|
||||
|
||||
// ori r31,r31,0 acts as a speculation barrier
|
||||
#define SEC_FTR_SPEC_BAR_ORI31 0x0000000000000004ull
|
||||
|
||||
// Speculation past bctr is disabled
|
||||
#define SEC_FTR_BCCTRL_SERIALISED 0x0000000000000008ull
|
||||
|
||||
// Entries in L1-D are private to a SMT thread
|
||||
#define SEC_FTR_L1D_THREAD_PRIV 0x0000000000000010ull
|
||||
|
||||
// Indirect branch prediction cache disabled
|
||||
#define SEC_FTR_COUNT_CACHE_DISABLED 0x0000000000000020ull
|
||||
|
||||
|
||||
// Features indicating need for Spectre/Meltdown mitigations
|
||||
|
||||
// The L1-D cache should be flushed on MSR[HV] 1->0 transition (hypervisor to guest)
|
||||
#define SEC_FTR_L1D_FLUSH_HV 0x0000000000000040ull
|
||||
|
||||
// The L1-D cache should be flushed on MSR[PR] 0->1 transition (kernel to userspace)
|
||||
#define SEC_FTR_L1D_FLUSH_PR 0x0000000000000080ull
|
||||
|
||||
// A speculation barrier should be used for bounds checks (Spectre variant 1)
|
||||
#define SEC_FTR_BNDS_CHK_SPEC_BAR 0x0000000000000100ull
|
||||
|
||||
// Firmware configuration indicates user favours security over performance
|
||||
#define SEC_FTR_FAVOUR_SECURITY 0x0000000000000200ull
|
||||
|
||||
|
||||
// Features enabled by default
|
||||
#define SEC_FTR_DEFAULT \
|
||||
(SEC_FTR_L1D_FLUSH_HV | \
|
||||
SEC_FTR_L1D_FLUSH_PR | \
|
||||
SEC_FTR_BNDS_CHK_SPEC_BAR | \
|
||||
SEC_FTR_FAVOUR_SECURITY)
|
||||
|
||||
#endif /* _ASM_POWERPC_SECURITY_FEATURES_H */
|
||||
@@ -48,7 +48,7 @@ enum l1d_flush_type {
|
||||
L1D_FLUSH_MTTRIG = 0x8,
|
||||
};
|
||||
|
||||
void __init setup_rfi_flush(enum l1d_flush_type, bool enable);
|
||||
void setup_rfi_flush(enum l1d_flush_type, bool enable);
|
||||
void do_rfi_flush_fixups(enum l1d_flush_type types);
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
@@ -44,7 +44,7 @@ obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \
|
||||
obj-$(CONFIG_VDSO32) += vdso32/
|
||||
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
|
||||
obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_ppc970.o cpu_setup_pa6t.o
|
||||
obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_power.o
|
||||
obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_power.o security.o
|
||||
obj-$(CONFIG_PPC_BOOK3S_64) += mce.o mce_power.o
|
||||
obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o idle_book3e.o
|
||||
obj-$(CONFIG_PPC64) += vdso64/
|
||||
|
||||
@@ -28,6 +28,7 @@ _GLOBAL(__setup_cpu_power7)
|
||||
beqlr
|
||||
li r0,0
|
||||
mtspr SPRN_LPID,r0
|
||||
mtspr SPRN_PCR,r0
|
||||
mfspr r3,SPRN_LPCR
|
||||
bl __init_LPCR
|
||||
bl __init_tlb_power7
|
||||
@@ -41,6 +42,7 @@ _GLOBAL(__restore_cpu_power7)
|
||||
beqlr
|
||||
li r0,0
|
||||
mtspr SPRN_LPID,r0
|
||||
mtspr SPRN_PCR,r0
|
||||
mfspr r3,SPRN_LPCR
|
||||
bl __init_LPCR
|
||||
bl __init_tlb_power7
|
||||
@@ -57,6 +59,7 @@ _GLOBAL(__setup_cpu_power8)
|
||||
beqlr
|
||||
li r0,0
|
||||
mtspr SPRN_LPID,r0
|
||||
mtspr SPRN_PCR,r0
|
||||
mfspr r3,SPRN_LPCR
|
||||
ori r3, r3, LPCR_PECEDH
|
||||
bl __init_LPCR
|
||||
@@ -78,6 +81,7 @@ _GLOBAL(__restore_cpu_power8)
|
||||
beqlr
|
||||
li r0,0
|
||||
mtspr SPRN_LPID,r0
|
||||
mtspr SPRN_PCR,r0
|
||||
mfspr r3,SPRN_LPCR
|
||||
ori r3, r3, LPCR_PECEDH
|
||||
bl __init_LPCR
|
||||
@@ -98,6 +102,7 @@ _GLOBAL(__setup_cpu_power9)
|
||||
li r0,0
|
||||
mtspr SPRN_LPID,r0
|
||||
mtspr SPRN_PID,r0
|
||||
mtspr SPRN_PCR,r0
|
||||
mfspr r3,SPRN_LPCR
|
||||
LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE)
|
||||
or r3, r3, r4
|
||||
@@ -121,6 +126,7 @@ _GLOBAL(__restore_cpu_power9)
|
||||
li r0,0
|
||||
mtspr SPRN_LPID,r0
|
||||
mtspr SPRN_PID,r0
|
||||
mtspr SPRN_PCR,r0
|
||||
mfspr r3,SPRN_LPCR
|
||||
LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE)
|
||||
or r3, r3, r4
|
||||
|
||||
@@ -586,6 +586,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
|
||||
* actually hit this code path.
|
||||
*/
|
||||
|
||||
isync
|
||||
slbie r6
|
||||
slbie r6 /* Workaround POWER5 < DD2.1 issue */
|
||||
slbmte r7,r0
|
||||
|
||||
@@ -846,7 +846,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM)
|
||||
#endif
|
||||
|
||||
|
||||
EXC_REAL_MASKABLE(decrementer, 0x900, 0x980)
|
||||
EXC_REAL_OOL_MASKABLE(decrementer, 0x900, 0x980)
|
||||
EXC_VIRT_MASKABLE(decrementer, 0x4900, 0x4980, 0x900)
|
||||
TRAMP_KVM(PACA_EXGEN, 0x900)
|
||||
EXC_COMMON_ASYNC(decrementer_common, 0x900, timer_interrupt)
|
||||
@@ -884,6 +884,7 @@ BEGIN_FTR_SECTION \
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) \
|
||||
mr r9,r13 ; \
|
||||
GET_PACA(r13) ; \
|
||||
INTERRUPT_TO_KERNEL ; \
|
||||
mfspr r11,SPRN_SRR0 ; \
|
||||
0:
|
||||
|
||||
@@ -1353,6 +1354,19 @@ masked_##_H##interrupt: \
|
||||
##_H##RFI_TO_KERNEL; \
|
||||
b .
|
||||
|
||||
TRAMP_REAL_BEGIN(stf_barrier_fallback)
|
||||
std r9,PACA_EXRFI+EX_R9(r13)
|
||||
std r10,PACA_EXRFI+EX_R10(r13)
|
||||
sync
|
||||
ld r9,PACA_EXRFI+EX_R9(r13)
|
||||
ld r10,PACA_EXRFI+EX_R10(r13)
|
||||
ori 31,31,0
|
||||
.rept 14
|
||||
b 1f
|
||||
1:
|
||||
.endr
|
||||
blr
|
||||
|
||||
/*
|
||||
* Real mode exceptions actually use this too, but alternate
|
||||
* instruction code patches (which end up in the common .text area)
|
||||
|
||||
@@ -1033,6 +1033,9 @@ void fadump_cleanup(void)
|
||||
init_fadump_mem_struct(&fdm,
|
||||
be64_to_cpu(fdm_active->cpu_state_data.destination_address));
|
||||
fadump_invalidate_dump(&fdm);
|
||||
} else if (fw_dump.dump_registered) {
|
||||
/* Un-register Firmware-assisted dump if it was registered. */
|
||||
fadump_unregister_dump(&fdm);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -175,8 +175,8 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
|
||||
if (cpu_has_feature(CPU_FTR_DAWR)) {
|
||||
length_max = 512 ; /* 64 doublewords */
|
||||
/* DAWR region can't cross 512 boundary */
|
||||
if ((bp->attr.bp_addr >> 10) !=
|
||||
((bp->attr.bp_addr + bp->attr.bp_len - 1) >> 10))
|
||||
if ((bp->attr.bp_addr >> 9) !=
|
||||
((bp->attr.bp_addr + bp->attr.bp_len - 1) >> 9))
|
||||
return -EINVAL;
|
||||
}
|
||||
if (info->len >
|
||||
|
||||
@@ -2380,6 +2380,7 @@ static int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
|
||||
/* Create a new breakpoint request if one doesn't exist already */
|
||||
hw_breakpoint_init(&attr);
|
||||
attr.bp_addr = hw_brk.address;
|
||||
attr.bp_len = 8;
|
||||
arch_bp_generic_fields(hw_brk.type,
|
||||
&attr.bp_type);
|
||||
|
||||
|
||||
237
arch/powerpc/kernel/security.c
Normal file
237
arch/powerpc/kernel/security.c
Normal file
@@ -0,0 +1,237 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
//
|
||||
// Security related flags and so on.
|
||||
//
|
||||
// Copyright 2018, Michael Ellerman, IBM Corporation.
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/seq_buf.h>
|
||||
|
||||
#include <asm/security_features.h>
|
||||
|
||||
|
||||
unsigned long powerpc_security_features __read_mostly = SEC_FTR_DEFAULT;
|
||||
|
||||
ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
bool thread_priv;
|
||||
|
||||
thread_priv = security_ftr_enabled(SEC_FTR_L1D_THREAD_PRIV);
|
||||
|
||||
if (rfi_flush || thread_priv) {
|
||||
struct seq_buf s;
|
||||
seq_buf_init(&s, buf, PAGE_SIZE - 1);
|
||||
|
||||
seq_buf_printf(&s, "Mitigation: ");
|
||||
|
||||
if (rfi_flush)
|
||||
seq_buf_printf(&s, "RFI Flush");
|
||||
|
||||
if (rfi_flush && thread_priv)
|
||||
seq_buf_printf(&s, ", ");
|
||||
|
||||
if (thread_priv)
|
||||
seq_buf_printf(&s, "L1D private per thread");
|
||||
|
||||
seq_buf_printf(&s, "\n");
|
||||
|
||||
return s.len;
|
||||
}
|
||||
|
||||
if (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) &&
|
||||
!security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR))
|
||||
return sprintf(buf, "Not affected\n");
|
||||
|
||||
return sprintf(buf, "Vulnerable\n");
|
||||
}
|
||||
|
||||
ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
if (!security_ftr_enabled(SEC_FTR_BNDS_CHK_SPEC_BAR))
|
||||
return sprintf(buf, "Not affected\n");
|
||||
|
||||
return sprintf(buf, "Vulnerable\n");
|
||||
}
|
||||
|
||||
ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
bool bcs, ccd, ori;
|
||||
struct seq_buf s;
|
||||
|
||||
seq_buf_init(&s, buf, PAGE_SIZE - 1);
|
||||
|
||||
bcs = security_ftr_enabled(SEC_FTR_BCCTRL_SERIALISED);
|
||||
ccd = security_ftr_enabled(SEC_FTR_COUNT_CACHE_DISABLED);
|
||||
ori = security_ftr_enabled(SEC_FTR_SPEC_BAR_ORI31);
|
||||
|
||||
if (bcs || ccd) {
|
||||
seq_buf_printf(&s, "Mitigation: ");
|
||||
|
||||
if (bcs)
|
||||
seq_buf_printf(&s, "Indirect branch serialisation (kernel only)");
|
||||
|
||||
if (bcs && ccd)
|
||||
seq_buf_printf(&s, ", ");
|
||||
|
||||
if (ccd)
|
||||
seq_buf_printf(&s, "Indirect branch cache disabled");
|
||||
} else
|
||||
seq_buf_printf(&s, "Vulnerable");
|
||||
|
||||
if (ori)
|
||||
seq_buf_printf(&s, ", ori31 speculation barrier enabled");
|
||||
|
||||
seq_buf_printf(&s, "\n");
|
||||
|
||||
return s.len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Store-forwarding barrier support.
|
||||
*/
|
||||
|
||||
static enum stf_barrier_type stf_enabled_flush_types;
|
||||
static bool no_stf_barrier;
|
||||
bool stf_barrier;
|
||||
|
||||
static int __init handle_no_stf_barrier(char *p)
|
||||
{
|
||||
pr_info("stf-barrier: disabled on command line.");
|
||||
no_stf_barrier = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
early_param("no_stf_barrier", handle_no_stf_barrier);
|
||||
|
||||
/* This is the generic flag used by other architectures */
|
||||
static int __init handle_ssbd(char *p)
|
||||
{
|
||||
if (!p || strncmp(p, "auto", 5) == 0 || strncmp(p, "on", 2) == 0 ) {
|
||||
/* Until firmware tells us, we have the barrier with auto */
|
||||
return 0;
|
||||
} else if (strncmp(p, "off", 3) == 0) {
|
||||
handle_no_stf_barrier(NULL);
|
||||
return 0;
|
||||
} else
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
early_param("spec_store_bypass_disable", handle_ssbd);
|
||||
|
||||
/* This is the generic flag used by other architectures */
|
||||
static int __init handle_no_ssbd(char *p)
|
||||
{
|
||||
handle_no_stf_barrier(NULL);
|
||||
return 0;
|
||||
}
|
||||
early_param("nospec_store_bypass_disable", handle_no_ssbd);
|
||||
|
||||
static void stf_barrier_enable(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
do_stf_barrier_fixups(stf_enabled_flush_types);
|
||||
else
|
||||
do_stf_barrier_fixups(STF_BARRIER_NONE);
|
||||
|
||||
stf_barrier = enable;
|
||||
}
|
||||
|
||||
void setup_stf_barrier(void)
|
||||
{
|
||||
enum stf_barrier_type type;
|
||||
bool enable, hv;
|
||||
|
||||
hv = cpu_has_feature(CPU_FTR_HVMODE);
|
||||
|
||||
/* Default to fallback in case fw-features are not available */
|
||||
if (cpu_has_feature(CPU_FTR_ARCH_300))
|
||||
type = STF_BARRIER_EIEIO;
|
||||
else if (cpu_has_feature(CPU_FTR_ARCH_207S))
|
||||
type = STF_BARRIER_SYNC_ORI;
|
||||
else if (cpu_has_feature(CPU_FTR_ARCH_206))
|
||||
type = STF_BARRIER_FALLBACK;
|
||||
else
|
||||
type = STF_BARRIER_NONE;
|
||||
|
||||
enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) &&
|
||||
(security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR) ||
|
||||
(security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) && hv));
|
||||
|
||||
if (type == STF_BARRIER_FALLBACK) {
|
||||
pr_info("stf-barrier: fallback barrier available\n");
|
||||
} else if (type == STF_BARRIER_SYNC_ORI) {
|
||||
pr_info("stf-barrier: hwsync barrier available\n");
|
||||
} else if (type == STF_BARRIER_EIEIO) {
|
||||
pr_info("stf-barrier: eieio barrier available\n");
|
||||
}
|
||||
|
||||
stf_enabled_flush_types = type;
|
||||
|
||||
if (!no_stf_barrier)
|
||||
stf_barrier_enable(enable);
|
||||
}
|
||||
|
||||
ssize_t cpu_show_spec_store_bypass(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
if (stf_barrier && stf_enabled_flush_types != STF_BARRIER_NONE) {
|
||||
const char *type;
|
||||
switch (stf_enabled_flush_types) {
|
||||
case STF_BARRIER_EIEIO:
|
||||
type = "eieio";
|
||||
break;
|
||||
case STF_BARRIER_SYNC_ORI:
|
||||
type = "hwsync";
|
||||
break;
|
||||
case STF_BARRIER_FALLBACK:
|
||||
type = "fallback";
|
||||
break;
|
||||
default:
|
||||
type = "unknown";
|
||||
}
|
||||
return sprintf(buf, "Mitigation: Kernel entry/exit barrier (%s)\n", type);
|
||||
}
|
||||
|
||||
if (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) &&
|
||||
!security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR))
|
||||
return sprintf(buf, "Not affected\n");
|
||||
|
||||
return sprintf(buf, "Vulnerable\n");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
static int stf_barrier_set(void *data, u64 val)
|
||||
{
|
||||
bool enable;
|
||||
|
||||
if (val == 1)
|
||||
enable = true;
|
||||
else if (val == 0)
|
||||
enable = false;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
/* Only do anything if we're changing state */
|
||||
if (enable != stf_barrier)
|
||||
stf_barrier_enable(enable);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stf_barrier_get(void *data, u64 *val)
|
||||
{
|
||||
*val = stf_barrier ? 1 : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_ATTRIBUTE(fops_stf_barrier, stf_barrier_get, stf_barrier_set, "%llu\n");
|
||||
|
||||
static __init int stf_barrier_debugfs_init(void)
|
||||
{
|
||||
debugfs_create_file("stf_barrier", 0600, powerpc_debugfs_root, NULL, &fops_stf_barrier);
|
||||
return 0;
|
||||
}
|
||||
device_initcall(stf_barrier_debugfs_init);
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
@@ -228,14 +228,6 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
unsigned short maj;
|
||||
unsigned short min;
|
||||
|
||||
/* We only show online cpus: disable preempt (overzealous, I
|
||||
* knew) to prevent cpu going down. */
|
||||
preempt_disable();
|
||||
if (!cpu_online(cpu_id)) {
|
||||
preempt_enable();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
pvr = per_cpu(cpu_pvr, cpu_id);
|
||||
#else
|
||||
@@ -340,9 +332,6 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
#ifdef CONFIG_SMP
|
||||
seq_printf(m, "\n");
|
||||
#endif
|
||||
|
||||
preempt_enable();
|
||||
|
||||
/* If this is the last cpu, print the summary */
|
||||
if (cpumask_next(cpu_id, cpu_online_mask) >= nr_cpu_ids)
|
||||
show_cpuinfo_summary(m);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user