This is the 4.9.84 stable release
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAlqSio0ACgkQONu9yGCS aT7v/w/+OTmWpuavTV+sJz34t8UfnYtl7MnJhubkaCpaTryLXUDeWr5XGzjYRQTh 2OhvqDqoFqrKeKsMSl9x5ZBzA4CUcl5b/Umr8bqMH2iLeVr159qHoqttJ7lMwhX4 JR0avL4rZZlg/6Vbr8PjwNRn/6KF5UOQnTe4Yfpk89nDojeP5+tIZqhq7d6BFRis Bcsb3BZg4UuJZYlJXARoXyPb4kCSEpJ6TPRM5Z1OlqbBLSCecjyqhYzW32Yj3HhT FvV4pJLs/YBkD3GQTrWpNPmLIP/4anu+0geCviCV3SVC7UQJI46yzYLZFSaW1kg0 ol7pNONRGFNxihk4jiKMi5ON3pOMKq3qfY9KDIjGa6R8OIiQLCmC09TFFdzUjCJE E9Q4av+KmUsCvrYtgpRTPjo/v2KGJRz8ZTuXdF9QjEIOdOomU4PMNNrXKx014goZ r7mlxK3qW9HToBp60AAinRvNRJyFr3QH9gXjLU8fZvTVJ45eQkIwIqm5Q40Nk/IL GrpCYkMcFouIYcpnYdurxYcaAeqwA/R4Df5WRHTaOzNXWZ5gsLRkS/muPVOL23cV kCmlZytacE6R4TDkXzrEVfnN+n3QJWybyrx8sQbhBkT7NiEuPcqU/iGZe3uWSPS8 N2CVTW+keaPJijWeAPDqs+JEn6I/ARNq1gzw8tKjKWpEwyBa25g= =FVgu -----END PGP SIGNATURE----- Merge tag 'v4.9.84' into 4.9-1.0.x-imx-stable-merge This is the 4.9.84 stable releasesteinar/wifi_calib_4_9_kernel
commit
20ebb9fb81
|
@ -350,3 +350,19 @@ Contact: Linux ARM Kernel Mailing list <linux-arm-kernel@lists.infradead.org>
|
||||||
Description: AArch64 CPU registers
|
Description: AArch64 CPU registers
|
||||||
'identification' directory exposes the CPU ID registers for
|
'identification' directory exposes the CPU ID registers for
|
||||||
identifying model and revision of the CPU.
|
identifying model and revision of the CPU.
|
||||||
|
|
||||||
|
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
|
||||||
|
Date: January 2018
|
||||||
|
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
|
||||||
|
Description: Information about CPU vulnerabilities
|
||||||
|
|
||||||
|
The files are named after the code names of CPU
|
||||||
|
vulnerabilities. The output of those files reflects the
|
||||||
|
state of the CPUs in the system. Possible output values:
|
||||||
|
|
||||||
|
"Not affected" CPU is not affected by the vulnerability
|
||||||
|
"Vulnerable" CPU is affected and no mitigation in effect
|
||||||
|
"Mitigation: $M" CPU is affected and mitigation $M is in effect
|
||||||
|
|
|
@ -63,6 +63,6 @@ Example:
|
||||||
interrupts = <0 35 0x4>;
|
interrupts = <0 35 0x4>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
dmas = <&dmahost 12 0 1>,
|
dmas = <&dmahost 12 0 1>,
|
||||||
<&dmahost 13 0 1 0>;
|
<&dmahost 13 1 0>;
|
||||||
dma-names = "rx", "rx";
|
dma-names = "rx", "rx";
|
||||||
};
|
};
|
||||||
|
|
|
@ -233,7 +233,7 @@ data_err=ignore(*) Just print an error message if an error occurs
|
||||||
data_err=abort Abort the journal if an error occurs in a file
|
data_err=abort Abort the journal if an error occurs in a file
|
||||||
data buffer in ordered mode.
|
data buffer in ordered mode.
|
||||||
|
|
||||||
grpid Give objects the same group ID as their creator.
|
grpid New objects have the group ID of their parent.
|
||||||
bsdgroups
|
bsdgroups
|
||||||
|
|
||||||
nogrpid (*) New objects have the group ID of their creator.
|
nogrpid (*) New objects have the group ID of their creator.
|
||||||
|
|
|
@ -2691,6 +2691,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||||
nosmt [KNL,S390] Disable symmetric multithreading (SMT).
|
nosmt [KNL,S390] Disable symmetric multithreading (SMT).
|
||||||
Equivalent to smt=1.
|
Equivalent to smt=1.
|
||||||
|
|
||||||
|
nospectre_v2 [X86] Disable all mitigations for the Spectre variant 2
|
||||||
|
(indirect branch prediction) vulnerability. System may
|
||||||
|
allow data leaks with this option, which is equivalent
|
||||||
|
to spectre_v2=off.
|
||||||
|
|
||||||
noxsave [BUGS=X86] Disables x86 extended register state save
|
noxsave [BUGS=X86] Disables x86 extended register state save
|
||||||
and restore using xsave. The kernel will fallback to
|
and restore using xsave. The kernel will fallback to
|
||||||
enabling legacy floating-point and sse state.
|
enabling legacy floating-point and sse state.
|
||||||
|
@ -2763,8 +2768,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||||
|
|
||||||
nojitter [IA-64] Disables jitter checking for ITC timers.
|
nojitter [IA-64] Disables jitter checking for ITC timers.
|
||||||
|
|
||||||
nopti [X86-64] Disable KAISER isolation of kernel from user.
|
|
||||||
|
|
||||||
no-kvmclock [X86,KVM] Disable paravirtualized KVM clock driver
|
no-kvmclock [X86,KVM] Disable paravirtualized KVM clock driver
|
||||||
|
|
||||||
no-kvmapf [X86,KVM] Disable paravirtualized asynchronous page
|
no-kvmapf [X86,KVM] Disable paravirtualized asynchronous page
|
||||||
|
@ -2802,8 +2805,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||||
norandmaps Don't use address space randomization. Equivalent to
|
norandmaps Don't use address space randomization. Equivalent to
|
||||||
echo 0 > /proc/sys/kernel/randomize_va_space
|
echo 0 > /proc/sys/kernel/randomize_va_space
|
||||||
|
|
||||||
noreplace-paravirt [X86,IA-64,PV_OPS] Don't patch paravirt_ops
|
|
||||||
|
|
||||||
noreplace-smp [X86-32,SMP] Don't replace SMP instructions
|
noreplace-smp [X86-32,SMP] Don't replace SMP instructions
|
||||||
with UP alternatives
|
with UP alternatives
|
||||||
|
|
||||||
|
@ -3327,11 +3328,20 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||||
pt. [PARIDE]
|
pt. [PARIDE]
|
||||||
See Documentation/blockdev/paride.txt.
|
See Documentation/blockdev/paride.txt.
|
||||||
|
|
||||||
pti= [X86_64]
|
pti= [X86_64] Control Page Table Isolation of user and
|
||||||
Control KAISER user/kernel address space isolation:
|
kernel address spaces. Disabling this feature
|
||||||
on - enable
|
removes hardening, but improves performance of
|
||||||
off - disable
|
system calls and interrupts.
|
||||||
auto - default setting
|
|
||||||
|
on - unconditionally enable
|
||||||
|
off - unconditionally disable
|
||||||
|
auto - kernel detects whether your CPU model is
|
||||||
|
vulnerable to issues that PTI mitigates
|
||||||
|
|
||||||
|
Not specifying this option is equivalent to pti=auto.
|
||||||
|
|
||||||
|
nopti [X86_64]
|
||||||
|
Equivalent to pti=off
|
||||||
|
|
||||||
pty.legacy_count=
|
pty.legacy_count=
|
||||||
[KNL] Number of legacy pty's. Overwrites compiled-in
|
[KNL] Number of legacy pty's. Overwrites compiled-in
|
||||||
|
@ -3937,6 +3947,29 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||||
sonypi.*= [HW] Sony Programmable I/O Control Device driver
|
sonypi.*= [HW] Sony Programmable I/O Control Device driver
|
||||||
See Documentation/laptops/sonypi.txt
|
See Documentation/laptops/sonypi.txt
|
||||||
|
|
||||||
|
spectre_v2= [X86] Control mitigation of Spectre variant 2
|
||||||
|
(indirect branch speculation) vulnerability.
|
||||||
|
|
||||||
|
on - unconditionally enable
|
||||||
|
off - unconditionally disable
|
||||||
|
auto - kernel detects whether your CPU model is
|
||||||
|
vulnerable
|
||||||
|
|
||||||
|
Selecting 'on' will, and 'auto' may, choose a
|
||||||
|
mitigation method at run time according to the
|
||||||
|
CPU, the available microcode, the setting of the
|
||||||
|
CONFIG_RETPOLINE configuration option, and the
|
||||||
|
compiler with which the kernel was built.
|
||||||
|
|
||||||
|
Specific mitigations can also be selected manually:
|
||||||
|
|
||||||
|
retpoline - replace indirect branches
|
||||||
|
retpoline,generic - google's original retpoline
|
||||||
|
retpoline,amd - AMD-specific minimal thunk
|
||||||
|
|
||||||
|
Not specifying this option is equivalent to
|
||||||
|
spectre_v2=auto.
|
||||||
|
|
||||||
spia_io_base= [HW,MTD]
|
spia_io_base= [HW,MTD]
|
||||||
spia_fio_base=
|
spia_fio_base=
|
||||||
spia_pedr=
|
spia_pedr=
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
This document explains potential effects of speculation, and how undesirable
|
||||||
|
effects can be mitigated portably using common APIs.
|
||||||
|
|
||||||
|
===========
|
||||||
|
Speculation
|
||||||
|
===========
|
||||||
|
|
||||||
|
To improve performance and minimize average latencies, many contemporary CPUs
|
||||||
|
employ speculative execution techniques such as branch prediction, performing
|
||||||
|
work which may be discarded at a later stage.
|
||||||
|
|
||||||
|
Typically speculative execution cannot be observed from architectural state,
|
||||||
|
such as the contents of registers. However, in some cases it is possible to
|
||||||
|
observe its impact on microarchitectural state, such as the presence or
|
||||||
|
absence of data in caches. Such state may form side-channels which can be
|
||||||
|
observed to extract secret information.
|
||||||
|
|
||||||
|
For example, in the presence of branch prediction, it is possible for bounds
|
||||||
|
checks to be ignored by code which is speculatively executed. Consider the
|
||||||
|
following code:
|
||||||
|
|
||||||
|
int load_array(int *array, unsigned int index)
|
||||||
|
{
|
||||||
|
if (index >= MAX_ARRAY_ELEMS)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return array[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
Which, on arm64, may be compiled to an assembly sequence such as:
|
||||||
|
|
||||||
|
CMP <index>, #MAX_ARRAY_ELEMS
|
||||||
|
B.LT less
|
||||||
|
MOV <returnval>, #0
|
||||||
|
RET
|
||||||
|
less:
|
||||||
|
LDR <returnval>, [<array>, <index>]
|
||||||
|
RET
|
||||||
|
|
||||||
|
It is possible that a CPU mis-predicts the conditional branch, and
|
||||||
|
speculatively loads array[index], even if index >= MAX_ARRAY_ELEMS. This
|
||||||
|
value will subsequently be discarded, but the speculated load may affect
|
||||||
|
microarchitectural state which can be subsequently measured.
|
||||||
|
|
||||||
|
More complex sequences involving multiple dependent memory accesses may
|
||||||
|
result in sensitive information being leaked. Consider the following
|
||||||
|
code, building on the prior example:
|
||||||
|
|
||||||
|
int load_dependent_arrays(int *arr1, int *arr2, int index)
|
||||||
|
{
|
||||||
|
int val1, val2,
|
||||||
|
|
||||||
|
val1 = load_array(arr1, index);
|
||||||
|
val2 = load_array(arr2, val1);
|
||||||
|
|
||||||
|
return val2;
|
||||||
|
}
|
||||||
|
|
||||||
|
Under speculation, the first call to load_array() may return the value
|
||||||
|
of an out-of-bounds address, while the second call will influence
|
||||||
|
microarchitectural state dependent on this value. This may provide an
|
||||||
|
arbitrary read primitive.
|
||||||
|
|
||||||
|
====================================
|
||||||
|
Mitigating speculation side-channels
|
||||||
|
====================================
|
||||||
|
|
||||||
|
The kernel provides a generic API to ensure that bounds checks are
|
||||||
|
respected even under speculation. Architectures which are affected by
|
||||||
|
speculation-based side-channels are expected to implement these
|
||||||
|
primitives.
|
||||||
|
|
||||||
|
The array_index_nospec() helper in <linux/nospec.h> can be used to
|
||||||
|
prevent information from being leaked via side-channels.
|
||||||
|
|
||||||
|
A call to array_index_nospec(index, size) returns a sanitized index
|
||||||
|
value that is bounded to [0, size) even under cpu speculation
|
||||||
|
conditions.
|
||||||
|
|
||||||
|
This can be used to protect the earlier load_array() example:
|
||||||
|
|
||||||
|
int load_array(int *array, unsigned int index)
|
||||||
|
{
|
||||||
|
if (index >= MAX_ARRAY_ELEMS)
|
||||||
|
return 0;
|
||||||
|
else {
|
||||||
|
index = array_index_nospec(index, MAX_ARRAY_ELEMS);
|
||||||
|
return array[index];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,186 @@
|
||||||
|
Overview
|
||||||
|
========
|
||||||
|
|
||||||
|
Page Table Isolation (pti, previously known as KAISER[1]) is a
|
||||||
|
countermeasure against attacks on the shared user/kernel address
|
||||||
|
space such as the "Meltdown" approach[2].
|
||||||
|
|
||||||
|
To mitigate this class of attacks, we create an independent set of
|
||||||
|
page tables for use only when running userspace applications. When
|
||||||
|
the kernel is entered via syscalls, interrupts or exceptions, the
|
||||||
|
page tables are switched to the full "kernel" copy. When the system
|
||||||
|
switches back to user mode, the user copy is used again.
|
||||||
|
|
||||||
|
The userspace page tables contain only a minimal amount of kernel
|
||||||
|
data: only what is needed to enter/exit the kernel such as the
|
||||||
|
entry/exit functions themselves and the interrupt descriptor table
|
||||||
|
(IDT). There are a few strictly unnecessary things that get mapped
|
||||||
|
such as the first C function when entering an interrupt (see
|
||||||
|
comments in pti.c).
|
||||||
|
|
||||||
|
This approach helps to ensure that side-channel attacks leveraging
|
||||||
|
the paging structures do not function when PTI is enabled. It can be
|
||||||
|
enabled by setting CONFIG_PAGE_TABLE_ISOLATION=y at compile time.
|
||||||
|
Once enabled at compile-time, it can be disabled at boot with the
|
||||||
|
'nopti' or 'pti=' kernel parameters (see kernel-parameters.txt).
|
||||||
|
|
||||||
|
Page Table Management
|
||||||
|
=====================
|
||||||
|
|
||||||
|
When PTI is enabled, the kernel manages two sets of page tables.
|
||||||
|
The first set is very similar to the single set which is present in
|
||||||
|
kernels without PTI. This includes a complete mapping of userspace
|
||||||
|
that the kernel can use for things like copy_to_user().
|
||||||
|
|
||||||
|
Although _complete_, the user portion of the kernel page tables is
|
||||||
|
crippled by setting the NX bit in the top level. This ensures
|
||||||
|
that any missed kernel->user CR3 switch will immediately crash
|
||||||
|
userspace upon executing its first instruction.
|
||||||
|
|
||||||
|
The userspace page tables map only the kernel data needed to enter
|
||||||
|
and exit the kernel. This data is entirely contained in the 'struct
|
||||||
|
cpu_entry_area' structure which is placed in the fixmap which gives
|
||||||
|
each CPU's copy of the area a compile-time-fixed virtual address.
|
||||||
|
|
||||||
|
For new userspace mappings, the kernel makes the entries in its
|
||||||
|
page tables like normal. The only difference is when the kernel
|
||||||
|
makes entries in the top (PGD) level. In addition to setting the
|
||||||
|
entry in the main kernel PGD, a copy of the entry is made in the
|
||||||
|
userspace page tables' PGD.
|
||||||
|
|
||||||
|
This sharing at the PGD level also inherently shares all the lower
|
||||||
|
layers of the page tables. This leaves a single, shared set of
|
||||||
|
userspace page tables to manage. One PTE to lock, one set of
|
||||||
|
accessed bits, dirty bits, etc...
|
||||||
|
|
||||||
|
Overhead
|
||||||
|
========
|
||||||
|
|
||||||
|
Protection against side-channel attacks is important. But,
|
||||||
|
this protection comes at a cost:
|
||||||
|
|
||||||
|
1. Increased Memory Use
|
||||||
|
a. Each process now needs an order-1 PGD instead of order-0.
|
||||||
|
(Consumes an additional 4k per process).
|
||||||
|
b. The 'cpu_entry_area' structure must be 2MB in size and 2MB
|
||||||
|
aligned so that it can be mapped by setting a single PMD
|
||||||
|
entry. This consumes nearly 2MB of RAM once the kernel
|
||||||
|
is decompressed, but no space in the kernel image itself.
|
||||||
|
|
||||||
|
2. Runtime Cost
|
||||||
|
a. CR3 manipulation to switch between the page table copies
|
||||||
|
must be done at interrupt, syscall, and exception entry
|
||||||
|
and exit (it can be skipped when the kernel is interrupted,
|
||||||
|
though.) Moves to CR3 are on the order of a hundred
|
||||||
|
cycles, and are required at every entry and exit.
|
||||||
|
b. A "trampoline" must be used for SYSCALL entry. This
|
||||||
|
trampoline depends on a smaller set of resources than the
|
||||||
|
non-PTI SYSCALL entry code, so requires mapping fewer
|
||||||
|
things into the userspace page tables. The downside is
|
||||||
|
that stacks must be switched at entry time.
|
||||||
|
c. Global pages are disabled for all kernel structures not
|
||||||
|
mapped into both kernel and userspace page tables. This
|
||||||
|
feature of the MMU allows different processes to share TLB
|
||||||
|
entries mapping the kernel. Losing the feature means more
|
||||||
|
TLB misses after a context switch. The actual loss of
|
||||||
|
performance is very small, however, never exceeding 1%.
|
||||||
|
d. Process Context IDentifiers (PCID) is a CPU feature that
|
||||||
|
allows us to skip flushing the entire TLB when switching page
|
||||||
|
tables by setting a special bit in CR3 when the page tables
|
||||||
|
are changed. This makes switching the page tables (at context
|
||||||
|
switch, or kernel entry/exit) cheaper. But, on systems with
|
||||||
|
PCID support, the context switch code must flush both the user
|
||||||
|
and kernel entries out of the TLB. The user PCID TLB flush is
|
||||||
|
deferred until the exit to userspace, minimizing the cost.
|
||||||
|
See intel.com/sdm for the gory PCID/INVPCID details.
|
||||||
|
e. The userspace page tables must be populated for each new
|
||||||
|
process. Even without PTI, the shared kernel mappings
|
||||||
|
are created by copying top-level (PGD) entries into each
|
||||||
|
new process. But, with PTI, there are now *two* kernel
|
||||||
|
mappings: one in the kernel page tables that maps everything
|
||||||
|
and one for the entry/exit structures. At fork(), we need to
|
||||||
|
copy both.
|
||||||
|
f. In addition to the fork()-time copying, there must also
|
||||||
|
be an update to the userspace PGD any time a set_pgd() is done
|
||||||
|
on a PGD used to map userspace. This ensures that the kernel
|
||||||
|
and userspace copies always map the same userspace
|
||||||
|
memory.
|
||||||
|
g. On systems without PCID support, each CR3 write flushes
|
||||||
|
the entire TLB. That means that each syscall, interrupt
|
||||||
|
or exception flushes the TLB.
|
||||||
|
h. INVPCID is a TLB-flushing instruction which allows flushing
|
||||||
|
of TLB entries for non-current PCIDs. Some systems support
|
||||||
|
PCIDs, but do not support INVPCID. On these systems, addresses
|
||||||
|
can only be flushed from the TLB for the current PCID. When
|
||||||
|
flushing a kernel address, we need to flush all PCIDs, so a
|
||||||
|
single kernel address flush will require a TLB-flushing CR3
|
||||||
|
write upon the next use of every PCID.
|
||||||
|
|
||||||
|
Possible Future Work
|
||||||
|
====================
|
||||||
|
1. We can be more careful about not actually writing to CR3
|
||||||
|
unless its value is actually changed.
|
||||||
|
2. Allow PTI to be enabled/disabled at runtime in addition to the
|
||||||
|
boot-time switching.
|
||||||
|
|
||||||
|
Testing
|
||||||
|
========
|
||||||
|
|
||||||
|
To test stability of PTI, the following test procedure is recommended,
|
||||||
|
ideally doing all of these in parallel:
|
||||||
|
|
||||||
|
1. Set CONFIG_DEBUG_ENTRY=y
|
||||||
|
2. Run several copies of all of the tools/testing/selftests/x86/ tests
|
||||||
|
(excluding MPX and protection_keys) in a loop on multiple CPUs for
|
||||||
|
several minutes. These tests frequently uncover corner cases in the
|
||||||
|
kernel entry code. In general, old kernels might cause these tests
|
||||||
|
themselves to crash, but they should never crash the kernel.
|
||||||
|
3. Run the 'perf' tool in a mode (top or record) that generates many
|
||||||
|
frequent performance monitoring non-maskable interrupts (see "NMI"
|
||||||
|
in /proc/interrupts). This exercises the NMI entry/exit code which
|
||||||
|
is known to trigger bugs in code paths that did not expect to be
|
||||||
|
interrupted, including nested NMIs. Using "-c" boosts the rate of
|
||||||
|
NMIs, and using two -c with separate counters encourages nested NMIs
|
||||||
|
and less deterministic behavior.
|
||||||
|
|
||||||
|
while true; do perf record -c 10000 -e instructions,cycles -a sleep 10; done
|
||||||
|
|
||||||
|
4. Launch a KVM virtual machine.
|
||||||
|
5. Run 32-bit binaries on systems supporting the SYSCALL instruction.
|
||||||
|
This has been a lightly-tested code path and needs extra scrutiny.
|
||||||
|
|
||||||
|
Debugging
|
||||||
|
=========
|
||||||
|
|
||||||
|
Bugs in PTI cause a few different signatures of crashes
|
||||||
|
that are worth noting here.
|
||||||
|
|
||||||
|
* Failures of the selftests/x86 code. Usually a bug in one of the
|
||||||
|
more obscure corners of entry_64.S
|
||||||
|
* Crashes in early boot, especially around CPU bringup. Bugs
|
||||||
|
in the trampoline code or mappings cause these.
|
||||||
|
* Crashes at the first interrupt. Caused by bugs in entry_64.S,
|
||||||
|
like screwing up a page table switch. Also caused by
|
||||||
|
incorrectly mapping the IRQ handler entry code.
|
||||||
|
* Crashes at the first NMI. The NMI code is separate from main
|
||||||
|
interrupt handlers and can have bugs that do not affect
|
||||||
|
normal interrupts. Also caused by incorrectly mapping NMI
|
||||||
|
code. NMIs that interrupt the entry code must be very
|
||||||
|
careful and can be the cause of crashes that show up when
|
||||||
|
running perf.
|
||||||
|
* Kernel crashes at the first exit to userspace. entry_64.S
|
||||||
|
bugs, or failing to map some of the exit code.
|
||||||
|
* Crashes at first interrupt that interrupts userspace. The paths
|
||||||
|
in entry_64.S that return to userspace are sometimes separate
|
||||||
|
from the ones that return to the kernel.
|
||||||
|
* Double faults: overflowing the kernel stack because of page
|
||||||
|
faults upon page faults. Caused by touching non-pti-mapped
|
||||||
|
data in the entry code, or forgetting to switch to kernel
|
||||||
|
CR3 before calling into C functions which are not pti-mapped.
|
||||||
|
* Userspace segfaults early in boot, sometimes manifesting
|
||||||
|
as mount(8) failing to mount the rootfs. These have
|
||||||
|
tended to be TLB invalidation issues. Usually invalidating
|
||||||
|
the wrong PCID, or otherwise missing an invalidation.
|
||||||
|
|
||||||
|
1. https://gruss.cc/files/kaiser.pdf
|
||||||
|
2. https://meltdownattack.com/meltdown.pdf
|
8
Makefile
8
Makefile
|
@ -1,6 +1,6 @@
|
||||||
VERSION = 4
|
VERSION = 4
|
||||||
PATCHLEVEL = 9
|
PATCHLEVEL = 9
|
||||||
SUBLEVEL = 76
|
SUBLEVEL = 84
|
||||||
EXTRAVERSION =
|
EXTRAVERSION =
|
||||||
NAME = Roaring Lionus
|
NAME = Roaring Lionus
|
||||||
|
|
||||||
|
@ -87,10 +87,12 @@ endif
|
||||||
ifneq ($(filter 4.%,$(MAKE_VERSION)),) # make-4
|
ifneq ($(filter 4.%,$(MAKE_VERSION)),) # make-4
|
||||||
ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),)
|
ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),)
|
||||||
quiet=silent_
|
quiet=silent_
|
||||||
|
tools_silent=s
|
||||||
endif
|
endif
|
||||||
else # make-3.8x
|
else # make-3.8x
|
||||||
ifneq ($(filter s% -s%,$(MAKEFLAGS)),)
|
ifneq ($(filter s% -s%,$(MAKEFLAGS)),)
|
||||||
quiet=silent_
|
quiet=silent_
|
||||||
|
tools_silent=-s
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -1614,11 +1616,11 @@ image_name:
|
||||||
# Clear a bunch of variables before executing the submake
|
# Clear a bunch of variables before executing the submake
|
||||||
tools/: FORCE
|
tools/: FORCE
|
||||||
$(Q)mkdir -p $(objtree)/tools
|
$(Q)mkdir -p $(objtree)/tools
|
||||||
$(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/
|
$(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/
|
||||||
|
|
||||||
tools/%: FORCE
|
tools/%: FORCE
|
||||||
$(Q)mkdir -p $(objtree)/tools
|
$(Q)mkdir -p $(objtree)/tools
|
||||||
$(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/ $*
|
$(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/ $*
|
||||||
|
|
||||||
# Single targets
|
# Single targets
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
|
@ -143,7 +143,8 @@ struct pci_iommu_arena
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(CONFIG_ALPHA_SRM) && \
|
#if defined(CONFIG_ALPHA_SRM) && \
|
||||||
(defined(CONFIG_ALPHA_CIA) || defined(CONFIG_ALPHA_LCA))
|
(defined(CONFIG_ALPHA_CIA) || defined(CONFIG_ALPHA_LCA) || \
|
||||||
|
defined(CONFIG_ALPHA_AVANTI))
|
||||||
# define NEED_SRM_SAVE_RESTORE
|
# define NEED_SRM_SAVE_RESTORE
|
||||||
#else
|
#else
|
||||||
# undef NEED_SRM_SAVE_RESTORE
|
# undef NEED_SRM_SAVE_RESTORE
|
||||||
|
|
|
@ -265,12 +265,13 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
|
||||||
application calling fork. */
|
application calling fork. */
|
||||||
if (clone_flags & CLONE_SETTLS)
|
if (clone_flags & CLONE_SETTLS)
|
||||||
childti->pcb.unique = regs->r20;
|
childti->pcb.unique = regs->r20;
|
||||||
|
else
|
||||||
|
regs->r20 = 0; /* OSF/1 has some strange fork() semantics. */
|
||||||
childti->pcb.usp = usp ?: rdusp();
|
childti->pcb.usp = usp ?: rdusp();
|
||||||
*childregs = *regs;
|
*childregs = *regs;
|
||||||
childregs->r0 = 0;
|
childregs->r0 = 0;
|
||||||
childregs->r19 = 0;
|
childregs->r19 = 0;
|
||||||
childregs->r20 = 1; /* OSF/1 has some strange fork() semantics. */
|
childregs->r20 = 1; /* OSF/1 has some strange fork() semantics. */
|
||||||
regs->r20 = 0;
|
|
||||||
stack = ((struct switch_stack *) regs) - 1;
|
stack = ((struct switch_stack *) regs) - 1;
|
||||||
*childstack = *stack;
|
*childstack = *stack;
|
||||||
childstack->r26 = (unsigned long) ret_from_fork;
|
childstack->r26 = (unsigned long) ret_from_fork;
|
||||||
|
|
|
@ -158,11 +158,16 @@ void show_stack(struct task_struct *task, unsigned long *sp)
|
||||||
for(i=0; i < kstack_depth_to_print; i++) {
|
for(i=0; i < kstack_depth_to_print; i++) {
|
||||||
if (((long) stack & (THREAD_SIZE-1)) == 0)
|
if (((long) stack & (THREAD_SIZE-1)) == 0)
|
||||||
break;
|
break;
|
||||||
if (i && ((i % 4) == 0))
|
if ((i % 4) == 0) {
|
||||||
printk("\n ");
|
if (i)
|
||||||
printk("%016lx ", *stack++);
|
pr_cont("\n");
|
||||||
|
printk(" ");
|
||||||
|
} else {
|
||||||
|
pr_cont(" ");
|
||||||
|
}
|
||||||
|
pr_cont("%016lx", *stack++);
|
||||||
}
|
}
|
||||||
printk("\n");
|
pr_cont("\n");
|
||||||
dik_show_trace(sp);
|
dik_show_trace(sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -926,7 +926,8 @@
|
||||||
reg = <0x48038000 0x2000>,
|
reg = <0x48038000 0x2000>,
|
||||||
<0x46000000 0x400000>;
|
<0x46000000 0x400000>;
|
||||||
reg-names = "mpu", "dat";
|
reg-names = "mpu", "dat";
|
||||||
interrupts = <80>, <81>;
|
interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
|
<GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
interrupt-names = "tx", "rx";
|
interrupt-names = "tx", "rx";
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
dmas = <&edma 8 2>,
|
dmas = <&edma 8 2>,
|
||||||
|
@ -940,7 +941,8 @@
|
||||||
reg = <0x4803C000 0x2000>,
|
reg = <0x4803C000 0x2000>,
|
||||||
<0x46400000 0x400000>;
|
<0x46400000 0x400000>;
|
||||||
reg-names = "mpu", "dat";
|
reg-names = "mpu", "dat";
|
||||||
interrupts = <82>, <83>;
|
interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
|
<GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
interrupt-names = "tx", "rx";
|
interrupt-names = "tx", "rx";
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
dmas = <&edma 10 2>,
|
dmas = <&edma 10 2>,
|
||||||
|
|
|
@ -301,8 +301,8 @@
|
||||||
status = "okay";
|
status = "okay";
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
pinctrl-0 = <&spi0_pins>;
|
pinctrl-0 = <&spi0_pins>;
|
||||||
dmas = <&edma 16
|
dmas = <&edma 16 0
|
||||||
&edma 17>;
|
&edma 17 0>;
|
||||||
dma-names = "tx0", "rx0";
|
dma-names = "tx0", "rx0";
|
||||||
|
|
||||||
flash: w25q64cvzpig@0 {
|
flash: w25q64cvzpig@0 {
|
||||||
|
|
|
@ -150,11 +150,6 @@
|
||||||
interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
};
|
};
|
||||||
|
|
||||||
&charlcd {
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
|
|
||||||
};
|
|
||||||
|
|
||||||
&serial0 {
|
&serial0 {
|
||||||
interrupt-parent = <&intc>;
|
interrupt-parent = <&intc>;
|
||||||
interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
timer@20200 {
|
timer@20200 {
|
||||||
compatible = "arm,cortex-a9-global-timer";
|
compatible = "arm,cortex-a9-global-timer";
|
||||||
reg = <0x20200 0x100>;
|
reg = <0x20200 0x100>;
|
||||||
interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <GIC_PPI 11 IRQ_TYPE_EDGE_RISING>;
|
||||||
clocks = <&periph_clk>;
|
clocks = <&periph_clk>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@
|
||||||
compatible = "arm,cortex-a9-twd-timer";
|
compatible = "arm,cortex-a9-twd-timer";
|
||||||
reg = <0x20600 0x20>;
|
reg = <0x20600 0x20>;
|
||||||
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
|
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
|
||||||
IRQ_TYPE_LEVEL_HIGH)>;
|
IRQ_TYPE_EDGE_RISING)>;
|
||||||
clocks = <&periph_clk>;
|
clocks = <&periph_clk>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -274,7 +274,6 @@
|
||||||
&rtc {
|
&rtc {
|
||||||
clocks = <&clock CLK_RTC>;
|
clocks = <&clock CLK_RTC>;
|
||||||
clock-names = "rtc";
|
clock-names = "rtc";
|
||||||
interrupt-parent = <&pmu_system_controller>;
|
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,8 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
pinctrl: pin-controller@10000 {
|
pinctrl: pin-controller@10000 {
|
||||||
pinctrl-0 = <&pmx_dip_switches &pmx_gpio_header>;
|
pinctrl-0 = <&pmx_dip_switches &pmx_gpio_header
|
||||||
|
&pmx_gpio_header_gpo>;
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
|
|
||||||
pmx_uart0: pmx-uart0 {
|
pmx_uart0: pmx-uart0 {
|
||||||
|
@ -85,11 +86,16 @@
|
||||||
* ground.
|
* ground.
|
||||||
*/
|
*/
|
||||||
pmx_gpio_header: pmx-gpio-header {
|
pmx_gpio_header: pmx-gpio-header {
|
||||||
marvell,pins = "mpp17", "mpp7", "mpp29", "mpp28",
|
marvell,pins = "mpp17", "mpp29", "mpp28",
|
||||||
"mpp35", "mpp34", "mpp40";
|
"mpp35", "mpp34", "mpp40";
|
||||||
marvell,function = "gpio";
|
marvell,function = "gpio";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pmx_gpio_header_gpo: pxm-gpio-header-gpo {
|
||||||
|
marvell,pins = "mpp7";
|
||||||
|
marvell,function = "gpo";
|
||||||
|
};
|
||||||
|
|
||||||
pmx_gpio_init: pmx-init {
|
pmx_gpio_init: pmx-init {
|
||||||
marvell,pins = "mpp38";
|
marvell,pins = "mpp38";
|
||||||
marvell,function = "gpio";
|
marvell,function = "gpio";
|
||||||
|
|
|
@ -72,7 +72,8 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
&gpmc {
|
&gpmc {
|
||||||
ranges = <1 0 0x08000000 0x1000000>; /* CS1: 16MB for LAN9221 */
|
ranges = <0 0 0x30000000 0x1000000 /* CS0: 16MB for NAND */
|
||||||
|
1 0 0x2c000000 0x1000000>; /* CS1: 16MB for LAN9221 */
|
||||||
|
|
||||||
ethernet@gpmc {
|
ethernet@gpmc {
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
&gpmc {
|
&gpmc {
|
||||||
ranges = <0 0 0x00000000 0x1000000>; /* CS0: 16MB for NAND */
|
ranges = <0 0 0x30000000 0x1000000>; /* CS0: 16MB for NAND */
|
||||||
|
|
||||||
nand@0,0 {
|
nand@0,0 {
|
||||||
compatible = "ti,omap2-nand";
|
compatible = "ti,omap2-nand";
|
||||||
|
@ -121,7 +121,7 @@
|
||||||
|
|
||||||
&mmc3 {
|
&mmc3 {
|
||||||
interrupts-extended = <&intc 94 &omap3_pmx_core2 0x46>;
|
interrupts-extended = <&intc 94 &omap3_pmx_core2 0x46>;
|
||||||
pinctrl-0 = <&mmc3_pins>;
|
pinctrl-0 = <&mmc3_pins &wl127x_gpio>;
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
vmmc-supply = <&wl12xx_vmmc>;
|
vmmc-supply = <&wl12xx_vmmc>;
|
||||||
non-removable;
|
non-removable;
|
||||||
|
@ -132,8 +132,8 @@
|
||||||
wlcore: wlcore@2 {
|
wlcore: wlcore@2 {
|
||||||
compatible = "ti,wl1273";
|
compatible = "ti,wl1273";
|
||||||
reg = <2>;
|
reg = <2>;
|
||||||
interrupt-parent = <&gpio5>;
|
interrupt-parent = <&gpio1>;
|
||||||
interrupts = <24 IRQ_TYPE_LEVEL_HIGH>; /* gpio 152 */
|
interrupts = <2 IRQ_TYPE_LEVEL_HIGH>; /* gpio 2 */
|
||||||
ref-clock-frequency = <26000000>;
|
ref-clock-frequency = <26000000>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -157,8 +157,6 @@
|
||||||
OMAP3_CORE1_IOPAD(0x2166, PIN_INPUT_PULLUP | MUX_MODE3) /* sdmmc2_dat5.sdmmc3_dat1 */
|
OMAP3_CORE1_IOPAD(0x2166, PIN_INPUT_PULLUP | MUX_MODE3) /* sdmmc2_dat5.sdmmc3_dat1 */
|
||||||
OMAP3_CORE1_IOPAD(0x2168, PIN_INPUT_PULLUP | MUX_MODE3) /* sdmmc2_dat6.sdmmc3_dat2 */
|
OMAP3_CORE1_IOPAD(0x2168, PIN_INPUT_PULLUP | MUX_MODE3) /* sdmmc2_dat6.sdmmc3_dat2 */
|
||||||
OMAP3_CORE1_IOPAD(0x216a, PIN_INPUT_PULLUP | MUX_MODE3) /* sdmmc2_dat6.sdmmc3_dat3 */
|
OMAP3_CORE1_IOPAD(0x216a, PIN_INPUT_PULLUP | MUX_MODE3) /* sdmmc2_dat6.sdmmc3_dat3 */
|
||||||
OMAP3_CORE1_IOPAD(0x2184, PIN_INPUT_PULLUP | MUX_MODE4) /* mcbsp4_clkx.gpio_152 */
|
|
||||||
OMAP3_CORE1_IOPAD(0x2a0c, PIN_OUTPUT | MUX_MODE4) /* sys_boot1.gpio_3 */
|
|
||||||
OMAP3_CORE1_IOPAD(0x21d0, PIN_INPUT_PULLUP | MUX_MODE3) /* mcspi1_cs1.sdmmc3_cmd */
|
OMAP3_CORE1_IOPAD(0x21d0, PIN_INPUT_PULLUP | MUX_MODE3) /* mcspi1_cs1.sdmmc3_cmd */
|
||||||
OMAP3_CORE1_IOPAD(0x21d2, PIN_INPUT_PULLUP | MUX_MODE3) /* mcspi1_cs2.sdmmc_clk */
|
OMAP3_CORE1_IOPAD(0x21d2, PIN_INPUT_PULLUP | MUX_MODE3) /* mcspi1_cs2.sdmmc_clk */
|
||||||
>;
|
>;
|
||||||
|
@ -228,6 +226,12 @@
|
||||||
OMAP3_WKUP_IOPAD(0x2a0e, PIN_OUTPUT | MUX_MODE4) /* sys_boot2.gpio_4 */
|
OMAP3_WKUP_IOPAD(0x2a0e, PIN_OUTPUT | MUX_MODE4) /* sys_boot2.gpio_4 */
|
||||||
>;
|
>;
|
||||||
};
|
};
|
||||||
|
wl127x_gpio: pinmux_wl127x_gpio_pin {
|
||||||
|
pinctrl-single,pins = <
|
||||||
|
OMAP3_WKUP_IOPAD(0x2a0c, PIN_INPUT | MUX_MODE4) /* sys_boot0.gpio_2 */
|
||||||
|
OMAP3_WKUP_IOPAD(0x2a0c, PIN_OUTPUT | MUX_MODE4) /* sys_boot1.gpio_3 */
|
||||||
|
>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
&omap3_pmx_core2 {
|
&omap3_pmx_core2 {
|
||||||
|
|
|
@ -156,8 +156,8 @@
|
||||||
uda1380: uda1380@18 {
|
uda1380: uda1380@18 {
|
||||||
compatible = "nxp,uda1380";
|
compatible = "nxp,uda1380";
|
||||||
reg = <0x18>;
|
reg = <0x18>;
|
||||||
power-gpio = <&gpio 0x59 0>;
|
power-gpio = <&gpio 3 10 0>;
|
||||||
reset-gpio = <&gpio 0x51 0>;
|
reset-gpio = <&gpio 3 2 0>;
|
||||||
dac-clk = "wspll";
|
dac-clk = "wspll";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -81,8 +81,8 @@
|
||||||
uda1380: uda1380@18 {
|
uda1380: uda1380@18 {
|
||||||
compatible = "nxp,uda1380";
|
compatible = "nxp,uda1380";
|
||||||
reg = <0x18>;
|
reg = <0x18>;
|
||||||
power-gpio = <&gpio 0x59 0>;
|
power-gpio = <&gpio 3 10 0>;
|
||||||
reset-gpio = <&gpio 0x51 0>;
|
reset-gpio = <&gpio 3 2 0>;
|
||||||
dac-clk = "wspll";
|
dac-clk = "wspll";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -197,12 +197,14 @@
|
||||||
compatible = "mediatek,mt2701-hifsys", "syscon";
|
compatible = "mediatek,mt2701-hifsys", "syscon";
|
||||||
reg = <0 0x1a000000 0 0x1000>;
|
reg = <0 0x1a000000 0 0x1000>;
|
||||||
#clock-cells = <1>;
|
#clock-cells = <1>;
|
||||||
|
#reset-cells = <1>;
|
||||||
};
|
};
|
||||||
|
|
||||||
ethsys: syscon@1b000000 {
|
ethsys: syscon@1b000000 {
|
||||||
compatible = "mediatek,mt2701-ethsys", "syscon";
|
compatible = "mediatek,mt2701-ethsys", "syscon";
|
||||||
reg = <0 0x1b000000 0 0x1000>;
|
reg = <0 0x1b000000 0 0x1000>;
|
||||||
#clock-cells = <1>;
|
#clock-cells = <1>;
|
||||||
|
#reset-cells = <1>;
|
||||||
};
|
};
|
||||||
|
|
||||||
bdpsys: syscon@1c000000 {
|
bdpsys: syscon@1c000000 {
|
||||||
|
|
|
@ -352,7 +352,7 @@
|
||||||
elm: elm@48078000 {
|
elm: elm@48078000 {
|
||||||
compatible = "ti,am3352-elm";
|
compatible = "ti,am3352-elm";
|
||||||
reg = <0x48078000 0x2000>;
|
reg = <0x48078000 0x2000>;
|
||||||
interrupts = <4>;
|
interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
ti,hwmods = "elm";
|
ti,hwmods = "elm";
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
@ -859,14 +859,12 @@
|
||||||
usbhsohci: ohci@4a064800 {
|
usbhsohci: ohci@4a064800 {
|
||||||
compatible = "ti,ohci-omap3";
|
compatible = "ti,ohci-omap3";
|
||||||
reg = <0x4a064800 0x400>;
|
reg = <0x4a064800 0x400>;
|
||||||
interrupt-parent = <&gic>;
|
|
||||||
interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
};
|
};
|
||||||
|
|
||||||
usbhsehci: ehci@4a064c00 {
|
usbhsehci: ehci@4a064c00 {
|
||||||
compatible = "ti,ehci-omap";
|
compatible = "ti,ehci-omap";
|
||||||
reg = <0x4a064c00 0x400>;
|
reg = <0x4a064c00 0x400>;
|
||||||
interrupt-parent = <&gic>;
|
|
||||||
interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -463,6 +463,7 @@
|
||||||
compatible = "samsung,exynos4210-ohci";
|
compatible = "samsung,exynos4210-ohci";
|
||||||
reg = <0xec300000 0x100>;
|
reg = <0xec300000 0x100>;
|
||||||
interrupts = <23>;
|
interrupts = <23>;
|
||||||
|
interrupt-parent = <&vic1>;
|
||||||
clocks = <&clocks CLK_USB_HOST>;
|
clocks = <&clocks CLK_USB_HOST>;
|
||||||
clock-names = "usbhost";
|
clock-names = "usbhost";
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
|
|
|
@ -349,7 +349,7 @@
|
||||||
spi0: spi@e0100000 {
|
spi0: spi@e0100000 {
|
||||||
status = "okay";
|
status = "okay";
|
||||||
num-cs = <3>;
|
num-cs = <3>;
|
||||||
cs-gpios = <&gpio1 7 0>, <&spics 0>, <&spics 1>;
|
cs-gpios = <&gpio1 7 0>, <&spics 0 0>, <&spics 1 0>;
|
||||||
|
|
||||||
stmpe610@0 {
|
stmpe610@0 {
|
||||||
compatible = "st,stmpe610";
|
compatible = "st,stmpe610";
|
||||||
|
|
|
@ -141,8 +141,8 @@
|
||||||
reg = <0xb4100000 0x1000>;
|
reg = <0xb4100000 0x1000>;
|
||||||
interrupts = <0 105 0x4>;
|
interrupts = <0 105 0x4>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
dmas = <&dwdma0 0x600 0 0 1>, /* 0xC << 11 */
|
dmas = <&dwdma0 12 0 1>,
|
||||||
<&dwdma0 0x680 0 1 0>; /* 0xD << 7 */
|
<&dwdma0 13 1 0>;
|
||||||
dma-names = "tx", "rx";
|
dma-names = "tx", "rx";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,7 @@
|
||||||
reg = <0xb2800000 0x1000>;
|
reg = <0xb2800000 0x1000>;
|
||||||
interrupts = <0 29 0x4>;
|
interrupts = <0 29 0x4>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
dmas = <&dwdma0 0 0 0 0>;
|
dmas = <&dwdma0 0 0 0>;
|
||||||
dma-names = "data";
|
dma-names = "data";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -288,8 +288,8 @@
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
interrupts = <0 31 0x4>;
|
interrupts = <0 31 0x4>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
dmas = <&dwdma0 0x2000 0 0 0>, /* 0x4 << 11 */
|
dmas = <&dwdma0 4 0 0>,
|
||||||
<&dwdma0 0x0280 0 0 0>; /* 0x5 << 7 */
|
<&dwdma0 5 0 0>;
|
||||||
dma-names = "tx", "rx";
|
dma-names = "tx", "rx";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -194,6 +194,7 @@
|
||||||
rtc@fc900000 {
|
rtc@fc900000 {
|
||||||
compatible = "st,spear600-rtc";
|
compatible = "st,spear600-rtc";
|
||||||
reg = <0xfc900000 0x1000>;
|
reg = <0xfc900000 0x1000>;
|
||||||
|
interrupt-parent = <&vic0>;
|
||||||
interrupts = <10>;
|
interrupts = <10>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
|
@ -749,6 +749,7 @@
|
||||||
reg = <0x10120000 0x1000>;
|
reg = <0x10120000 0x1000>;
|
||||||
interrupt-names = "combined";
|
interrupt-names = "combined";
|
||||||
interrupts = <14>;
|
interrupts = <14>;
|
||||||
|
interrupt-parent = <&vica>;
|
||||||
clocks = <&clcdclk>, <&hclkclcd>;
|
clocks = <&clcdclk>, <&hclkclcd>;
|
||||||
clock-names = "clcdclk", "apb_pclk";
|
clock-names = "clcdclk", "apb_pclk";
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
*/
|
*/
|
||||||
#include "stih407-clock.dtsi"
|
#include "stih407-clock.dtsi"
|
||||||
#include "stih407-family.dtsi"
|
#include "stih407-family.dtsi"
|
||||||
|
#include <dt-bindings/gpio/gpio.h>
|
||||||
/ {
|
/ {
|
||||||
soc {
|
soc {
|
||||||
sti-display-subsystem {
|
sti-display-subsystem {
|
||||||
|
@ -122,7 +123,7 @@
|
||||||
<&clk_s_d2_quadfs 0>,
|
<&clk_s_d2_quadfs 0>,
|
||||||
<&clk_s_d2_quadfs 1>;
|
<&clk_s_d2_quadfs 1>;
|
||||||
|
|
||||||
hdmi,hpd-gpio = <&pio5 3>;
|
hdmi,hpd-gpio = <&pio5 3 GPIO_ACTIVE_LOW>;
|
||||||
reset-names = "hdmi";
|
reset-names = "hdmi";
|
||||||
resets = <&softreset STIH407_HDMI_TX_PHY_SOFTRESET>;
|
resets = <&softreset STIH407_HDMI_TX_PHY_SOFTRESET>;
|
||||||
ddc = <&hdmiddc>;
|
ddc = <&hdmiddc>;
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "stih410-clock.dtsi"
|
#include "stih410-clock.dtsi"
|
||||||
#include "stih407-family.dtsi"
|
#include "stih407-family.dtsi"
|
||||||
#include "stih410-pinctrl.dtsi"
|
#include "stih410-pinctrl.dtsi"
|
||||||
|
#include <dt-bindings/gpio/gpio.h>
|
||||||
/ {
|
/ {
|
||||||
aliases {
|
aliases {
|
||||||
bdisp0 = &bdisp0;
|
bdisp0 = &bdisp0;
|
||||||
|
@ -213,7 +214,7 @@
|
||||||
<&clk_s_d2_quadfs 0>,
|
<&clk_s_d2_quadfs 0>,
|
||||||
<&clk_s_d2_quadfs 1>;
|
<&clk_s_d2_quadfs 1>;
|
||||||
|
|
||||||
hdmi,hpd-gpio = <&pio5 3>;
|
hdmi,hpd-gpio = <&pio5 3 GPIO_ACTIVE_LOW>;
|
||||||
reset-names = "hdmi";
|
reset-names = "hdmi";
|
||||||
resets = <&softreset STIH407_HDMI_TX_PHY_SOFTRESET>;
|
resets = <&softreset STIH407_HDMI_TX_PHY_SOFTRESET>;
|
||||||
ddc = <&hdmiddc>;
|
ddc = <&hdmiddc>;
|
||||||
|
|
|
@ -57,3 +57,7 @@ static struct miscdevice bL_switcher_device = {
|
||||||
&bL_switcher_fops
|
&bL_switcher_fops
|
||||||
};
|
};
|
||||||
module_misc_device(bL_switcher_device);
|
module_misc_device(bL_switcher_device);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Nicolas Pitre <nico@linaro.org>");
|
||||||
|
MODULE_LICENSE("GPL v2");
|
||||||
|
MODULE_DESCRIPTION("big.LITTLE switcher dummy user interface");
|
||||||
|
|
|
@ -11,6 +11,7 @@ CONFIG_SMP=y
|
||||||
CONFIG_NR_CPUS=8
|
CONFIG_NR_CPUS=8
|
||||||
CONFIG_AEABI=y
|
CONFIG_AEABI=y
|
||||||
CONFIG_HIGHMEM=y
|
CONFIG_HIGHMEM=y
|
||||||
|
CONFIG_CMA=y
|
||||||
CONFIG_ARM_APPENDED_DTB=y
|
CONFIG_ARM_APPENDED_DTB=y
|
||||||
CONFIG_ARM_ATAG_DTB_COMPAT=y
|
CONFIG_ARM_ATAG_DTB_COMPAT=y
|
||||||
CONFIG_CPU_FREQ=y
|
CONFIG_CPU_FREQ=y
|
||||||
|
@ -35,6 +36,7 @@ CONFIG_CAN_SUN4I=y
|
||||||
# CONFIG_WIRELESS is not set
|
# CONFIG_WIRELESS is not set
|
||||||
CONFIG_DEVTMPFS=y
|
CONFIG_DEVTMPFS=y
|
||||||
CONFIG_DEVTMPFS_MOUNT=y
|
CONFIG_DEVTMPFS_MOUNT=y
|
||||||
|
CONFIG_DMA_CMA=y
|
||||||
CONFIG_BLK_DEV_SD=y
|
CONFIG_BLK_DEV_SD=y
|
||||||
CONFIG_ATA=y
|
CONFIG_ATA=y
|
||||||
CONFIG_AHCI_SUNXI=y
|
CONFIG_AHCI_SUNXI=y
|
||||||
|
|
|
@ -1165,6 +1165,7 @@ static int hyp_init_cpu_pm_notifier(struct notifier_block *self,
|
||||||
cpu_hyp_reset();
|
cpu_hyp_reset();
|
||||||
|
|
||||||
return NOTIFY_OK;
|
return NOTIFY_OK;
|
||||||
|
case CPU_PM_ENTER_FAILED:
|
||||||
case CPU_PM_EXIT:
|
case CPU_PM_EXIT:
|
||||||
if (__this_cpu_read(kvm_arm_hardware_enabled))
|
if (__this_cpu_read(kvm_arm_hardware_enabled))
|
||||||
/* The hardware was enabled before suspend. */
|
/* The hardware was enabled before suspend. */
|
||||||
|
|
|
@ -38,7 +38,7 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
||||||
|
|
||||||
ret = kvm_psci_call(vcpu);
|
ret = kvm_psci_call(vcpu);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
kvm_inject_undefined(vcpu);
|
vcpu_set_reg(vcpu, 0, ~0UL);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,16 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
||||||
|
|
||||||
static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
||||||
{
|
{
|
||||||
kvm_inject_undefined(vcpu);
|
/*
|
||||||
|
* "If an SMC instruction executed at Non-secure EL1 is
|
||||||
|
* trapped to EL2 because HCR_EL2.TSC is 1, the exception is a
|
||||||
|
* Trap exception, not a Secure Monitor Call exception [...]"
|
||||||
|
*
|
||||||
|
* We need to advance the PC after the trap, as it would
|
||||||
|
* otherwise return to the same address...
|
||||||
|
*/
|
||||||
|
vcpu_set_reg(vcpu, 0, ~0UL);
|
||||||
|
kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_kvm_mmio(KVM_TRACE_MMIO_READ, len, run->mmio.phys_addr,
|
trace_kvm_mmio(KVM_TRACE_MMIO_READ, len, run->mmio.phys_addr,
|
||||||
data);
|
&data);
|
||||||
data = vcpu_data_host_to_guest(vcpu, data, len);
|
data = vcpu_data_host_to_guest(vcpu, data, len);
|
||||||
vcpu_set_reg(vcpu, vcpu->arch.mmio_decode.rt, data);
|
vcpu_set_reg(vcpu, vcpu->arch.mmio_decode.rt, data);
|
||||||
}
|
}
|
||||||
|
@ -182,14 +182,14 @@ int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run,
|
||||||
data = vcpu_data_guest_to_host(vcpu, vcpu_get_reg(vcpu, rt),
|
data = vcpu_data_guest_to_host(vcpu, vcpu_get_reg(vcpu, rt),
|
||||||
len);
|
len);
|
||||||
|
|
||||||
trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, len, fault_ipa, data);
|
trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, len, fault_ipa, &data);
|
||||||
kvm_mmio_write_buf(data_buf, len, data);
|
kvm_mmio_write_buf(data_buf, len, data);
|
||||||
|
|
||||||
ret = kvm_io_bus_write(vcpu, KVM_MMIO_BUS, fault_ipa, len,
|
ret = kvm_io_bus_write(vcpu, KVM_MMIO_BUS, fault_ipa, len,
|
||||||
data_buf);
|
data_buf);
|
||||||
} else {
|
} else {
|
||||||
trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, len,
|
trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, len,
|
||||||
fault_ipa, 0);
|
fault_ipa, NULL);
|
||||||
|
|
||||||
ret = kvm_io_bus_read(vcpu, KVM_MMIO_BUS, fault_ipa, len,
|
ret = kvm_io_bus_read(vcpu, KVM_MMIO_BUS, fault_ipa, len,
|
||||||
data_buf);
|
data_buf);
|
||||||
|
|
|
@ -1284,7 +1284,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_vm_hugetlb_page(vma) && !logging_active) {
|
if (vma_kernel_pagesize(vma) && !logging_active) {
|
||||||
hugetlb = true;
|
hugetlb = true;
|
||||||
gfn = (fault_ipa & PMD_MASK) >> PAGE_SHIFT;
|
gfn = (fault_ipa & PMD_MASK) >> PAGE_SHIFT;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -73,6 +73,25 @@ phys_addr_t omap_secure_ram_mempool_base(void)
|
||||||
return omap_secure_memblock_base;
|
return omap_secure_memblock_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 omap3_save_secure_ram(void __iomem *addr, int size)
|
||||||
|
{
|
||||||
|
u32 ret;
|
||||||
|
u32 param[5];
|
||||||
|
|
||||||
|
if (size != OMAP3_SAVE_SECURE_RAM_SZ)
|
||||||
|
return OMAP3_SAVE_SECURE_RAM_SZ;
|
||||||
|
|
||||||
|
param[0] = 4; /* Number of arguments */
|
||||||
|
param[1] = __pa(addr); /* Physical address for saving */
|
||||||
|
param[2] = 0;
|
||||||
|
param[3] = 1;
|
||||||
|
param[4] = 1;
|
||||||
|
|
||||||
|
ret = save_secure_ram_context(__pa(param));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rx51_secure_dispatcher: Routine to dispatch secure PPA API calls
|
* rx51_secure_dispatcher: Routine to dispatch secure PPA API calls
|
||||||
* @idx: The PPA API index
|
* @idx: The PPA API index
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
/* Maximum Secure memory storage size */
|
/* Maximum Secure memory storage size */
|
||||||
#define OMAP_SECURE_RAM_STORAGE (88 * SZ_1K)
|
#define OMAP_SECURE_RAM_STORAGE (88 * SZ_1K)
|
||||||
|
|
||||||
|
#define OMAP3_SAVE_SECURE_RAM_SZ 0x803F
|
||||||
|
|
||||||
/* Secure low power HAL API index */
|
/* Secure low power HAL API index */
|
||||||
#define OMAP4_HAL_SAVESECURERAM_INDEX 0x1a
|
#define OMAP4_HAL_SAVESECURERAM_INDEX 0x1a
|
||||||
#define OMAP4_HAL_SAVEHW_INDEX 0x1b
|
#define OMAP4_HAL_SAVEHW_INDEX 0x1b
|
||||||
|
@ -65,6 +67,8 @@ extern u32 omap_smc2(u32 id, u32 falg, u32 pargs);
|
||||||
extern u32 omap_smc3(u32 id, u32 process, u32 flag, u32 pargs);
|
extern u32 omap_smc3(u32 id, u32 process, u32 flag, u32 pargs);
|
||||||
extern phys_addr_t omap_secure_ram_mempool_base(void);
|
extern phys_addr_t omap_secure_ram_mempool_base(void);
|
||||||
extern int omap_secure_ram_reserve_memblock(void);
|
extern int omap_secure_ram_reserve_memblock(void);
|
||||||
|
extern u32 save_secure_ram_context(u32 args_pa);
|
||||||
|
extern u32 omap3_save_secure_ram(void __iomem *save_regs, int size);
|
||||||
|
|
||||||
extern u32 rx51_secure_dispatcher(u32 idx, u32 process, u32 flag, u32 nargs,
|
extern u32 rx51_secure_dispatcher(u32 idx, u32 process, u32 flag, u32 nargs,
|
||||||
u32 arg1, u32 arg2, u32 arg3, u32 arg4);
|
u32 arg1, u32 arg2, u32 arg3, u32 arg4);
|
||||||
|
|
|
@ -81,10 +81,6 @@ extern unsigned int omap3_do_wfi_sz;
|
||||||
/* ... and its pointer from SRAM after copy */
|
/* ... and its pointer from SRAM after copy */
|
||||||
extern void (*omap3_do_wfi_sram)(void);
|
extern void (*omap3_do_wfi_sram)(void);
|
||||||
|
|
||||||
/* save_secure_ram_context function pointer and size, for copy to SRAM */
|
|
||||||
extern int save_secure_ram_context(u32 *addr);
|
|
||||||
extern unsigned int save_secure_ram_context_sz;
|
|
||||||
|
|
||||||
extern void omap3_save_scratchpad_contents(void);
|
extern void omap3_save_scratchpad_contents(void);
|
||||||
|
|
||||||
#define PM_RTA_ERRATUM_i608 (1 << 0)
|
#define PM_RTA_ERRATUM_i608 (1 << 0)
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include "prm3xxx.h"
|
#include "prm3xxx.h"
|
||||||
#include "pm.h"
|
#include "pm.h"
|
||||||
#include "sdrc.h"
|
#include "sdrc.h"
|
||||||
|
#include "omap-secure.h"
|
||||||
#include "sram.h"
|
#include "sram.h"
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "vc.h"
|
#include "vc.h"
|
||||||
|
@ -66,7 +67,6 @@ struct power_state {
|
||||||
|
|
||||||
static LIST_HEAD(pwrst_list);
|
static LIST_HEAD(pwrst_list);
|
||||||
|
|
||||||
static int (*_omap_save_secure_sram)(u32 *addr);
|
|
||||||
void (*omap3_do_wfi_sram)(void);
|
void (*omap3_do_wfi_sram)(void);
|
||||||
|
|
||||||
static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
|
static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
|
||||||
|
@ -121,8 +121,8 @@ static void omap3_save_secure_ram_context(void)
|
||||||
* will hang the system.
|
* will hang the system.
|
||||||
*/
|
*/
|
||||||
pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
|
pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
|
||||||
ret = _omap_save_secure_sram((u32 *)(unsigned long)
|
ret = omap3_save_secure_ram(omap3_secure_ram_storage,
|
||||||
__pa(omap3_secure_ram_storage));
|
OMAP3_SAVE_SECURE_RAM_SZ);
|
||||||
pwrdm_set_next_pwrst(mpu_pwrdm, mpu_next_state);
|
pwrdm_set_next_pwrst(mpu_pwrdm, mpu_next_state);
|
||||||
/* Following is for error tracking, it should not happen */
|
/* Following is for error tracking, it should not happen */
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -434,15 +434,10 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
|
||||||
*
|
*
|
||||||
* The minimum set of functions is pushed to SRAM for execution:
|
* The minimum set of functions is pushed to SRAM for execution:
|
||||||
* - omap3_do_wfi for erratum i581 WA,
|
* - omap3_do_wfi for erratum i581 WA,
|
||||||
* - save_secure_ram_context for security extensions.
|
|
||||||
*/
|
*/
|
||||||
void omap_push_sram_idle(void)
|
void omap_push_sram_idle(void)
|
||||||
{
|
{
|
||||||
omap3_do_wfi_sram = omap_sram_push(omap3_do_wfi, omap3_do_wfi_sz);
|
omap3_do_wfi_sram = omap_sram_push(omap3_do_wfi, omap3_do_wfi_sz);
|
||||||
|
|
||||||
if (omap_type() != OMAP2_DEVICE_TYPE_GP)
|
|
||||||
_omap_save_secure_sram = omap_sram_push(save_secure_ram_context,
|
|
||||||
save_secure_ram_context_sz);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init pm_errata_configure(void)
|
static void __init pm_errata_configure(void)
|
||||||
|
@ -554,7 +549,7 @@ int __init omap3_pm_init(void)
|
||||||
clkdm_add_wkdep(neon_clkdm, mpu_clkdm);
|
clkdm_add_wkdep(neon_clkdm, mpu_clkdm);
|
||||||
if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
|
if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
|
||||||
omap3_secure_ram_storage =
|
omap3_secure_ram_storage =
|
||||||
kmalloc(0x803F, GFP_KERNEL);
|
kmalloc(OMAP3_SAVE_SECURE_RAM_SZ, GFP_KERNEL);
|
||||||
if (!omap3_secure_ram_storage)
|
if (!omap3_secure_ram_storage)
|
||||||
pr_err("Memory allocation failed when allocating for secure sram context\n");
|
pr_err("Memory allocation failed when allocating for secure sram context\n");
|
||||||
|
|
||||||
|
|
|
@ -176,17 +176,6 @@ static int am33xx_pwrdm_read_pwrst(struct powerdomain *pwrdm)
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int am33xx_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
|
|
||||||
{
|
|
||||||
u32 v;
|
|
||||||
|
|
||||||
v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
|
|
||||||
v &= AM33XX_LASTPOWERSTATEENTERED_MASK;
|
|
||||||
v >>= AM33XX_LASTPOWERSTATEENTERED_SHIFT;
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int am33xx_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
|
static int am33xx_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
|
||||||
{
|
{
|
||||||
am33xx_prm_rmw_reg_bits(AM33XX_LOWPOWERSTATECHANGE_MASK,
|
am33xx_prm_rmw_reg_bits(AM33XX_LOWPOWERSTATECHANGE_MASK,
|
||||||
|
@ -357,7 +346,6 @@ struct pwrdm_ops am33xx_pwrdm_operations = {
|
||||||
.pwrdm_set_next_pwrst = am33xx_pwrdm_set_next_pwrst,
|
.pwrdm_set_next_pwrst = am33xx_pwrdm_set_next_pwrst,
|
||||||
.pwrdm_read_next_pwrst = am33xx_pwrdm_read_next_pwrst,
|
.pwrdm_read_next_pwrst = am33xx_pwrdm_read_next_pwrst,
|
||||||
.pwrdm_read_pwrst = am33xx_pwrdm_read_pwrst,
|
.pwrdm_read_pwrst = am33xx_pwrdm_read_pwrst,
|
||||||
.pwrdm_read_prev_pwrst = am33xx_pwrdm_read_prev_pwrst,
|
|
||||||
.pwrdm_set_logic_retst = am33xx_pwrdm_set_logic_retst,
|
.pwrdm_set_logic_retst = am33xx_pwrdm_set_logic_retst,
|
||||||
.pwrdm_read_logic_pwrst = am33xx_pwrdm_read_logic_pwrst,
|
.pwrdm_read_logic_pwrst = am33xx_pwrdm_read_logic_pwrst,
|
||||||
.pwrdm_read_logic_retst = am33xx_pwrdm_read_logic_retst,
|
.pwrdm_read_logic_retst = am33xx_pwrdm_read_logic_retst,
|
||||||
|
|
|
@ -93,20 +93,13 @@ ENTRY(enable_omap3630_toggle_l2_on_restore)
|
||||||
ENDPROC(enable_omap3630_toggle_l2_on_restore)
|
ENDPROC(enable_omap3630_toggle_l2_on_restore)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function to call rom code to save secure ram context. This gets
|
* Function to call rom code to save secure ram context.
|
||||||
* relocated to SRAM, so it can be all in .data section. Otherwise
|
*
|
||||||
* we need to initialize api_params separately.
|
* r0 = physical address of the parameters
|
||||||
*/
|
*/
|
||||||
.data
|
|
||||||
.align 3
|
|
||||||
ENTRY(save_secure_ram_context)
|
ENTRY(save_secure_ram_context)
|
||||||
stmfd sp!, {r4 - r11, lr} @ save registers on stack
|
stmfd sp!, {r4 - r11, lr} @ save registers on stack
|
||||||
adr r3, api_params @ r3 points to parameters
|
mov r3, r0 @ physical address of parameters
|
||||||
str r0, [r3,#0x4] @ r0 has sdram address
|
|
||||||
ldr r12, high_mask
|
|
||||||
and r3, r3, r12
|
|
||||||
ldr r12, sram_phy_addr_mask
|
|
||||||
orr r3, r3, r12
|
|
||||||
mov r0, #25 @ set service ID for PPA
|
mov r0, #25 @ set service ID for PPA
|
||||||
mov r12, r0 @ copy secure service ID in r12
|
mov r12, r0 @ copy secure service ID in r12
|
||||||
mov r1, #0 @ set task id for ROM code in r1
|
mov r1, #0 @ set task id for ROM code in r1
|
||||||
|
@ -120,18 +113,7 @@ ENTRY(save_secure_ram_context)
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
ldmfd sp!, {r4 - r11, pc}
|
ldmfd sp!, {r4 - r11, pc}
|
||||||
.align
|
|
||||||
sram_phy_addr_mask:
|
|
||||||
.word SRAM_BASE_P
|
|
||||||
high_mask:
|
|
||||||
.word 0xffff
|
|
||||||
api_params:
|
|
||||||
.word 0x4, 0x0, 0x0, 0x1, 0x1
|
|
||||||
ENDPROC(save_secure_ram_context)
|
ENDPROC(save_secure_ram_context)
|
||||||
ENTRY(save_secure_ram_context_sz)
|
|
||||||
.word . - save_secure_ram_context
|
|
||||||
|
|
||||||
.text
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ======================
|
* ======================
|
||||||
|
|
|
@ -132,3 +132,7 @@ static struct platform_driver tosa_bt_driver = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
module_platform_driver(tosa_bt_driver);
|
module_platform_driver(tosa_bt_driver);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_AUTHOR("Dmitry Baryshkov");
|
||||||
|
MODULE_DESCRIPTION("Bluetooth built-in chip control");
|
||||||
|
|
|
@ -1007,7 +1007,7 @@ source "fs/Kconfig.binfmt"
|
||||||
config COMPAT
|
config COMPAT
|
||||||
bool "Kernel support for 32-bit EL0"
|
bool "Kernel support for 32-bit EL0"
|
||||||
depends on ARM64_4K_PAGES || EXPERT
|
depends on ARM64_4K_PAGES || EXPERT
|
||||||
select COMPAT_BINFMT_ELF
|
select COMPAT_BINFMT_ELF if BINFMT_ELF
|
||||||
select HAVE_UID16
|
select HAVE_UID16
|
||||||
select OLD_SIGSUSPEND3
|
select OLD_SIGSUSPEND3
|
||||||
select COMPAT_OLD_SIGACTION
|
select COMPAT_OLD_SIGACTION
|
||||||
|
|
|
@ -2,9 +2,11 @@ menu "Platform selection"
|
||||||
|
|
||||||
config ARCH_SUNXI
|
config ARCH_SUNXI
|
||||||
bool "Allwinner sunxi 64-bit SoC Family"
|
bool "Allwinner sunxi 64-bit SoC Family"
|
||||||
|
select ARCH_HAS_RESET_CONTROLLER
|
||||||
select GENERIC_IRQ_CHIP
|
select GENERIC_IRQ_CHIP
|
||||||
select PINCTRL
|
select PINCTRL
|
||||||
select PINCTRL_SUN50I_A64
|
select PINCTRL_SUN50I_A64
|
||||||
|
select RESET_CONTROLLER
|
||||||
help
|
help
|
||||||
This enables support for Allwinner sunxi based SoCs like the A64.
|
This enables support for Allwinner sunxi based SoCs like the A64.
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,7 @@
|
||||||
reg = <0x000>;
|
reg = <0x000>;
|
||||||
enable-method = "psci";
|
enable-method = "psci";
|
||||||
cpu-idle-states = <&CPU_SLEEP_0>;
|
cpu-idle-states = <&CPU_SLEEP_0>;
|
||||||
|
#cooling-cells = <2>;
|
||||||
};
|
};
|
||||||
|
|
||||||
cpu1: cpu@1 {
|
cpu1: cpu@1 {
|
||||||
|
@ -89,6 +90,7 @@
|
||||||
reg = <0x100>;
|
reg = <0x100>;
|
||||||
enable-method = "psci";
|
enable-method = "psci";
|
||||||
cpu-idle-states = <&CPU_SLEEP_0>;
|
cpu-idle-states = <&CPU_SLEEP_0>;
|
||||||
|
#cooling-cells = <2>;
|
||||||
};
|
};
|
||||||
|
|
||||||
cpu3: cpu@101 {
|
cpu3: cpu@101 {
|
||||||
|
|
|
@ -796,6 +796,7 @@
|
||||||
"dsi_phy_regulator";
|
"dsi_phy_regulator";
|
||||||
|
|
||||||
#clock-cells = <1>;
|
#clock-cells = <1>;
|
||||||
|
#phy-cells = <0>;
|
||||||
|
|
||||||
clocks = <&gcc GCC_MDSS_AHB_CLK>;
|
clocks = <&gcc GCC_MDSS_AHB_CLK>;
|
||||||
clock-names = "iface_clk";
|
clock-names = "iface_clk";
|
||||||
|
@ -906,8 +907,8 @@
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
|
|
||||||
qcom,ipc-1 = <&apcs 0 13>;
|
qcom,ipc-1 = <&apcs 8 13>;
|
||||||
qcom,ipc-6 = <&apcs 0 19>;
|
qcom,ipc-3 = <&apcs 8 19>;
|
||||||
|
|
||||||
apps_smsm: apps@0 {
|
apps_smsm: apps@0 {
|
||||||
reg = <0>;
|
reg = <0>;
|
||||||
|
|
|
@ -232,6 +232,7 @@ static struct shash_alg crc32_alg = {
|
||||||
.cra_name = "crc32",
|
.cra_name = "crc32",
|
||||||
.cra_driver_name = "crc32-arm64-hw",
|
.cra_driver_name = "crc32-arm64-hw",
|
||||||
.cra_priority = 300,
|
.cra_priority = 300,
|
||||||
|
.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
|
||||||
.cra_blocksize = CHKSUM_BLOCK_SIZE,
|
.cra_blocksize = CHKSUM_BLOCK_SIZE,
|
||||||
.cra_alignmask = 0,
|
.cra_alignmask = 0,
|
||||||
.cra_ctxsize = sizeof(struct chksum_ctx),
|
.cra_ctxsize = sizeof(struct chksum_ctx),
|
||||||
|
@ -253,6 +254,7 @@ static struct shash_alg crc32c_alg = {
|
||||||
.cra_name = "crc32c",
|
.cra_name = "crc32c",
|
||||||
.cra_driver_name = "crc32c-arm64-hw",
|
.cra_driver_name = "crc32c-arm64-hw",
|
||||||
.cra_priority = 300,
|
.cra_priority = 300,
|
||||||
|
.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
|
||||||
.cra_blocksize = CHKSUM_BLOCK_SIZE,
|
.cra_blocksize = CHKSUM_BLOCK_SIZE,
|
||||||
.cra_alignmask = 0,
|
.cra_alignmask = 0,
|
||||||
.cra_ctxsize = sizeof(struct chksum_ctx),
|
.cra_ctxsize = sizeof(struct chksum_ctx),
|
||||||
|
|
|
@ -20,9 +20,6 @@
|
||||||
|
|
||||||
#include <asm/brk-imm.h>
|
#include <asm/brk-imm.h>
|
||||||
|
|
||||||
#ifdef CONFIG_GENERIC_BUG
|
|
||||||
#define HAVE_ARCH_BUG
|
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
||||||
#define _BUGVERBOSE_LOCATION(file, line) __BUGVERBOSE_LOCATION(file, line)
|
#define _BUGVERBOSE_LOCATION(file, line) __BUGVERBOSE_LOCATION(file, line)
|
||||||
#define __BUGVERBOSE_LOCATION(file, line) \
|
#define __BUGVERBOSE_LOCATION(file, line) \
|
||||||
|
@ -36,28 +33,36 @@
|
||||||
#define _BUGVERBOSE_LOCATION(file, line)
|
#define _BUGVERBOSE_LOCATION(file, line)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define _BUG_FLAGS(flags) __BUG_FLAGS(flags)
|
#ifdef CONFIG_GENERIC_BUG
|
||||||
|
|
||||||
#define __BUG_FLAGS(flags) asm volatile ( \
|
#define __BUG_ENTRY(flags) \
|
||||||
".pushsection __bug_table,\"a\"\n\t" \
|
".pushsection __bug_table,\"a\"\n\t" \
|
||||||
".align 2\n\t" \
|
".align 2\n\t" \
|
||||||
"0: .long 1f - 0b\n\t" \
|
"0: .long 1f - 0b\n\t" \
|
||||||
_BUGVERBOSE_LOCATION(__FILE__, __LINE__) \
|
_BUGVERBOSE_LOCATION(__FILE__, __LINE__) \
|
||||||
".short " #flags "\n\t" \
|
".short " #flags "\n\t" \
|
||||||
".popsection\n" \
|
".popsection\n" \
|
||||||
\
|
"1: "
|
||||||
"1: brk %[imm]" \
|
#else
|
||||||
:: [imm] "i" (BUG_BRK_IMM) \
|
#define __BUG_ENTRY(flags) ""
|
||||||
)
|
#endif
|
||||||
|
|
||||||
#define BUG() do { \
|
#define __BUG_FLAGS(flags) \
|
||||||
_BUG_FLAGS(0); \
|
asm volatile ( \
|
||||||
unreachable(); \
|
__BUG_ENTRY(flags) \
|
||||||
|
"brk %[imm]" :: [imm] "i" (BUG_BRK_IMM) \
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
#define BUG() do { \
|
||||||
|
__BUG_FLAGS(0); \
|
||||||
|
unreachable(); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define __WARN_TAINT(taint) _BUG_FLAGS(BUGFLAG_TAINT(taint))
|
#define __WARN_TAINT(taint) \
|
||||||
|
__BUG_FLAGS(BUGFLAG_TAINT(taint))
|
||||||
|
|
||||||
#endif /* ! CONFIG_GENERIC_BUG */
|
#define HAVE_ARCH_BUG
|
||||||
|
|
||||||
#include <asm-generic/bug.h>
|
#include <asm-generic/bug.h>
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
||||||
|
|
||||||
ret = kvm_psci_call(vcpu);
|
ret = kvm_psci_call(vcpu);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
kvm_inject_undefined(vcpu);
|
vcpu_set_reg(vcpu, 0, ~0UL);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
||||||
|
|
||||||
static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
||||||
{
|
{
|
||||||
kvm_inject_undefined(vcpu);
|
vcpu_set_reg(vcpu, 0, ~0UL);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -479,7 +479,7 @@ void __init paging_init(void)
|
||||||
* To do this we need to go via a temporary pgd.
|
* To do this we need to go via a temporary pgd.
|
||||||
*/
|
*/
|
||||||
cpu_replace_ttbr1(__va(pgd_phys));
|
cpu_replace_ttbr1(__va(pgd_phys));
|
||||||
memcpy(swapper_pg_dir, pgd, PAGE_SIZE);
|
memcpy(swapper_pg_dir, pgd, PGD_SIZE);
|
||||||
cpu_replace_ttbr1(swapper_pg_dir);
|
cpu_replace_ttbr1(swapper_pg_dir);
|
||||||
|
|
||||||
pgd_clear_fixmap();
|
pgd_clear_fixmap();
|
||||||
|
|
|
@ -44,6 +44,8 @@ SECTIONS {
|
||||||
.text : {
|
.text : {
|
||||||
HEAD_TEXT
|
HEAD_TEXT
|
||||||
TEXT_TEXT
|
TEXT_TEXT
|
||||||
|
IRQENTRY_TEXT
|
||||||
|
SOFTIRQENTRY_TEXT
|
||||||
SCHED_TEXT
|
SCHED_TEXT
|
||||||
CPUIDLE_TEXT
|
CPUIDLE_TEXT
|
||||||
LOCK_TEXT
|
LOCK_TEXT
|
||||||
|
|
|
@ -15,6 +15,8 @@ SECTIONS
|
||||||
.text : {
|
.text : {
|
||||||
HEAD_TEXT
|
HEAD_TEXT
|
||||||
TEXT_TEXT
|
TEXT_TEXT
|
||||||
|
IRQENTRY_TEXT
|
||||||
|
SOFTIRQENTRY_TEXT
|
||||||
SCHED_TEXT
|
SCHED_TEXT
|
||||||
CPUIDLE_TEXT
|
CPUIDLE_TEXT
|
||||||
LOCK_TEXT
|
LOCK_TEXT
|
||||||
|
|
|
@ -15,6 +15,8 @@ SECTIONS
|
||||||
.text : {
|
.text : {
|
||||||
HEAD_TEXT
|
HEAD_TEXT
|
||||||
TEXT_TEXT
|
TEXT_TEXT
|
||||||
|
IRQENTRY_TEXT
|
||||||
|
SOFTIRQENTRY_TEXT
|
||||||
SCHED_TEXT
|
SCHED_TEXT
|
||||||
CPUIDLE_TEXT
|
CPUIDLE_TEXT
|
||||||
LOCK_TEXT
|
LOCK_TEXT
|
||||||
|
|
|
@ -112,12 +112,12 @@ config MIPS_GENERIC
|
||||||
select SYS_SUPPORTS_MULTITHREADING
|
select SYS_SUPPORTS_MULTITHREADING
|
||||||
select SYS_SUPPORTS_RELOCATABLE
|
select SYS_SUPPORTS_RELOCATABLE
|
||||||
select SYS_SUPPORTS_SMARTMIPS
|
select SYS_SUPPORTS_SMARTMIPS
|
||||||
select USB_EHCI_BIG_ENDIAN_DESC if BIG_ENDIAN
|
select USB_EHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
|
||||||
select USB_EHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN
|
select USB_EHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
|
||||||
select USB_OHCI_BIG_ENDIAN_DESC if BIG_ENDIAN
|
select USB_OHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
|
||||||
select USB_OHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN
|
select USB_OHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
|
||||||
select USB_UHCI_BIG_ENDIAN_DESC if BIG_ENDIAN
|
select USB_UHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
|
||||||
select USB_UHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN
|
select USB_UHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
|
||||||
select USE_OF
|
select USE_OF
|
||||||
help
|
help
|
||||||
Select this to build a kernel which aims to support multiple boards,
|
Select this to build a kernel which aims to support multiple boards,
|
||||||
|
|
|
@ -576,7 +576,7 @@ static int __init ar7_register_uarts(void)
|
||||||
uart_port.type = PORT_AR7;
|
uart_port.type = PORT_AR7;
|
||||||
uart_port.uartclk = clk_get_rate(bus_clk) / 2;
|
uart_port.uartclk = clk_get_rate(bus_clk) / 2;
|
||||||
uart_port.iotype = UPIO_MEM32;
|
uart_port.iotype = UPIO_MEM32;
|
||||||
uart_port.flags = UPF_FIXED_TYPE;
|
uart_port.flags = UPF_FIXED_TYPE | UPF_BOOT_AUTOCONF;
|
||||||
uart_port.regshift = 2;
|
uart_port.regshift = 2;
|
||||||
|
|
||||||
uart_port.line = 0;
|
uart_port.line = 0;
|
||||||
|
|
|
@ -683,6 +683,18 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value)
|
||||||
struct task_struct *t;
|
struct task_struct *t;
|
||||||
int max_users;
|
int max_users;
|
||||||
|
|
||||||
|
/* If nothing to change, return right away, successfully. */
|
||||||
|
if (value == mips_get_process_fp_mode(task))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Only accept a mode change if 64-bit FP enabled for o32. */
|
||||||
|
if (!IS_ENABLED(CONFIG_MIPS_O32_FP64_SUPPORT))
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
/* And only for o32 tasks. */
|
||||||
|
if (IS_ENABLED(CONFIG_64BIT) && !test_thread_flag(TIF_32BIT_REGS))
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
/* Check the value is valid */
|
/* Check the value is valid */
|
||||||
if (value & ~known_bits)
|
if (value & ~known_bits)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
|
@ -439,25 +439,38 @@ static int gpr64_set(struct task_struct *target,
|
||||||
|
|
||||||
#endif /* CONFIG_64BIT */
|
#endif /* CONFIG_64BIT */
|
||||||
|
|
||||||
static int fpr_get(struct task_struct *target,
|
/*
|
||||||
const struct user_regset *regset,
|
* Copy the floating-point context to the supplied NT_PRFPREG buffer,
|
||||||
unsigned int pos, unsigned int count,
|
* !CONFIG_CPU_HAS_MSA variant. FP context's general register slots
|
||||||
void *kbuf, void __user *ubuf)
|
* correspond 1:1 to buffer slots. Only general registers are copied.
|
||||||
|
*/
|
||||||
|
static int fpr_get_fpa(struct task_struct *target,
|
||||||
|
unsigned int *pos, unsigned int *count,
|
||||||
|
void **kbuf, void __user **ubuf)
|
||||||
{
|
{
|
||||||
unsigned i;
|
return user_regset_copyout(pos, count, kbuf, ubuf,
|
||||||
int err;
|
&target->thread.fpu,
|
||||||
|
0, NUM_FPU_REGS * sizeof(elf_fpreg_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy the floating-point context to the supplied NT_PRFPREG buffer,
|
||||||
|
* CONFIG_CPU_HAS_MSA variant. Only lower 64 bits of FP context's
|
||||||
|
* general register slots are copied to buffer slots. Only general
|
||||||
|
* registers are copied.
|
||||||
|
*/
|
||||||
|
static int fpr_get_msa(struct task_struct *target,
|
||||||
|
unsigned int *pos, unsigned int *count,
|
||||||
|
void **kbuf, void __user **ubuf)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
u64 fpr_val;
|
u64 fpr_val;
|
||||||
|
int err;
|
||||||
|
|
||||||
/* XXX fcr31 */
|
BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t));
|
||||||
|
|
||||||
if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t))
|
|
||||||
return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
|
|
||||||
&target->thread.fpu,
|
|
||||||
0, sizeof(elf_fpregset_t));
|
|
||||||
|
|
||||||
for (i = 0; i < NUM_FPU_REGS; i++) {
|
for (i = 0; i < NUM_FPU_REGS; i++) {
|
||||||
fpr_val = get_fpr64(&target->thread.fpu.fpr[i], 0);
|
fpr_val = get_fpr64(&target->thread.fpu.fpr[i], 0);
|
||||||
err = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
|
err = user_regset_copyout(pos, count, kbuf, ubuf,
|
||||||
&fpr_val, i * sizeof(elf_fpreg_t),
|
&fpr_val, i * sizeof(elf_fpreg_t),
|
||||||
(i + 1) * sizeof(elf_fpreg_t));
|
(i + 1) * sizeof(elf_fpreg_t));
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -467,27 +480,64 @@ static int fpr_get(struct task_struct *target,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fpr_set(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.
|
||||||
|
*/
|
||||||
|
static int fpr_get(struct task_struct *target,
|
||||||
const struct user_regset *regset,
|
const struct user_regset *regset,
|
||||||
unsigned int pos, unsigned int count,
|
unsigned int pos, unsigned int count,
|
||||||
const void *kbuf, const void __user *ubuf)
|
void *kbuf, void __user *ubuf)
|
||||||
{
|
{
|
||||||
unsigned i;
|
const int fcr31_pos = NUM_FPU_REGS * sizeof(elf_fpreg_t);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t))
|
||||||
|
err = fpr_get_fpa(target, &pos, &count, &kbuf, &ubuf);
|
||||||
|
else
|
||||||
|
err = fpr_get_msa(target, &pos, &count, &kbuf, &ubuf);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
|
||||||
|
&target->thread.fpu.fcr31,
|
||||||
|
fcr31_pos, fcr31_pos + sizeof(u32));
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy the supplied NT_PRFPREG buffer to the floating-point context,
|
||||||
|
* !CONFIG_CPU_HAS_MSA variant. Buffer slots correspond 1:1 to FP
|
||||||
|
* context's general register slots. Only general registers are copied.
|
||||||
|
*/
|
||||||
|
static int fpr_set_fpa(struct task_struct *target,
|
||||||
|
unsigned int *pos, unsigned int *count,
|
||||||
|
const void **kbuf, const void __user **ubuf)
|
||||||
|
{
|
||||||
|
return user_regset_copyin(pos, count, kbuf, ubuf,
|
||||||
|
&target->thread.fpu,
|
||||||
|
0, NUM_FPU_REGS * sizeof(elf_fpreg_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy the supplied NT_PRFPREG buffer to the floating-point context,
|
||||||
|
* CONFIG_CPU_HAS_MSA variant. Buffer slots are copied to lower 64
|
||||||
|
* bits only of FP context's general register slots. Only general
|
||||||
|
* registers are copied.
|
||||||
|
*/
|
||||||
|
static int fpr_set_msa(struct task_struct *target,
|
||||||
|
unsigned int *pos, unsigned int *count,
|
||||||
|
const void **kbuf, const void __user **ubuf)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
u64 fpr_val;
|
u64 fpr_val;
|
||||||
|
int err;
|
||||||
/* XXX fcr31 */
|
|
||||||
|
|
||||||
init_fp_ctx(target);
|
|
||||||
|
|
||||||
if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t))
|
|
||||||
return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
|
||||||
&target->thread.fpu,
|
|
||||||
0, sizeof(elf_fpregset_t));
|
|
||||||
|
|
||||||
BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t));
|
BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t));
|
||||||
for (i = 0; i < NUM_FPU_REGS && count >= sizeof(elf_fpreg_t); i++) {
|
for (i = 0; i < NUM_FPU_REGS && *count > 0; i++) {
|
||||||
err = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
err = user_regset_copyin(pos, count, kbuf, ubuf,
|
||||||
&fpr_val, i * sizeof(elf_fpreg_t),
|
&fpr_val, i * sizeof(elf_fpreg_t),
|
||||||
(i + 1) * sizeof(elf_fpreg_t));
|
(i + 1) * sizeof(elf_fpreg_t));
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -498,6 +548,53 @@ static int fpr_set(struct task_struct *target,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* We optimize for the case where `count % sizeof(elf_fpreg_t) == 0',
|
||||||
|
* which is supposed to have been guaranteed by the kernel before
|
||||||
|
* calling us, e.g. in `ptrace_regset'. We enforce that requirement,
|
||||||
|
* so that we can safely avoid preinitializing temporaries for
|
||||||
|
* partial register writes.
|
||||||
|
*/
|
||||||
|
static int fpr_set(struct task_struct *target,
|
||||||
|
const struct user_regset *regset,
|
||||||
|
unsigned int pos, unsigned int count,
|
||||||
|
const void *kbuf, const void __user *ubuf)
|
||||||
|
{
|
||||||
|
const int fcr31_pos = NUM_FPU_REGS * sizeof(elf_fpreg_t);
|
||||||
|
u32 fcr31;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
BUG_ON(count % sizeof(elf_fpreg_t));
|
||||||
|
|
||||||
|
if (pos + count > sizeof(elf_fpregset_t))
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
init_fp_ctx(target);
|
||||||
|
|
||||||
|
if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t))
|
||||||
|
err = fpr_set_fpa(target, &pos, &count, &kbuf, &ubuf);
|
||||||
|
else
|
||||||
|
err = fpr_set_msa(target, &pos, &count, &kbuf, &ubuf);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (count > 0) {
|
||||||
|
err = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||||
|
&fcr31,
|
||||||
|
fcr31_pos, fcr31_pos + sizeof(u32));
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
ptrace_setfcr31(target, fcr31);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
enum mips_regset {
|
enum mips_regset {
|
||||||
REGSET_GPR,
|
REGSET_GPR,
|
||||||
REGSET_FPR,
|
REGSET_FPR,
|
||||||
|
|
|
@ -437,7 +437,7 @@ transfer_failed:
|
||||||
|
|
||||||
info.si_signo = SIGSEGV;
|
info.si_signo = SIGSEGV;
|
||||||
info.si_errno = 0;
|
info.si_errno = 0;
|
||||||
info.si_code = 0;
|
info.si_code = SEGV_MAPERR;
|
||||||
info.si_addr = (void *) regs->pc;
|
info.si_addr = (void *) regs->pc;
|
||||||
force_sig_info(SIGSEGV, &info, current);
|
force_sig_info(SIGSEGV, &info, current);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -302,12 +302,12 @@ asmlinkage void do_unaligned_access(struct pt_regs *regs, unsigned long address)
|
||||||
siginfo_t info;
|
siginfo_t info;
|
||||||
|
|
||||||
if (user_mode(regs)) {
|
if (user_mode(regs)) {
|
||||||
/* Send a SIGSEGV */
|
/* Send a SIGBUS */
|
||||||
info.si_signo = SIGSEGV;
|
info.si_signo = SIGBUS;
|
||||||
info.si_errno = 0;
|
info.si_errno = 0;
|
||||||
/* info.si_code has been set above */
|
info.si_code = BUS_ADRALN;
|
||||||
info.si_addr = (void *)address;
|
info.si_addr = (void __user *)address;
|
||||||
force_sig_info(SIGSEGV, &info, current);
|
force_sig_info(SIGBUS, &info, current);
|
||||||
} else {
|
} else {
|
||||||
printk("KERNEL: Unaligned Access 0x%.8lx\n", address);
|
printk("KERNEL: Unaligned Access 0x%.8lx\n", address);
|
||||||
show_registers(regs);
|
show_registers(regs);
|
||||||
|
|
|
@ -128,6 +128,7 @@ config PPC
|
||||||
select ARCH_HAS_GCOV_PROFILE_ALL
|
select ARCH_HAS_GCOV_PROFILE_ALL
|
||||||
select GENERIC_SMP_IDLE_THREAD
|
select GENERIC_SMP_IDLE_THREAD
|
||||||
select GENERIC_CMOS_UPDATE
|
select GENERIC_CMOS_UPDATE
|
||||||
|
select GENERIC_CPU_VULNERABILITIES if PPC_BOOK3S_64
|
||||||
select GENERIC_TIME_VSYSCALL_OLD
|
select GENERIC_TIME_VSYSCALL_OLD
|
||||||
select GENERIC_CLOCKEVENTS
|
select GENERIC_CLOCKEVENTS
|
||||||
select GENERIC_CLOCKEVENTS_BROADCAST if SMP
|
select GENERIC_CLOCKEVENTS_BROADCAST if SMP
|
||||||
|
|
|
@ -141,6 +141,7 @@ static struct shash_alg alg = {
|
||||||
.cra_name = "crc32c",
|
.cra_name = "crc32c",
|
||||||
.cra_driver_name = "crc32c-vpmsum",
|
.cra_driver_name = "crc32c-vpmsum",
|
||||||
.cra_priority = 200,
|
.cra_priority = 200,
|
||||||
|
.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
|
||||||
.cra_blocksize = CHKSUM_BLOCK_SIZE,
|
.cra_blocksize = CHKSUM_BLOCK_SIZE,
|
||||||
.cra_ctxsize = sizeof(u32),
|
.cra_ctxsize = sizeof(u32),
|
||||||
.cra_module = THIS_MODULE,
|
.cra_module = THIS_MODULE,
|
||||||
|
|
|
@ -209,5 +209,11 @@ exc_##label##_book3e:
|
||||||
ori r3,r3,vector_offset@l; \
|
ori r3,r3,vector_offset@l; \
|
||||||
mtspr SPRN_IVOR##vector_number,r3;
|
mtspr SPRN_IVOR##vector_number,r3;
|
||||||
|
|
||||||
|
#define RFI_TO_KERNEL \
|
||||||
|
rfi
|
||||||
|
|
||||||
|
#define RFI_TO_USER \
|
||||||
|
rfi
|
||||||
|
|
||||||
#endif /* _ASM_POWERPC_EXCEPTION_64E_H */
|
#endif /* _ASM_POWERPC_EXCEPTION_64E_H */
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,59 @@
|
||||||
#define EX_PPR 88 /* SMT thread status register (priority) */
|
#define EX_PPR 88 /* SMT thread status register (priority) */
|
||||||
#define EX_CTR 96
|
#define EX_CTR 96
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Macros for annotating the expected destination of (h)rfid
|
||||||
|
*
|
||||||
|
* The nop instructions allow us to insert one or more instructions to flush the
|
||||||
|
* L1-D cache when returning to userspace or a guest.
|
||||||
|
*/
|
||||||
|
#define RFI_FLUSH_SLOT \
|
||||||
|
RFI_FLUSH_FIXUP_SECTION; \
|
||||||
|
nop; \
|
||||||
|
nop; \
|
||||||
|
nop
|
||||||
|
|
||||||
|
#define RFI_TO_KERNEL \
|
||||||
|
rfid
|
||||||
|
|
||||||
|
#define RFI_TO_USER \
|
||||||
|
RFI_FLUSH_SLOT; \
|
||||||
|
rfid; \
|
||||||
|
b rfi_flush_fallback
|
||||||
|
|
||||||
|
#define RFI_TO_USER_OR_KERNEL \
|
||||||
|
RFI_FLUSH_SLOT; \
|
||||||
|
rfid; \
|
||||||
|
b rfi_flush_fallback
|
||||||
|
|
||||||
|
#define RFI_TO_GUEST \
|
||||||
|
RFI_FLUSH_SLOT; \
|
||||||
|
rfid; \
|
||||||
|
b rfi_flush_fallback
|
||||||
|
|
||||||
|
#define HRFI_TO_KERNEL \
|
||||||
|
hrfid
|
||||||
|
|
||||||
|
#define HRFI_TO_USER \
|
||||||
|
RFI_FLUSH_SLOT; \
|
||||||
|
hrfid; \
|
||||||
|
b hrfi_flush_fallback
|
||||||
|
|
||||||
|
#define HRFI_TO_USER_OR_KERNEL \
|
||||||
|
RFI_FLUSH_SLOT; \
|
||||||
|
hrfid; \
|
||||||
|
b hrfi_flush_fallback
|
||||||
|
|
||||||
|
#define HRFI_TO_GUEST \
|
||||||
|
RFI_FLUSH_SLOT; \
|
||||||
|
hrfid; \
|
||||||
|
b hrfi_flush_fallback
|
||||||
|
|
||||||
|
#define HRFI_TO_UNKNOWN \
|
||||||
|
RFI_FLUSH_SLOT; \
|
||||||
|
hrfid; \
|
||||||
|
b hrfi_flush_fallback
|
||||||
|
|
||||||
#ifdef CONFIG_RELOCATABLE
|
#ifdef CONFIG_RELOCATABLE
|
||||||
#define __EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \
|
#define __EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \
|
||||||
mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \
|
mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \
|
||||||
|
@ -189,7 +242,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
|
||||||
mtspr SPRN_##h##SRR0,r12; \
|
mtspr SPRN_##h##SRR0,r12; \
|
||||||
mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \
|
mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \
|
||||||
mtspr SPRN_##h##SRR1,r10; \
|
mtspr SPRN_##h##SRR1,r10; \
|
||||||
h##rfid; \
|
h##RFI_TO_KERNEL; \
|
||||||
b . /* prevent speculative execution */
|
b . /* prevent speculative execution */
|
||||||
#define EXCEPTION_PROLOG_PSERIES_1(label, h) \
|
#define EXCEPTION_PROLOG_PSERIES_1(label, h) \
|
||||||
__EXCEPTION_PROLOG_PSERIES_1(label, h)
|
__EXCEPTION_PROLOG_PSERIES_1(label, h)
|
||||||
|
|
|
@ -189,4 +189,19 @@ void apply_feature_fixups(void);
|
||||||
void setup_feature_keys(void);
|
void setup_feature_keys(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define RFI_FLUSH_FIXUP_SECTION \
|
||||||
|
951: \
|
||||||
|
.pushsection __rfi_flush_fixup,"a"; \
|
||||||
|
.align 2; \
|
||||||
|
952: \
|
||||||
|
FTR_ENTRY_OFFSET 951b-952b; \
|
||||||
|
.popsection;
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
|
extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __ASM_POWERPC_FEATURE_FIXUPS_H */
|
#endif /* __ASM_POWERPC_FEATURE_FIXUPS_H */
|
||||||
|
|
|
@ -240,6 +240,7 @@
|
||||||
#define H_GET_HCA_INFO 0x1B8
|
#define H_GET_HCA_INFO 0x1B8
|
||||||
#define H_GET_PERF_COUNT 0x1BC
|
#define H_GET_PERF_COUNT 0x1BC
|
||||||
#define H_MANAGE_TRACE 0x1C0
|
#define H_MANAGE_TRACE 0x1C0
|
||||||
|
#define H_GET_CPU_CHARACTERISTICS 0x1C8
|
||||||
#define H_FREE_LOGICAL_LAN_BUFFER 0x1D4
|
#define H_FREE_LOGICAL_LAN_BUFFER 0x1D4
|
||||||
#define H_QUERY_INT_STATE 0x1E4
|
#define H_QUERY_INT_STATE 0x1E4
|
||||||
#define H_POLL_PENDING 0x1D8
|
#define H_POLL_PENDING 0x1D8
|
||||||
|
@ -306,7 +307,19 @@
|
||||||
#define H_SET_MODE_RESOURCE_ADDR_TRANS_MODE 3
|
#define H_SET_MODE_RESOURCE_ADDR_TRANS_MODE 3
|
||||||
#define H_SET_MODE_RESOURCE_LE 4
|
#define H_SET_MODE_RESOURCE_LE 4
|
||||||
|
|
||||||
|
/* H_GET_CPU_CHARACTERISTICS return values */
|
||||||
|
#define H_CPU_CHAR_SPEC_BAR_ORI31 (1ull << 63) // IBM bit 0
|
||||||
|
#define H_CPU_CHAR_BCCTRL_SERIALISED (1ull << 62) // IBM bit 1
|
||||||
|
#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_BEHAV_FAVOUR_SECURITY (1ull << 63) // IBM bit 0
|
||||||
|
#define H_CPU_BEHAV_L1D_FLUSH_PR (1ull << 62) // IBM bit 1
|
||||||
|
#define H_CPU_BEHAV_BNDS_CHK_SPEC_BAR (1ull << 61) // IBM bit 2
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* plpar_hcall_norets: - Make a pseries hypervisor call with no return arguments
|
* plpar_hcall_norets: - Make a pseries hypervisor call with no return arguments
|
||||||
|
@ -433,6 +446,11 @@ static inline unsigned long cmo_get_page_size(void)
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_PPC_PSERIES */
|
#endif /* CONFIG_PPC_PSERIES */
|
||||||
|
|
||||||
|
struct h_cpu_char_result {
|
||||||
|
u64 character;
|
||||||
|
u64 behaviour;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
#endif /* _ASM_POWERPC_HVCALL_H */
|
#endif /* _ASM_POWERPC_HVCALL_H */
|
||||||
|
|
|
@ -205,6 +205,15 @@ struct paca_struct {
|
||||||
struct sibling_subcore_state *sibling_subcore_state;
|
struct sibling_subcore_state *sibling_subcore_state;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_PPC_BOOK3S_64
|
||||||
|
/*
|
||||||
|
* rfi fallback flush must be in its own cacheline to prevent
|
||||||
|
* other paca data leaking into the L1d
|
||||||
|
*/
|
||||||
|
u64 exrfi[13] __aligned(0x80);
|
||||||
|
void *rfi_flush_fallback_area;
|
||||||
|
u64 l1d_flush_size;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_BOOK3S
|
#ifdef CONFIG_PPC_BOOK3S
|
||||||
|
|
|
@ -340,4 +340,18 @@ static inline long plapr_set_watchpoint0(unsigned long dawr0, unsigned long dawr
|
||||||
return plpar_set_mode(0, H_SET_MODE_RESOURCE_SET_DAWR, dawr0, dawrx0);
|
return plpar_set_mode(0, H_SET_MODE_RESOURCE_SET_DAWR, dawr0, dawrx0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline long plpar_get_cpu_characteristics(struct h_cpu_char_result *p)
|
||||||
|
{
|
||||||
|
unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
|
||||||
|
long rc;
|
||||||
|
|
||||||
|
rc = plpar_hcall(H_GET_CPU_CHARACTERISTICS, retbuf);
|
||||||
|
if (rc == H_SUCCESS) {
|
||||||
|
p->character = retbuf[0];
|
||||||
|
p->behaviour = retbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _ASM_POWERPC_PLPAR_WRAPPERS_H */
|
#endif /* _ASM_POWERPC_PLPAR_WRAPPERS_H */
|
||||||
|
|
|
@ -38,6 +38,19 @@ static inline void pseries_big_endian_exceptions(void) {}
|
||||||
static inline void pseries_little_endian_exceptions(void) {}
|
static inline void pseries_little_endian_exceptions(void) {}
|
||||||
#endif /* CONFIG_PPC_PSERIES */
|
#endif /* CONFIG_PPC_PSERIES */
|
||||||
|
|
||||||
|
void rfi_flush_enable(bool enable);
|
||||||
|
|
||||||
|
/* These are bit flags */
|
||||||
|
enum l1d_flush_type {
|
||||||
|
L1D_FLUSH_NONE = 0x1,
|
||||||
|
L1D_FLUSH_FALLBACK = 0x2,
|
||||||
|
L1D_FLUSH_ORI = 0x4,
|
||||||
|
L1D_FLUSH_MTTRIG = 0x8,
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init setup_rfi_flush(enum l1d_flush_type, bool enable);
|
||||||
|
void do_rfi_flush_fixups(enum l1d_flush_type types);
|
||||||
|
|
||||||
#endif /* !__ASSEMBLY__ */
|
#endif /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
#endif /* _ASM_POWERPC_SETUP_H */
|
#endif /* _ASM_POWERPC_SETUP_H */
|
||||||
|
|
|
@ -240,6 +240,9 @@ int main(void)
|
||||||
#ifdef CONFIG_PPC_BOOK3S_64
|
#ifdef CONFIG_PPC_BOOK3S_64
|
||||||
DEFINE(PACAMCEMERGSP, offsetof(struct paca_struct, mc_emergency_sp));
|
DEFINE(PACAMCEMERGSP, offsetof(struct paca_struct, mc_emergency_sp));
|
||||||
DEFINE(PACA_IN_MCE, offsetof(struct paca_struct, in_mce));
|
DEFINE(PACA_IN_MCE, offsetof(struct paca_struct, in_mce));
|
||||||
|
DEFINE(PACA_RFI_FLUSH_FALLBACK_AREA, offsetof(struct paca_struct, rfi_flush_fallback_area));
|
||||||
|
DEFINE(PACA_EXRFI, offsetof(struct paca_struct, exrfi));
|
||||||
|
DEFINE(PACA_L1D_FLUSH_SIZE, offsetof(struct paca_struct, l1d_flush_size));
|
||||||
#endif
|
#endif
|
||||||
DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
|
DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
|
||||||
DEFINE(PACAKEXECSTATE, offsetof(struct paca_struct, kexec_state));
|
DEFINE(PACAKEXECSTATE, offsetof(struct paca_struct, kexec_state));
|
||||||
|
|
|
@ -39,6 +39,11 @@
|
||||||
#include <asm/tm.h>
|
#include <asm/tm.h>
|
||||||
#include <asm/ppc-opcode.h>
|
#include <asm/ppc-opcode.h>
|
||||||
#include <asm/export.h>
|
#include <asm/export.h>
|
||||||
|
#ifdef CONFIG_PPC_BOOK3S
|
||||||
|
#include <asm/exception-64s.h>
|
||||||
|
#else
|
||||||
|
#include <asm/exception-64e.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* System calls.
|
* System calls.
|
||||||
|
@ -251,13 +256,23 @@ BEGIN_FTR_SECTION
|
||||||
END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
|
END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
|
||||||
|
|
||||||
ld r13,GPR13(r1) /* only restore r13 if returning to usermode */
|
ld r13,GPR13(r1) /* only restore r13 if returning to usermode */
|
||||||
|
ld r2,GPR2(r1)
|
||||||
|
ld r1,GPR1(r1)
|
||||||
|
mtlr r4
|
||||||
|
mtcr r5
|
||||||
|
mtspr SPRN_SRR0,r7
|
||||||
|
mtspr SPRN_SRR1,r8
|
||||||
|
RFI_TO_USER
|
||||||
|
b . /* prevent speculative execution */
|
||||||
|
|
||||||
|
/* exit to kernel */
|
||||||
1: ld r2,GPR2(r1)
|
1: ld r2,GPR2(r1)
|
||||||
ld r1,GPR1(r1)
|
ld r1,GPR1(r1)
|
||||||
mtlr r4
|
mtlr r4
|
||||||
mtcr r5
|
mtcr r5
|
||||||
mtspr SPRN_SRR0,r7
|
mtspr SPRN_SRR0,r7
|
||||||
mtspr SPRN_SRR1,r8
|
mtspr SPRN_SRR1,r8
|
||||||
RFI
|
RFI_TO_KERNEL
|
||||||
b . /* prevent speculative execution */
|
b . /* prevent speculative execution */
|
||||||
|
|
||||||
syscall_error:
|
syscall_error:
|
||||||
|
@ -386,8 +401,7 @@ tabort_syscall:
|
||||||
mtmsrd r10, 1
|
mtmsrd r10, 1
|
||||||
mtspr SPRN_SRR0, r11
|
mtspr SPRN_SRR0, r11
|
||||||
mtspr SPRN_SRR1, r12
|
mtspr SPRN_SRR1, r12
|
||||||
|
RFI_TO_USER
|
||||||
rfid
|
|
||||||
b . /* prevent speculative execution */
|
b . /* prevent speculative execution */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -859,7 +873,7 @@ BEGIN_FTR_SECTION
|
||||||
END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
|
END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
|
||||||
ACCOUNT_CPU_USER_EXIT(r13, r2, r4)
|
ACCOUNT_CPU_USER_EXIT(r13, r2, r4)
|
||||||
REST_GPR(13, r1)
|
REST_GPR(13, r1)
|
||||||
1:
|
|
||||||
mtspr SPRN_SRR1,r3
|
mtspr SPRN_SRR1,r3
|
||||||
|
|
||||||
ld r2,_CCR(r1)
|
ld r2,_CCR(r1)
|
||||||
|
@ -872,8 +886,22 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
|
||||||
ld r3,GPR3(r1)
|
ld r3,GPR3(r1)
|
||||||
ld r4,GPR4(r1)
|
ld r4,GPR4(r1)
|
||||||
ld r1,GPR1(r1)
|
ld r1,GPR1(r1)
|
||||||
|
RFI_TO_USER
|
||||||
|
b . /* prevent speculative execution */
|
||||||
|
|
||||||
rfid
|
1: mtspr SPRN_SRR1,r3
|
||||||
|
|
||||||
|
ld r2,_CCR(r1)
|
||||||
|
mtcrf 0xFF,r2
|
||||||
|
ld r2,_NIP(r1)
|
||||||
|
mtspr SPRN_SRR0,r2
|
||||||
|
|
||||||
|
ld r0,GPR0(r1)
|
||||||
|
ld r2,GPR2(r1)
|
||||||
|
ld r3,GPR3(r1)
|
||||||
|
ld r4,GPR4(r1)
|
||||||
|
ld r1,GPR1(r1)
|
||||||
|
RFI_TO_KERNEL
|
||||||
b . /* prevent speculative execution */
|
b . /* prevent speculative execution */
|
||||||
|
|
||||||
#endif /* CONFIG_PPC_BOOK3E */
|
#endif /* CONFIG_PPC_BOOK3E */
|
||||||
|
@ -1049,7 +1077,7 @@ _GLOBAL(enter_rtas)
|
||||||
|
|
||||||
mtspr SPRN_SRR0,r5
|
mtspr SPRN_SRR0,r5
|
||||||
mtspr SPRN_SRR1,r6
|
mtspr SPRN_SRR1,r6
|
||||||
rfid
|
RFI_TO_KERNEL
|
||||||
b . /* prevent speculative execution */
|
b . /* prevent speculative execution */
|
||||||
|
|
||||||
rtas_return_loc:
|
rtas_return_loc:
|
||||||
|
@ -1074,7 +1102,7 @@ rtas_return_loc:
|
||||||
|
|
||||||
mtspr SPRN_SRR0,r3
|
mtspr SPRN_SRR0,r3
|
||||||
mtspr SPRN_SRR1,r4
|
mtspr SPRN_SRR1,r4
|
||||||
rfid
|
RFI_TO_KERNEL
|
||||||
b . /* prevent speculative execution */
|
b . /* prevent speculative execution */
|
||||||
|
|
||||||
.align 3
|
.align 3
|
||||||
|
@ -1145,7 +1173,7 @@ _GLOBAL(enter_prom)
|
||||||
LOAD_REG_IMMEDIATE(r12, MSR_SF | MSR_ISF | MSR_LE)
|
LOAD_REG_IMMEDIATE(r12, MSR_SF | MSR_ISF | MSR_LE)
|
||||||
andc r11,r11,r12
|
andc r11,r11,r12
|
||||||
mtsrr1 r11
|
mtsrr1 r11
|
||||||
rfid
|
RFI_TO_KERNEL
|
||||||
#endif /* CONFIG_PPC_BOOK3E */
|
#endif /* CONFIG_PPC_BOOK3E */
|
||||||
|
|
||||||
1: /* Return from OF */
|
1: /* Return from OF */
|
||||||
|
|
|
@ -244,7 +244,7 @@ BEGIN_FTR_SECTION
|
||||||
LOAD_HANDLER(r12, machine_check_handle_early)
|
LOAD_HANDLER(r12, machine_check_handle_early)
|
||||||
1: mtspr SPRN_SRR0,r12
|
1: mtspr SPRN_SRR0,r12
|
||||||
mtspr SPRN_SRR1,r11
|
mtspr SPRN_SRR1,r11
|
||||||
rfid
|
RFI_TO_KERNEL
|
||||||
b . /* prevent speculative execution */
|
b . /* prevent speculative execution */
|
||||||
2:
|
2:
|
||||||
/* Stack overflow. Stay on emergency stack and panic.
|
/* Stack overflow. Stay on emergency stack and panic.
|
||||||
|
@ -280,7 +280,7 @@ machine_check_pSeries_0:
|
||||||
mtspr SPRN_SRR0,r12
|
mtspr SPRN_SRR0,r12
|
||||||
mfspr r12,SPRN_SRR1
|
mfspr r12,SPRN_SRR1
|
||||||
mtspr SPRN_SRR1,r10
|
mtspr SPRN_SRR1,r10
|
||||||
rfid
|
RFI_TO_KERNEL
|
||||||
b . /* prevent speculative execution */
|
b . /* prevent speculative execution */
|
||||||
|
|
||||||
TRAMP_KVM_SKIP(PACA_EXMC, 0x200)
|
TRAMP_KVM_SKIP(PACA_EXMC, 0x200)
|
||||||
|
@ -446,7 +446,7 @@ EXC_COMMON_BEGIN(machine_check_handle_early)
|
||||||
li r3,MSR_ME
|
li r3,MSR_ME
|
||||||
andc r10,r10,r3 /* Turn off MSR_ME */
|
andc r10,r10,r3 /* Turn off MSR_ME */
|
||||||
mtspr SPRN_SRR1,r10
|
mtspr SPRN_SRR1,r10
|
||||||
rfid
|
RFI_TO_KERNEL
|
||||||
b .
|
b .
|
||||||
2:
|
2:
|
||||||
/*
|
/*
|
||||||
|
@ -464,7 +464,7 @@ EXC_COMMON_BEGIN(machine_check_handle_early)
|
||||||
*/
|
*/
|
||||||
bl machine_check_queue_event
|
bl machine_check_queue_event
|
||||||
MACHINE_CHECK_HANDLER_WINDUP
|
MACHINE_CHECK_HANDLER_WINDUP
|
||||||
rfid
|
RFI_TO_USER_OR_KERNEL
|
||||||
9:
|
9:
|
||||||
/* Deliver the machine check to host kernel in V mode. */
|
/* Deliver the machine check to host kernel in V mode. */
|
||||||
MACHINE_CHECK_HANDLER_WINDUP
|
MACHINE_CHECK_HANDLER_WINDUP
|
||||||
|
@ -655,6 +655,8 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX)
|
||||||
|
|
||||||
andi. r10,r12,MSR_RI /* check for unrecoverable exception */
|
andi. r10,r12,MSR_RI /* check for unrecoverable exception */
|
||||||
beq- 2f
|
beq- 2f
|
||||||
|
andi. r10,r12,MSR_PR /* check for user mode (PR != 0) */
|
||||||
|
bne 1f
|
||||||
|
|
||||||
/* All done -- return from exception. */
|
/* All done -- return from exception. */
|
||||||
|
|
||||||
|
@ -671,7 +673,24 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX)
|
||||||
ld r11,PACA_EXSLB+EX_R11(r13)
|
ld r11,PACA_EXSLB+EX_R11(r13)
|
||||||
ld r12,PACA_EXSLB+EX_R12(r13)
|
ld r12,PACA_EXSLB+EX_R12(r13)
|
||||||
ld r13,PACA_EXSLB+EX_R13(r13)
|
ld r13,PACA_EXSLB+EX_R13(r13)
|
||||||
rfid
|
RFI_TO_KERNEL
|
||||||
|
b . /* prevent speculative execution */
|
||||||
|
|
||||||
|
1:
|
||||||
|
.machine push
|
||||||
|
.machine "power4"
|
||||||
|
mtcrf 0x80,r9
|
||||||
|
mtcrf 0x02,r9 /* I/D indication is in cr6 */
|
||||||
|
mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */
|
||||||
|
.machine pop
|
||||||
|
|
||||||
|
RESTORE_PPR_PACA(PACA_EXSLB, r9)
|
||||||
|
ld r9,PACA_EXSLB+EX_R9(r13)
|
||||||
|
ld r10,PACA_EXSLB+EX_R10(r13)
|
||||||
|
ld r11,PACA_EXSLB+EX_R11(r13)
|
||||||
|
ld r12,PACA_EXSLB+EX_R12(r13)
|
||||||
|
ld r13,PACA_EXSLB+EX_R13(r13)
|
||||||
|
RFI_TO_USER
|
||||||
b . /* prevent speculative execution */
|
b . /* prevent speculative execution */
|
||||||
|
|
||||||
2: mfspr r11,SPRN_SRR0
|
2: mfspr r11,SPRN_SRR0
|
||||||
|
@ -679,7 +698,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX)
|
||||||
mtspr SPRN_SRR0,r10
|
mtspr SPRN_SRR0,r10
|
||||||
ld r10,PACAKMSR(r13)
|
ld r10,PACAKMSR(r13)
|
||||||
mtspr SPRN_SRR1,r10
|
mtspr SPRN_SRR1,r10
|
||||||
rfid
|
RFI_TO_KERNEL
|
||||||
b .
|
b .
|
||||||
|
|
||||||
8: mfspr r11,SPRN_SRR0
|
8: mfspr r11,SPRN_SRR0
|
||||||
|
@ -687,7 +706,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX)
|
||||||
mtspr SPRN_SRR0,r10
|
mtspr SPRN_SRR0,r10
|
||||||
ld r10,PACAKMSR(r13)
|
ld r10,PACAKMSR(r13)
|
||||||
mtspr SPRN_SRR1,r10
|
mtspr SPRN_SRR1,r10
|
||||||
rfid
|
RFI_TO_KERNEL
|
||||||
b .
|
b .
|
||||||
|
|
||||||
EXC_COMMON_BEGIN(unrecov_slb)
|
EXC_COMMON_BEGIN(unrecov_slb)
|
||||||
|
@ -874,7 +893,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) \
|
||||||
mtspr SPRN_SRR0,r10 ; \
|
mtspr SPRN_SRR0,r10 ; \
|
||||||
ld r10,PACAKMSR(r13) ; \
|
ld r10,PACAKMSR(r13) ; \
|
||||||
mtspr SPRN_SRR1,r10 ; \
|
mtspr SPRN_SRR1,r10 ; \
|
||||||
rfid ; \
|
RFI_TO_KERNEL ; \
|
||||||
b . ; /* prevent speculative execution */
|
b . ; /* prevent speculative execution */
|
||||||
|
|
||||||
#define SYSCALL_PSERIES_3 \
|
#define SYSCALL_PSERIES_3 \
|
||||||
|
@ -882,7 +901,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) \
|
||||||
1: mfspr r12,SPRN_SRR1 ; \
|
1: mfspr r12,SPRN_SRR1 ; \
|
||||||
xori r12,r12,MSR_LE ; \
|
xori r12,r12,MSR_LE ; \
|
||||||
mtspr SPRN_SRR1,r12 ; \
|
mtspr SPRN_SRR1,r12 ; \
|
||||||
rfid ; /* return to userspace */ \
|
RFI_TO_USER ; /* return to userspace */ \
|
||||||
b . ; /* prevent speculative execution */
|
b . ; /* prevent speculative execution */
|
||||||
|
|
||||||
#if defined(CONFIG_RELOCATABLE)
|
#if defined(CONFIG_RELOCATABLE)
|
||||||
|
@ -1257,7 +1276,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
|
||||||
ld r11,PACA_EXGEN+EX_R11(r13)
|
ld r11,PACA_EXGEN+EX_R11(r13)
|
||||||
ld r12,PACA_EXGEN+EX_R12(r13)
|
ld r12,PACA_EXGEN+EX_R12(r13)
|
||||||
ld r13,PACA_EXGEN+EX_R13(r13)
|
ld r13,PACA_EXGEN+EX_R13(r13)
|
||||||
HRFID
|
HRFI_TO_UNKNOWN
|
||||||
b .
|
b .
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1331,7 +1350,7 @@ masked_##_H##interrupt: \
|
||||||
ld r10,PACA_EXGEN+EX_R10(r13); \
|
ld r10,PACA_EXGEN+EX_R10(r13); \
|
||||||
ld r11,PACA_EXGEN+EX_R11(r13); \
|
ld r11,PACA_EXGEN+EX_R11(r13); \
|
||||||
GET_SCRATCH0(r13); \
|
GET_SCRATCH0(r13); \
|
||||||
##_H##rfid; \
|
##_H##RFI_TO_KERNEL; \
|
||||||
b .
|
b .
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1353,7 +1372,7 @@ TRAMP_REAL_BEGIN(kvmppc_skip_interrupt)
|
||||||
addi r13, r13, 4
|
addi r13, r13, 4
|
||||||
mtspr SPRN_SRR0, r13
|
mtspr SPRN_SRR0, r13
|
||||||
GET_SCRATCH0(r13)
|
GET_SCRATCH0(r13)
|
||||||
rfid
|
RFI_TO_KERNEL
|
||||||
b .
|
b .
|
||||||
|
|
||||||
TRAMP_REAL_BEGIN(kvmppc_skip_Hinterrupt)
|
TRAMP_REAL_BEGIN(kvmppc_skip_Hinterrupt)
|
||||||
|
@ -1365,7 +1384,7 @@ TRAMP_REAL_BEGIN(kvmppc_skip_Hinterrupt)
|
||||||
addi r13, r13, 4
|
addi r13, r13, 4
|
||||||
mtspr SPRN_HSRR0, r13
|
mtspr SPRN_HSRR0, r13
|
||||||
GET_SCRATCH0(r13)
|
GET_SCRATCH0(r13)
|
||||||
hrfid
|
HRFI_TO_KERNEL
|
||||||
b .
|
b .
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1576,6 +1595,88 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
|
||||||
bl kernel_bad_stack
|
bl kernel_bad_stack
|
||||||
b 1b
|
b 1b
|
||||||
|
|
||||||
|
.globl rfi_flush_fallback
|
||||||
|
rfi_flush_fallback:
|
||||||
|
SET_SCRATCH0(r13);
|
||||||
|
GET_PACA(r13);
|
||||||
|
std r9,PACA_EXRFI+EX_R9(r13)
|
||||||
|
std r10,PACA_EXRFI+EX_R10(r13)
|
||||||
|
std r11,PACA_EXRFI+EX_R11(r13)
|
||||||
|
mfctr r9
|
||||||
|
ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13)
|
||||||
|
ld r11,PACA_L1D_FLUSH_SIZE(r13)
|
||||||
|
srdi r11,r11,(7 + 3) /* 128 byte lines, unrolled 8x */
|
||||||
|
mtctr r11
|
||||||
|
DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */
|
||||||
|
|
||||||
|
/* order ld/st prior to dcbt stop all streams with flushing */
|
||||||
|
sync
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The load adresses are at staggered offsets within cachelines,
|
||||||
|
* which suits some pipelines better (on others it should not
|
||||||
|
* hurt).
|
||||||
|
*/
|
||||||
|
1:
|
||||||
|
ld r11,(0x80 + 8)*0(r10)
|
||||||
|
ld r11,(0x80 + 8)*1(r10)
|
||||||
|
ld r11,(0x80 + 8)*2(r10)
|
||||||
|
ld r11,(0x80 + 8)*3(r10)
|
||||||
|
ld r11,(0x80 + 8)*4(r10)
|
||||||
|
ld r11,(0x80 + 8)*5(r10)
|
||||||
|
ld r11,(0x80 + 8)*6(r10)
|
||||||
|
ld r11,(0x80 + 8)*7(r10)
|
||||||
|
addi r10,r10,0x80*8
|
||||||
|
bdnz 1b
|
||||||
|
|
||||||
|
mtctr r9
|
||||||
|
ld r9,PACA_EXRFI+EX_R9(r13)
|
||||||
|
ld r10,PACA_EXRFI+EX_R10(r13)
|
||||||
|
ld r11,PACA_EXRFI+EX_R11(r13)
|
||||||
|
GET_SCRATCH0(r13);
|
||||||
|
rfid
|
||||||
|
|
||||||
|
.globl hrfi_flush_fallback
|
||||||
|
hrfi_flush_fallback:
|
||||||
|
SET_SCRATCH0(r13);
|
||||||
|
GET_PACA(r13);
|
||||||
|
std r9,PACA_EXRFI+EX_R9(r13)
|
||||||
|
std r10,PACA_EXRFI+EX_R10(r13)
|
||||||
|
std r11,PACA_EXRFI+EX_R11(r13)
|
||||||
|
mfctr r9
|
||||||
|
ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13)
|
||||||
|
ld r11,PACA_L1D_FLUSH_SIZE(r13)
|
||||||
|
srdi r11,r11,(7 + 3) /* 128 byte lines, unrolled 8x */
|
||||||
|
mtctr r11
|
||||||
|
DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */
|
||||||
|
|
||||||
|
/* order ld/st prior to dcbt stop all streams with flushing */
|
||||||
|
sync
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The load adresses are at staggered offsets within cachelines,
|
||||||
|
* which suits some pipelines better (on others it should not
|
||||||
|
* hurt).
|
||||||
|
*/
|
||||||
|
1:
|
||||||
|
ld r11,(0x80 + 8)*0(r10)
|
||||||
|
ld r11,(0x80 + 8)*1(r10)
|
||||||
|
ld r11,(0x80 + 8)*2(r10)
|
||||||
|
ld r11,(0x80 + 8)*3(r10)
|
||||||
|
ld r11,(0x80 + 8)*4(r10)
|
||||||
|
ld r11,(0x80 + 8)*5(r10)
|
||||||
|
ld r11,(0x80 + 8)*6(r10)
|
||||||
|
ld r11,(0x80 + 8)*7(r10)
|
||||||
|
addi r10,r10,0x80*8
|
||||||
|
bdnz 1b
|
||||||
|
|
||||||
|
mtctr r9
|
||||||
|
ld r9,PACA_EXRFI+EX_R9(r13)
|
||||||
|
ld r10,PACA_EXRFI+EX_R10(r13)
|
||||||
|
ld r11,PACA_EXRFI+EX_R11(r13)
|
||||||
|
GET_SCRATCH0(r13);
|
||||||
|
hrfid
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called from arch_local_irq_enable when an interrupt needs
|
* Called from arch_local_irq_enable when an interrupt needs
|
||||||
* to be resent. r3 contains 0x500, 0x900, 0xa00 or 0xe80 to indicate
|
* to be resent. r3 contains 0x500, 0x900, 0xa00 or 0xe80 to indicate
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/threads.h>
|
#include <linux/threads.h>
|
||||||
|
#include <asm/exception-64s.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
#include <asm/cputable.h>
|
#include <asm/cputable.h>
|
||||||
|
@ -178,7 +179,7 @@ _GLOBAL(pnv_powersave_common)
|
||||||
mtmsrd r6, 1 /* clear RI before setting SRR0/1 */
|
mtmsrd r6, 1 /* clear RI before setting SRR0/1 */
|
||||||
mtspr SPRN_SRR0, r5
|
mtspr SPRN_SRR0, r5
|
||||||
mtspr SPRN_SRR1, r7
|
mtspr SPRN_SRR1, r7
|
||||||
rfid
|
RFI_TO_KERNEL
|
||||||
|
|
||||||
.globl pnv_enter_arch207_idle_mode
|
.globl pnv_enter_arch207_idle_mode
|
||||||
pnv_enter_arch207_idle_mode:
|
pnv_enter_arch207_idle_mode:
|
||||||
|
@ -668,7 +669,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
|
||||||
mtcr r6
|
mtcr r6
|
||||||
mtspr SPRN_SRR1,r4
|
mtspr SPRN_SRR1,r4
|
||||||
mtspr SPRN_SRR0,r5
|
mtspr SPRN_SRR0,r5
|
||||||
rfid
|
RFI_TO_KERNEL
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* R3 here contains the value that will be returned to the caller
|
* R3 here contains the value that will be returned to the caller
|
||||||
|
@ -689,4 +690,4 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
|
||||||
mtcr r6
|
mtcr r6
|
||||||
mtspr SPRN_SRR1,r4
|
mtspr SPRN_SRR1,r4
|
||||||
mtspr SPRN_SRR0,r5
|
mtspr SPRN_SRR0,r5
|
||||||
rfid
|
RFI_TO_KERNEL
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include <linux/memblock.h>
|
#include <linux/memblock.h>
|
||||||
#include <linux/memory.h>
|
#include <linux/memory.h>
|
||||||
#include <linux/nmi.h>
|
#include <linux/nmi.h>
|
||||||
|
#include <linux/debugfs.h>
|
||||||
|
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/kdump.h>
|
#include <asm/kdump.h>
|
||||||
|
@ -678,4 +679,131 @@ static int __init disable_hardlockup_detector(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
early_initcall(disable_hardlockup_detector);
|
early_initcall(disable_hardlockup_detector);
|
||||||
|
|
||||||
|
#ifdef CONFIG_PPC_BOOK3S_64
|
||||||
|
static enum l1d_flush_type enabled_flush_types;
|
||||||
|
static void *l1d_flush_fallback_area;
|
||||||
|
static bool no_rfi_flush;
|
||||||
|
bool rfi_flush;
|
||||||
|
|
||||||
|
static int __init handle_no_rfi_flush(char *p)
|
||||||
|
{
|
||||||
|
pr_info("rfi-flush: disabled on command line.");
|
||||||
|
no_rfi_flush = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
early_param("no_rfi_flush", handle_no_rfi_flush);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The RFI flush is not KPTI, but because users will see doco that says to use
|
||||||
|
* nopti we hijack that option here to also disable the RFI flush.
|
||||||
|
*/
|
||||||
|
static int __init handle_no_pti(char *p)
|
||||||
|
{
|
||||||
|
pr_info("rfi-flush: disabling due to 'nopti' on command line.\n");
|
||||||
|
handle_no_rfi_flush(NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
early_param("nopti", handle_no_pti);
|
||||||
|
|
||||||
|
static void do_nothing(void *unused)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We don't need to do the flush explicitly, just enter+exit kernel is
|
||||||
|
* sufficient, the RFI exit handlers will do the right thing.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void rfi_flush_enable(bool enable)
|
||||||
|
{
|
||||||
|
if (rfi_flush == enable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (enable) {
|
||||||
|
do_rfi_flush_fixups(enabled_flush_types);
|
||||||
|
on_each_cpu(do_nothing, NULL, 1);
|
||||||
|
} else
|
||||||
|
do_rfi_flush_fixups(L1D_FLUSH_NONE);
|
||||||
|
|
||||||
|
rfi_flush = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_fallback_flush(void)
|
||||||
|
{
|
||||||
|
u64 l1d_size, limit;
|
||||||
|
int cpu;
|
||||||
|
|
||||||
|
l1d_size = ppc64_caches.dsize;
|
||||||
|
limit = min(safe_stack_limit(), ppc64_rma_size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Align to L1d size, and size it at 2x L1d size, to catch possible
|
||||||
|
* hardware prefetch runoff. We don't have a recipe for load patterns to
|
||||||
|
* reliably avoid the prefetcher.
|
||||||
|
*/
|
||||||
|
l1d_flush_fallback_area = __va(memblock_alloc_base(l1d_size * 2, l1d_size, limit));
|
||||||
|
memset(l1d_flush_fallback_area, 0, l1d_size * 2);
|
||||||
|
|
||||||
|
for_each_possible_cpu(cpu) {
|
||||||
|
paca[cpu].rfi_flush_fallback_area = l1d_flush_fallback_area;
|
||||||
|
paca[cpu].l1d_flush_size = l1d_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init setup_rfi_flush(enum l1d_flush_type types, bool enable)
|
||||||
|
{
|
||||||
|
if (types & L1D_FLUSH_FALLBACK) {
|
||||||
|
pr_info("rfi-flush: Using fallback displacement flush\n");
|
||||||
|
init_fallback_flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (types & L1D_FLUSH_ORI)
|
||||||
|
pr_info("rfi-flush: Using ori type flush\n");
|
||||||
|
|
||||||
|
if (types & L1D_FLUSH_MTTRIG)
|
||||||
|
pr_info("rfi-flush: Using mttrig type flush\n");
|
||||||
|
|
||||||
|
enabled_flush_types = types;
|
||||||
|
|
||||||
|
if (!no_rfi_flush)
|
||||||
|
rfi_flush_enable(enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_FS
|
||||||
|
static int rfi_flush_set(void *data, u64 val)
|
||||||
|
{
|
||||||
|
if (val == 1)
|
||||||
|
rfi_flush_enable(true);
|
||||||
|
else if (val == 0)
|
||||||
|
rfi_flush_enable(false);
|
||||||
|
else
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rfi_flush_get(void *data, u64 *val)
|
||||||
|
{
|
||||||
|
*val = rfi_flush ? 1 : 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_SIMPLE_ATTRIBUTE(fops_rfi_flush, rfi_flush_get, rfi_flush_set, "%llu\n");
|
||||||
|
|
||||||
|
static __init int rfi_flush_debugfs_init(void)
|
||||||
|
{
|
||||||
|
debugfs_create_file("rfi_flush", 0600, powerpc_debugfs_root, NULL, &fops_rfi_flush);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
device_initcall(rfi_flush_debugfs_init);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
if (rfi_flush)
|
||||||
|
return sprintf(buf, "Mitigation: RFI Flush\n");
|
||||||
|
|
||||||
|
return sprintf(buf, "Vulnerable\n");
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_PPC_BOOK3S_64 */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -132,6 +132,15 @@ SECTIONS
|
||||||
/* Read-only data */
|
/* Read-only data */
|
||||||
RODATA
|
RODATA
|
||||||
|
|
||||||
|
#ifdef CONFIG_PPC64
|
||||||
|
. = ALIGN(8);
|
||||||
|
__rfi_flush_fixup : AT(ADDR(__rfi_flush_fixup) - LOAD_OFFSET) {
|
||||||
|
__start___rfi_flush_fixup = .;
|
||||||
|
*(__rfi_flush_fixup)
|
||||||
|
__stop___rfi_flush_fixup = .;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
EXCEPTION_TABLE(0)
|
EXCEPTION_TABLE(0)
|
||||||
|
|
||||||
NOTES :kernel :notes
|
NOTES :kernel :notes
|
||||||
|
|
|
@ -65,7 +65,7 @@ _GLOBAL_TOC(kvmppc_hv_entry_trampoline)
|
||||||
mtmsrd r0,1 /* clear RI in MSR */
|
mtmsrd r0,1 /* clear RI in MSR */
|
||||||
mtsrr0 r5
|
mtsrr0 r5
|
||||||
mtsrr1 r6
|
mtsrr1 r6
|
||||||
RFI
|
RFI_TO_KERNEL
|
||||||
|
|
||||||
kvmppc_call_hv_entry:
|
kvmppc_call_hv_entry:
|
||||||
ld r4, HSTATE_KVM_VCPU(r13)
|
ld r4, HSTATE_KVM_VCPU(r13)
|
||||||
|
@ -171,7 +171,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
|
||||||
mtsrr0 r8
|
mtsrr0 r8
|
||||||
mtsrr1 r7
|
mtsrr1 r7
|
||||||
beq cr1, 13f /* machine check */
|
beq cr1, 13f /* machine check */
|
||||||
RFI
|
RFI_TO_KERNEL
|
||||||
|
|
||||||
/* On POWER7, we have external interrupts set to use HSRR0/1 */
|
/* On POWER7, we have external interrupts set to use HSRR0/1 */
|
||||||
11: mtspr SPRN_HSRR0, r8
|
11: mtspr SPRN_HSRR0, r8
|
||||||
|
@ -1018,8 +1018,7 @@ BEGIN_FTR_SECTION
|
||||||
END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
|
END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
|
||||||
ld r0, VCPU_GPR(R0)(r4)
|
ld r0, VCPU_GPR(R0)(r4)
|
||||||
ld r4, VCPU_GPR(R4)(r4)
|
ld r4, VCPU_GPR(R4)(r4)
|
||||||
|
HRFI_TO_GUEST
|
||||||
hrfid
|
|
||||||
b .
|
b .
|
||||||
|
|
||||||
secondary_too_late:
|
secondary_too_late:
|
||||||
|
|
|
@ -46,6 +46,9 @@
|
||||||
|
|
||||||
#define FUNC(name) name
|
#define FUNC(name) name
|
||||||
|
|
||||||
|
#define RFI_TO_KERNEL RFI
|
||||||
|
#define RFI_TO_GUEST RFI
|
||||||
|
|
||||||
.macro INTERRUPT_TRAMPOLINE intno
|
.macro INTERRUPT_TRAMPOLINE intno
|
||||||
|
|
||||||
.global kvmppc_trampoline_\intno
|
.global kvmppc_trampoline_\intno
|
||||||
|
@ -141,7 +144,7 @@ kvmppc_handler_skip_ins:
|
||||||
GET_SCRATCH0(r13)
|
GET_SCRATCH0(r13)
|
||||||
|
|
||||||
/* And get back into the code */
|
/* And get back into the code */
|
||||||
RFI
|
RFI_TO_KERNEL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -164,6 +167,6 @@ _GLOBAL_TOC(kvmppc_entry_trampoline)
|
||||||
ori r5, r5, MSR_EE
|
ori r5, r5, MSR_EE
|
||||||
mtsrr0 r7
|
mtsrr0 r7
|
||||||
mtsrr1 r6
|
mtsrr1 r6
|
||||||
RFI
|
RFI_TO_KERNEL
|
||||||
|
|
||||||
#include "book3s_segment.S"
|
#include "book3s_segment.S"
|
||||||
|
|
|
@ -156,7 +156,7 @@ no_dcbz32_on:
|
||||||
PPC_LL r9, SVCPU_R9(r3)
|
PPC_LL r9, SVCPU_R9(r3)
|
||||||
PPC_LL r3, (SVCPU_R3)(r3)
|
PPC_LL r3, (SVCPU_R3)(r3)
|
||||||
|
|
||||||
RFI
|
RFI_TO_GUEST
|
||||||
kvmppc_handler_trampoline_enter_end:
|
kvmppc_handler_trampoline_enter_end:
|
||||||
|
|
||||||
|
|
||||||
|
@ -389,5 +389,5 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
|
||||||
cmpwi r12, BOOK3S_INTERRUPT_DOORBELL
|
cmpwi r12, BOOK3S_INTERRUPT_DOORBELL
|
||||||
beqa BOOK3S_INTERRUPT_DOORBELL
|
beqa BOOK3S_INTERRUPT_DOORBELL
|
||||||
|
|
||||||
RFI
|
RFI_TO_KERNEL
|
||||||
kvmppc_handler_trampoline_exit_end:
|
kvmppc_handler_trampoline_exit_end:
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <asm/sections.h>
|
#include <asm/sections.h>
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
#include <asm/firmware.h>
|
#include <asm/firmware.h>
|
||||||
|
#include <asm/setup.h>
|
||||||
|
|
||||||
struct fixup_entry {
|
struct fixup_entry {
|
||||||
unsigned long mask;
|
unsigned long mask;
|
||||||
|
@ -115,6 +116,47 @@ void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PPC_BOOK3S_64
|
||||||
|
void do_rfi_flush_fixups(enum l1d_flush_type types)
|
||||||
|
{
|
||||||
|
unsigned int instrs[3], *dest;
|
||||||
|
long *start, *end;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
start = PTRRELOC(&__start___rfi_flush_fixup),
|
||||||
|
end = PTRRELOC(&__stop___rfi_flush_fixup);
|
||||||
|
|
||||||
|
instrs[0] = 0x60000000; /* nop */
|
||||||
|
instrs[1] = 0x60000000; /* nop */
|
||||||
|
instrs[2] = 0x60000000; /* nop */
|
||||||
|
|
||||||
|
if (types & L1D_FLUSH_FALLBACK)
|
||||||
|
/* b .+16 to fallback flush */
|
||||||
|
instrs[0] = 0x48000010;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
if (types & L1D_FLUSH_ORI) {
|
||||||
|
instrs[i++] = 0x63ff0000; /* ori 31,31,0 speculation barrier */
|
||||||
|
instrs[i++] = 0x63de0000; /* ori 30,30,0 L1d flush*/
|
||||||
|
}
|
||||||
|
|
||||||
|
if (types & L1D_FLUSH_MTTRIG)
|
||||||
|
instrs[i++] = 0x7c12dba6; /* mtspr TRIG2,r0 (SPR #882) */
|
||||||
|
|
||||||
|
for (i = 0; start < end; start++, i++) {
|
||||||
|
dest = (void *)start + *start;
|
||||||
|
|
||||||
|
pr_devel("patching dest %lx\n", (unsigned long)dest);
|
||||||
|
|
||||||
|
patch_instruction(dest, instrs[0]);
|
||||||
|
patch_instruction(dest + 1, instrs[1]);
|
||||||
|
patch_instruction(dest + 2, instrs[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
printk(KERN_DEBUG "rfi-flush: patched %d locations\n", i);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_PPC_BOOK3S_64 */
|
||||||
|
|
||||||
void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
|
void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
|
||||||
{
|
{
|
||||||
long *start, *end;
|
long *start, *end;
|
||||||
|
|
|
@ -1381,7 +1381,7 @@ static int collect_events(struct perf_event *group, int max_count,
|
||||||
int n = 0;
|
int n = 0;
|
||||||
struct perf_event *event;
|
struct perf_event *event;
|
||||||
|
|
||||||
if (!is_software_event(group)) {
|
if (group->pmu->task_ctx_nr == perf_hw_context) {
|
||||||
if (n >= max_count)
|
if (n >= max_count)
|
||||||
return -1;
|
return -1;
|
||||||
ctrs[n] = group;
|
ctrs[n] = group;
|
||||||
|
@ -1389,7 +1389,7 @@ static int collect_events(struct perf_event *group, int max_count,
|
||||||
events[n++] = group->hw.config;
|
events[n++] = group->hw.config;
|
||||||
}
|
}
|
||||||
list_for_each_entry(event, &group->sibling_list, group_entry) {
|
list_for_each_entry(event, &group->sibling_list, group_entry) {
|
||||||
if (!is_software_event(event) &&
|
if (event->pmu->task_ctx_nr == perf_hw_context &&
|
||||||
event->state != PERF_EVENT_STATE_OFF) {
|
event->state != PERF_EVENT_STATE_OFF) {
|
||||||
if (n >= max_count)
|
if (n >= max_count)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -35,13 +35,63 @@
|
||||||
#include <asm/opal.h>
|
#include <asm/opal.h>
|
||||||
#include <asm/kexec.h>
|
#include <asm/kexec.h>
|
||||||
#include <asm/smp.h>
|
#include <asm/smp.h>
|
||||||
|
#include <asm/tm.h>
|
||||||
|
#include <asm/setup.h>
|
||||||
|
|
||||||
#include "powernv.h"
|
#include "powernv.h"
|
||||||
|
|
||||||
|
static void pnv_setup_rfi_flush(void)
|
||||||
|
{
|
||||||
|
struct device_node *np, *fw_features;
|
||||||
|
enum l1d_flush_type type;
|
||||||
|
int enable;
|
||||||
|
|
||||||
|
/* Default to fallback in case fw-features are not available */
|
||||||
|
type = L1D_FLUSH_FALLBACK;
|
||||||
|
enable = 1;
|
||||||
|
|
||||||
|
np = of_find_node_by_name(NULL, "ibm,opal");
|
||||||
|
fw_features = of_get_child_by_name(np, "fw-features");
|
||||||
|
of_node_put(np);
|
||||||
|
|
||||||
|
if (fw_features) {
|
||||||
|
np = of_get_child_by_name(fw_features, "inst-l1d-flush-trig2");
|
||||||
|
if (np && of_property_read_bool(np, "enabled"))
|
||||||
|
type = L1D_FLUSH_MTTRIG;
|
||||||
|
|
||||||
|
of_node_put(np);
|
||||||
|
|
||||||
|
np = of_get_child_by_name(fw_features, "inst-l1d-flush-ori30,30,0");
|
||||||
|
if (np && of_property_read_bool(np, "enabled"))
|
||||||
|
type = L1D_FLUSH_ORI;
|
||||||
|
|
||||||
|
of_node_put(np);
|
||||||
|
|
||||||
|
/* Enable unless firmware says NOT to */
|
||||||
|
enable = 2;
|
||||||
|
np = of_get_child_by_name(fw_features, "needs-l1d-flush-msr-hv-1-to-0");
|
||||||
|
if (np && of_property_read_bool(np, "disabled"))
|
||||||
|
enable--;
|
||||||
|
|
||||||
|
of_node_put(np);
|
||||||
|
|
||||||
|
np = of_get_child_by_name(fw_features, "needs-l1d-flush-msr-pr-0-to-1");
|
||||||
|
if (np && of_property_read_bool(np, "disabled"))
|
||||||
|
enable--;
|
||||||
|
|
||||||
|
of_node_put(np);
|
||||||
|
of_node_put(fw_features);
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_rfi_flush(type, enable > 0);
|
||||||
|
}
|
||||||
|
|
||||||
static void __init pnv_setup_arch(void)
|
static void __init pnv_setup_arch(void)
|
||||||
{
|
{
|
||||||
set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT);
|
set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT);
|
||||||
|
|
||||||
|
pnv_setup_rfi_flush();
|
||||||
|
|
||||||
/* Initialize SMP */
|
/* Initialize SMP */
|
||||||
pnv_smp_init();
|
pnv_smp_init();
|
||||||
|
|
||||||
|
|
|
@ -450,6 +450,39 @@ static void __init find_and_init_phbs(void)
|
||||||
of_pci_check_probe_only();
|
of_pci_check_probe_only();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pseries_setup_rfi_flush(void)
|
||||||
|
{
|
||||||
|
struct h_cpu_char_result result;
|
||||||
|
enum l1d_flush_type types;
|
||||||
|
bool enable;
|
||||||
|
long rc;
|
||||||
|
|
||||||
|
/* Enable by default */
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
rc = plpar_get_cpu_characteristics(&result);
|
||||||
|
if (rc == H_SUCCESS) {
|
||||||
|
types = L1D_FLUSH_NONE;
|
||||||
|
|
||||||
|
if (result.character & H_CPU_CHAR_L1D_FLUSH_TRIG2)
|
||||||
|
types |= L1D_FLUSH_MTTRIG;
|
||||||
|
if (result.character & H_CPU_CHAR_L1D_FLUSH_ORI30)
|
||||||
|
types |= L1D_FLUSH_ORI;
|
||||||
|
|
||||||
|
/* Use fallback if nothing set in hcall */
|
||||||
|
if (types == L1D_FLUSH_NONE)
|
||||||
|
types = L1D_FLUSH_FALLBACK;
|
||||||
|
|
||||||
|
if (!(result.behaviour & H_CPU_BEHAV_L1D_FLUSH_PR))
|
||||||
|
enable = false;
|
||||||
|
} else {
|
||||||
|
/* Default to fallback if case hcall is not available */
|
||||||
|
types = L1D_FLUSH_FALLBACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_rfi_flush(types, enable);
|
||||||
|
}
|
||||||
|
|
||||||
static void __init pSeries_setup_arch(void)
|
static void __init pSeries_setup_arch(void)
|
||||||
{
|
{
|
||||||
set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT);
|
set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT);
|
||||||
|
@ -467,6 +500,8 @@ static void __init pSeries_setup_arch(void)
|
||||||
|
|
||||||
fwnmi_init();
|
fwnmi_init();
|
||||||
|
|
||||||
|
pseries_setup_rfi_flush();
|
||||||
|
|
||||||
/* By default, only probe PCI (can be overridden by rtas_pci) */
|
/* By default, only probe PCI (can be overridden by rtas_pci) */
|
||||||
pci_add_flags(PCI_PROBE_ONLY);
|
pci_add_flags(PCI_PROBE_ONLY);
|
||||||
|
|
||||||
|
|
|
@ -238,6 +238,7 @@ static struct shash_alg crc32_vx_algs[] = {
|
||||||
.cra_name = "crc32",
|
.cra_name = "crc32",
|
||||||
.cra_driver_name = "crc32-vx",
|
.cra_driver_name = "crc32-vx",
|
||||||
.cra_priority = 200,
|
.cra_priority = 200,
|
||||||
|
.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
|
||||||
.cra_blocksize = CRC32_BLOCK_SIZE,
|
.cra_blocksize = CRC32_BLOCK_SIZE,
|
||||||
.cra_ctxsize = sizeof(struct crc_ctx),
|
.cra_ctxsize = sizeof(struct crc_ctx),
|
||||||
.cra_module = THIS_MODULE,
|
.cra_module = THIS_MODULE,
|
||||||
|
@ -258,6 +259,7 @@ static struct shash_alg crc32_vx_algs[] = {
|
||||||
.cra_name = "crc32be",
|
.cra_name = "crc32be",
|
||||||
.cra_driver_name = "crc32be-vx",
|
.cra_driver_name = "crc32be-vx",
|
||||||
.cra_priority = 200,
|
.cra_priority = 200,
|
||||||
|
.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
|
||||||
.cra_blocksize = CRC32_BLOCK_SIZE,
|
.cra_blocksize = CRC32_BLOCK_SIZE,
|
||||||
.cra_ctxsize = sizeof(struct crc_ctx),
|
.cra_ctxsize = sizeof(struct crc_ctx),
|
||||||
.cra_module = THIS_MODULE,
|
.cra_module = THIS_MODULE,
|
||||||
|
@ -278,6 +280,7 @@ static struct shash_alg crc32_vx_algs[] = {
|
||||||
.cra_name = "crc32c",
|
.cra_name = "crc32c",
|
||||||
.cra_driver_name = "crc32c-vx",
|
.cra_driver_name = "crc32c-vx",
|
||||||
.cra_priority = 200,
|
.cra_priority = 200,
|
||||||
|
.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
|
||||||
.cra_blocksize = CRC32_BLOCK_SIZE,
|
.cra_blocksize = CRC32_BLOCK_SIZE,
|
||||||
.cra_ctxsize = sizeof(struct crc_ctx),
|
.cra_ctxsize = sizeof(struct crc_ctx),
|
||||||
.cra_module = THIS_MODULE,
|
.cra_module = THIS_MODULE,
|
||||||
|
|
|
@ -110,7 +110,7 @@ COMPAT_SYSCALL_DEFINE2(s390_setregid16, u16, rgid, u16, egid)
|
||||||
|
|
||||||
COMPAT_SYSCALL_DEFINE1(s390_setgid16, u16, gid)
|
COMPAT_SYSCALL_DEFINE1(s390_setgid16, u16, gid)
|
||||||
{
|
{
|
||||||
return sys_setgid((gid_t)gid);
|
return sys_setgid(low2highgid(gid));
|
||||||
}
|
}
|
||||||
|
|
||||||
COMPAT_SYSCALL_DEFINE2(s390_setreuid16, u16, ruid, u16, euid)
|
COMPAT_SYSCALL_DEFINE2(s390_setreuid16, u16, ruid, u16, euid)
|
||||||
|
@ -120,7 +120,7 @@ COMPAT_SYSCALL_DEFINE2(s390_setreuid16, u16, ruid, u16, euid)
|
||||||
|
|
||||||
COMPAT_SYSCALL_DEFINE1(s390_setuid16, u16, uid)
|
COMPAT_SYSCALL_DEFINE1(s390_setuid16, u16, uid)
|
||||||
{
|
{
|
||||||
return sys_setuid((uid_t)uid);
|
return sys_setuid(low2highuid(uid));
|
||||||
}
|
}
|
||||||
|
|
||||||
COMPAT_SYSCALL_DEFINE3(s390_setresuid16, u16, ruid, u16, euid, u16, suid)
|
COMPAT_SYSCALL_DEFINE3(s390_setresuid16, u16, ruid, u16, euid, u16, suid)
|
||||||
|
@ -173,12 +173,12 @@ COMPAT_SYSCALL_DEFINE3(s390_getresgid16, u16 __user *, rgidp,
|
||||||
|
|
||||||
COMPAT_SYSCALL_DEFINE1(s390_setfsuid16, u16, uid)
|
COMPAT_SYSCALL_DEFINE1(s390_setfsuid16, u16, uid)
|
||||||
{
|
{
|
||||||
return sys_setfsuid((uid_t)uid);
|
return sys_setfsuid(low2highuid(uid));
|
||||||
}
|
}
|
||||||
|
|
||||||
COMPAT_SYSCALL_DEFINE1(s390_setfsgid16, u16, gid)
|
COMPAT_SYSCALL_DEFINE1(s390_setfsgid16, u16, gid)
|
||||||
{
|
{
|
||||||
return sys_setfsgid((gid_t)gid);
|
return sys_setfsgid(low2highgid(gid));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int groups16_to_user(u16 __user *grouplist, struct group_info *group_info)
|
static int groups16_to_user(u16 __user *grouplist, struct group_info *group_info)
|
||||||
|
|
|
@ -607,7 +607,8 @@ asmlinkage void do_divide_error(unsigned long r4)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
force_sig_info(SIGFPE, &info, current);
|
info.si_signo = SIGFPE;
|
||||||
|
force_sig_info(info.si_signo, &info, current);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -133,6 +133,7 @@ static struct shash_alg alg = {
|
||||||
.cra_name = "crc32c",
|
.cra_name = "crc32c",
|
||||||
.cra_driver_name = "crc32c-sparc64",
|
.cra_driver_name = "crc32c-sparc64",
|
||||||
.cra_priority = SPARC_CR_OPCODE_PRIORITY,
|
.cra_priority = SPARC_CR_OPCODE_PRIORITY,
|
||||||
|
.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
|
||||||
.cra_blocksize = CHKSUM_BLOCK_SIZE,
|
.cra_blocksize = CHKSUM_BLOCK_SIZE,
|
||||||
.cra_ctxsize = sizeof(u32),
|
.cra_ctxsize = sizeof(u32),
|
||||||
.cra_alignmask = 7,
|
.cra_alignmask = 7,
|
||||||
|
|
|
@ -117,7 +117,7 @@ archheaders:
|
||||||
archprepare: include/generated/user_constants.h
|
archprepare: include/generated/user_constants.h
|
||||||
|
|
||||||
LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static
|
LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static
|
||||||
LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib
|
LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib $(call cc-option, -no-pie)
|
||||||
|
|
||||||
CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,) \
|
CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,) \
|
||||||
$(call cc-option, -fno-stack-protector,) \
|
$(call cc-option, -fno-stack-protector,) \
|
||||||
|
|
|
@ -64,6 +64,7 @@ config X86
|
||||||
select GENERIC_CLOCKEVENTS_MIN_ADJUST
|
select GENERIC_CLOCKEVENTS_MIN_ADJUST
|
||||||
select GENERIC_CMOS_UPDATE
|
select GENERIC_CMOS_UPDATE
|
||||||
select GENERIC_CPU_AUTOPROBE
|
select GENERIC_CPU_AUTOPROBE
|
||||||
|
select GENERIC_CPU_VULNERABILITIES
|
||||||
select GENERIC_EARLY_IOREMAP
|
select GENERIC_EARLY_IOREMAP
|
||||||
select GENERIC_FIND_FIRST_BIT
|
select GENERIC_FIND_FIRST_BIT
|
||||||
select GENERIC_IOMAP
|
select GENERIC_IOMAP
|
||||||
|
@ -407,6 +408,19 @@ config GOLDFISH
|
||||||
def_bool y
|
def_bool y
|
||||||
depends on X86_GOLDFISH
|
depends on X86_GOLDFISH
|
||||||
|
|
||||||
|
config RETPOLINE
|
||||||
|
bool "Avoid speculative indirect branches in kernel"
|
||||||
|
default y
|
||||||
|
---help---
|
||||||
|
Compile kernel with the retpoline compiler options to guard against
|
||||||
|
kernel-to-user data leaks by avoiding speculative indirect
|
||||||
|
branches. Requires a compiler with -mindirect-branch=thunk-extern
|
||||||
|
support for full protection. The kernel may run slower.
|
||||||
|
|
||||||
|
Without compiler support, at least indirect branches in assembler
|
||||||
|
code are eliminated. Since this includes the syscall entry path,
|
||||||
|
it is not entirely pointless.
|
||||||
|
|
||||||
if X86_32
|
if X86_32
|
||||||
config X86_EXTENDED_PLATFORM
|
config X86_EXTENDED_PLATFORM
|
||||||
bool "Support for extended (non-PC) x86 platforms"
|
bool "Support for extended (non-PC) x86 platforms"
|
||||||
|
@ -1043,7 +1057,7 @@ config X86_MCE_THRESHOLD
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
config X86_MCE_INJECT
|
config X86_MCE_INJECT
|
||||||
depends on X86_MCE
|
depends on X86_MCE && X86_LOCAL_APIC
|
||||||
tristate "Machine check injector support"
|
tristate "Machine check injector support"
|
||||||
---help---
|
---help---
|
||||||
Provide support for injecting machine checks for testing purposes.
|
Provide support for injecting machine checks for testing purposes.
|
||||||
|
|
|
@ -352,6 +352,7 @@ config X86_DEBUG_FPU
|
||||||
|
|
||||||
config PUNIT_ATOM_DEBUG
|
config PUNIT_ATOM_DEBUG
|
||||||
tristate "ATOM Punit debug driver"
|
tristate "ATOM Punit debug driver"
|
||||||
|
depends on PCI
|
||||||
select DEBUG_FS
|
select DEBUG_FS
|
||||||
select IOSF_MBI
|
select IOSF_MBI
|
||||||
---help---
|
---help---
|
||||||
|
|
|
@ -182,6 +182,14 @@ KBUILD_CFLAGS += -fno-asynchronous-unwind-tables
|
||||||
KBUILD_CFLAGS += $(mflags-y)
|
KBUILD_CFLAGS += $(mflags-y)
|
||||||
KBUILD_AFLAGS += $(mflags-y)
|
KBUILD_AFLAGS += $(mflags-y)
|
||||||
|
|
||||||
|
# Avoid indirect branches in kernel to deal with Spectre
|
||||||
|
ifdef CONFIG_RETPOLINE
|
||||||
|
RETPOLINE_CFLAGS += $(call cc-option,-mindirect-branch=thunk-extern -mindirect-branch-register)
|
||||||
|
ifneq ($(RETPOLINE_CFLAGS),)
|
||||||
|
KBUILD_CFLAGS += $(RETPOLINE_CFLAGS) -DRETPOLINE
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
archscripts: scripts_basic
|
archscripts: scripts_basic
|
||||||
$(Q)$(MAKE) $(build)=arch/x86/tools relocs
|
$(Q)$(MAKE) $(build)=arch/x86/tools relocs
|
||||||
|
|
||||||
|
|
|
@ -73,12 +73,13 @@ UBSAN_SANITIZE := n
|
||||||
$(obj)/bzImage: asflags-y := $(SVGA_MODE)
|
$(obj)/bzImage: asflags-y := $(SVGA_MODE)
|
||||||
|
|
||||||
quiet_cmd_image = BUILD $@
|
quiet_cmd_image = BUILD $@
|
||||||
|
silent_redirect_image = >/dev/null
|
||||||
cmd_image = $(obj)/tools/build $(obj)/setup.bin $(obj)/vmlinux.bin \
|
cmd_image = $(obj)/tools/build $(obj)/setup.bin $(obj)/vmlinux.bin \
|
||||||
$(obj)/zoffset.h $@
|
$(obj)/zoffset.h $@ $($(quiet)redirect_image)
|
||||||
|
|
||||||
$(obj)/bzImage: $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/tools/build FORCE
|
$(obj)/bzImage: $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/tools/build FORCE
|
||||||
$(call if_changed,image)
|
$(call if_changed,image)
|
||||||
@echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
|
@$(kecho) 'Kernel: $@ is ready' ' (#'`cat .version`')'
|
||||||
|
|
||||||
OBJCOPYFLAGS_vmlinux.bin := -O binary -R .note -R .comment -S
|
OBJCOPYFLAGS_vmlinux.bin := -O binary -R .note -R .comment -S
|
||||||
$(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
|
$(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <linux/linkage.h>
|
#include <linux/linkage.h>
|
||||||
#include <asm/inst.h>
|
#include <asm/inst.h>
|
||||||
#include <asm/frame.h>
|
#include <asm/frame.h>
|
||||||
|
#include <asm/nospec-branch.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following macros are used to move an (un)aligned 16 byte value to/from
|
* The following macros are used to move an (un)aligned 16 byte value to/from
|
||||||
|
@ -2734,7 +2735,7 @@ ENTRY(aesni_xts_crypt8)
|
||||||
pxor INC, STATE4
|
pxor INC, STATE4
|
||||||
movdqu IV, 0x30(OUTP)
|
movdqu IV, 0x30(OUTP)
|
||||||
|
|
||||||
call *%r11
|
CALL_NOSPEC %r11
|
||||||
|
|
||||||
movdqu 0x00(OUTP), INC
|
movdqu 0x00(OUTP), INC
|
||||||
pxor INC, STATE1
|
pxor INC, STATE1
|
||||||
|
@ -2779,7 +2780,7 @@ ENTRY(aesni_xts_crypt8)
|
||||||
_aesni_gf128mul_x_ble()
|
_aesni_gf128mul_x_ble()
|
||||||
movups IV, (IVP)
|
movups IV, (IVP)
|
||||||
|
|
||||||
call *%r11
|
CALL_NOSPEC %r11
|
||||||
|
|
||||||
movdqu 0x40(OUTP), INC
|
movdqu 0x40(OUTP), INC
|
||||||
pxor INC, STATE1
|
pxor INC, STATE1
|
||||||
|
|
|
@ -906,7 +906,7 @@ static int helper_rfc4106_encrypt(struct aead_request *req)
|
||||||
|
|
||||||
if (sg_is_last(req->src) &&
|
if (sg_is_last(req->src) &&
|
||||||
req->src->offset + req->src->length <= PAGE_SIZE &&
|
req->src->offset + req->src->length <= PAGE_SIZE &&
|
||||||
sg_is_last(req->dst) &&
|
+ sg_is_last(req->dst) && req->dst->length &&
|
||||||
req->dst->offset + req->dst->length <= PAGE_SIZE) {
|
req->dst->offset + req->dst->length <= PAGE_SIZE) {
|
||||||
one_entry_in_sg = 1;
|
one_entry_in_sg = 1;
|
||||||
scatterwalk_start(&src_sg_walk, req->src);
|
scatterwalk_start(&src_sg_walk, req->src);
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include <linux/linkage.h>
|
#include <linux/linkage.h>
|
||||||
#include <asm/frame.h>
|
#include <asm/frame.h>
|
||||||
|
#include <asm/nospec-branch.h>
|
||||||
|
|
||||||
#define CAMELLIA_TABLE_BYTE_LEN 272
|
#define CAMELLIA_TABLE_BYTE_LEN 272
|
||||||
|
|
||||||
|
@ -1224,7 +1225,7 @@ camellia_xts_crypt_16way:
|
||||||
vpxor 14 * 16(%rax), %xmm15, %xmm14;
|
vpxor 14 * 16(%rax), %xmm15, %xmm14;
|
||||||
vpxor 15 * 16(%rax), %xmm15, %xmm15;
|
vpxor 15 * 16(%rax), %xmm15, %xmm15;
|
||||||
|
|
||||||
call *%r9;
|
CALL_NOSPEC %r9;
|
||||||
|
|
||||||
addq $(16 * 16), %rsp;
|
addq $(16 * 16), %rsp;
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include <linux/linkage.h>
|
#include <linux/linkage.h>
|
||||||
#include <asm/frame.h>
|
#include <asm/frame.h>
|
||||||
|
#include <asm/nospec-branch.h>
|
||||||
|
|
||||||
#define CAMELLIA_TABLE_BYTE_LEN 272
|
#define CAMELLIA_TABLE_BYTE_LEN 272
|
||||||
|
|
||||||
|
@ -1337,7 +1338,7 @@ camellia_xts_crypt_32way:
|
||||||
vpxor 14 * 32(%rax), %ymm15, %ymm14;
|
vpxor 14 * 32(%rax), %ymm15, %ymm14;
|
||||||
vpxor 15 * 32(%rax), %ymm15, %ymm15;
|
vpxor 15 * 32(%rax), %ymm15, %ymm15;
|
||||||
|
|
||||||
call *%r9;
|
CALL_NOSPEC %r9;
|
||||||
|
|
||||||
addq $(16 * 32), %rsp;
|
addq $(16 * 32), %rsp;
|
||||||
|
|
||||||
|
|
|
@ -162,6 +162,7 @@ static struct shash_alg alg = {
|
||||||
.cra_name = "crc32",
|
.cra_name = "crc32",
|
||||||
.cra_driver_name = "crc32-pclmul",
|
.cra_driver_name = "crc32-pclmul",
|
||||||
.cra_priority = 200,
|
.cra_priority = 200,
|
||||||
|
.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
|
||||||
.cra_blocksize = CHKSUM_BLOCK_SIZE,
|
.cra_blocksize = CHKSUM_BLOCK_SIZE,
|
||||||
.cra_ctxsize = sizeof(u32),
|
.cra_ctxsize = sizeof(u32),
|
||||||
.cra_module = THIS_MODULE,
|
.cra_module = THIS_MODULE,
|
||||||
|
|
|
@ -239,6 +239,7 @@ static struct shash_alg alg = {
|
||||||
.cra_name = "crc32c",
|
.cra_name = "crc32c",
|
||||||
.cra_driver_name = "crc32c-intel",
|
.cra_driver_name = "crc32c-intel",
|
||||||
.cra_priority = 200,
|
.cra_priority = 200,
|
||||||
|
.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
|
||||||
.cra_blocksize = CHKSUM_BLOCK_SIZE,
|
.cra_blocksize = CHKSUM_BLOCK_SIZE,
|
||||||
.cra_ctxsize = sizeof(u32),
|
.cra_ctxsize = sizeof(u32),
|
||||||
.cra_module = THIS_MODULE,
|
.cra_module = THIS_MODULE,
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
|
|
||||||
#include <asm/inst.h>
|
#include <asm/inst.h>
|
||||||
#include <linux/linkage.h>
|
#include <linux/linkage.h>
|
||||||
|
#include <asm/nospec-branch.h>
|
||||||
|
|
||||||
## ISCSI CRC 32 Implementation with crc32 and pclmulqdq Instruction
|
## ISCSI CRC 32 Implementation with crc32 and pclmulqdq Instruction
|
||||||
|
|
||||||
|
@ -172,7 +173,7 @@ continue_block:
|
||||||
movzxw (bufp, %rax, 2), len
|
movzxw (bufp, %rax, 2), len
|
||||||
lea crc_array(%rip), bufp
|
lea crc_array(%rip), bufp
|
||||||
lea (bufp, len, 1), bufp
|
lea (bufp, len, 1), bufp
|
||||||
jmp *bufp
|
JMP_NOSPEC bufp
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
## 2a) PROCESS FULL BLOCKS:
|
## 2a) PROCESS FULL BLOCKS:
|
||||||
|
|
|
@ -164,7 +164,6 @@ static struct shash_alg alg = {
|
||||||
.init = poly1305_simd_init,
|
.init = poly1305_simd_init,
|
||||||
.update = poly1305_simd_update,
|
.update = poly1305_simd_update,
|
||||||
.final = crypto_poly1305_final,
|
.final = crypto_poly1305_final,
|
||||||
.setkey = crypto_poly1305_setkey,
|
|
||||||
.descsize = sizeof(struct poly1305_simd_desc_ctx),
|
.descsize = sizeof(struct poly1305_simd_desc_ctx),
|
||||||
.base = {
|
.base = {
|
||||||
.cra_name = "poly1305",
|
.cra_name = "poly1305",
|
||||||
|
|
|
@ -57,10 +57,12 @@ void sha512_mb_mgr_init_avx2(struct sha512_mb_mgr *state)
|
||||||
{
|
{
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
|
|
||||||
state->lens[0] = 0;
|
/* initially all lanes are unused */
|
||||||
state->lens[1] = 1;
|
state->lens[0] = 0xFFFFFFFF00000000;
|
||||||
state->lens[2] = 2;
|
state->lens[1] = 0xFFFFFFFF00000001;
|
||||||
state->lens[3] = 3;
|
state->lens[2] = 0xFFFFFFFF00000002;
|
||||||
|
state->lens[3] = 0xFFFFFFFF00000003;
|
||||||
|
|
||||||
state->unused_lanes = 0xFF03020100;
|
state->unused_lanes = 0xFF03020100;
|
||||||
for (j = 0; j < 4; j++)
|
for (j = 0; j < 4; j++)
|
||||||
state->ldata[j].job_in_lane = NULL;
|
state->ldata[j].job_in_lane = NULL;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue