mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 06:10:53 +07:00
Merge branch 'for-4.16/nfit' into libnvdimm-for-next
This commit is contained in:
commit
ee95f4059a
1
.mailmap
1
.mailmap
@ -107,6 +107,7 @@ Linus Lüssing <linus.luessing@c0d3.blue> <linus.luessing@ascom.ch>
|
||||
Maciej W. Rozycki <macro@mips.com> <macro@imgtec.com>
|
||||
Marcin Nowakowski <marcin.nowakowski@mips.com> <marcin.nowakowski@imgtec.com>
|
||||
Mark Brown <broonie@sirena.org.uk>
|
||||
Mark Yao <markyao0591@gmail.com> <mark.yao@rock-chips.com>
|
||||
Martin Kepplinger <martink@posteo.de> <martin.kepplinger@theobroma-systems.com>
|
||||
Martin Kepplinger <martink@posteo.de> <martin.kepplinger@ginzinger.com>
|
||||
Matthieu CASTET <castet.matthieu@free.fr>
|
||||
|
@ -375,3 +375,19 @@ Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
|
||||
Description: information about CPUs heterogeneity.
|
||||
|
||||
cpu_capacity: capacity of 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
|
||||
|
@ -114,7 +114,6 @@
|
||||
This facility can be used to prevent such uncontrolled
|
||||
GPE floodings.
|
||||
Format: <int>
|
||||
Support masking of GPEs numbered from 0x00 to 0x7f.
|
||||
|
||||
acpi_no_auto_serialize [HW,ACPI]
|
||||
Disable auto-serialization of AML methods
|
||||
@ -713,9 +712,6 @@
|
||||
It will be ignored when crashkernel=X,high is not used
|
||||
or memory reserved is below 4G.
|
||||
|
||||
crossrelease_fullstack
|
||||
[KNL] Allow to record full stack trace in cross-release
|
||||
|
||||
cryptomgr.notests
|
||||
[KNL] Disable crypto self-tests
|
||||
|
||||
@ -2626,6 +2622,11 @@
|
||||
nosmt [KNL,S390] Disable symmetric multithreading (SMT).
|
||||
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
|
||||
and restore using xsave. The kernel will fallback to
|
||||
enabling legacy floating-point and sse state.
|
||||
@ -2712,8 +2713,6 @@
|
||||
steal time is computed, but won't influence scheduler
|
||||
behaviour
|
||||
|
||||
nopti [X86-64] Disable kernel page table isolation
|
||||
|
||||
nolapic [X86-32,APIC] Do not enable or use the local APIC.
|
||||
|
||||
nolapic_timer [X86-32,APIC] Do not use the local APIC timer.
|
||||
@ -3100,6 +3099,12 @@
|
||||
pcie_scan_all Scan all possible PCIe devices. Otherwise we
|
||||
only look for one device below a PCIe downstream
|
||||
port.
|
||||
big_root_window Try to add a big 64bit memory window to the PCIe
|
||||
root complex on AMD CPUs. Some GFX hardware
|
||||
can resize a BAR to allow access to all VRAM.
|
||||
Adding the window is slightly risky (it may
|
||||
conflict with unreported devices), so this
|
||||
taints the kernel.
|
||||
|
||||
pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power
|
||||
Management.
|
||||
@ -3288,11 +3293,20 @@
|
||||
pt. [PARIDE]
|
||||
See Documentation/blockdev/paride.txt.
|
||||
|
||||
pti= [X86_64]
|
||||
Control user/kernel address space isolation:
|
||||
on - enable
|
||||
off - disable
|
||||
auto - default setting
|
||||
pti= [X86_64] Control Page Table Isolation of user and
|
||||
kernel address spaces. Disabling this feature
|
||||
removes hardening, but improves performance of
|
||||
system calls and interrupts.
|
||||
|
||||
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=
|
||||
[KNL] Number of legacy pty's. Overwrites compiled-in
|
||||
@ -3943,6 +3957,29 @@
|
||||
sonypi.*= [HW] Sony Programmable I/O Control Device driver
|
||||
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_fio_base=
|
||||
spia_pedr=
|
||||
|
@ -25,8 +25,8 @@ available from the following download page. At least "mkfs.nilfs2",
|
||||
cleaner or garbage collector) are required. Details on the tools are
|
||||
described in the man pages included in the package.
|
||||
|
||||
Project web page: http://nilfs.sourceforge.net/
|
||||
Download page: http://nilfs.sourceforge.net/en/download.html
|
||||
Project web page: https://nilfs.sourceforge.io/
|
||||
Download page: https://nilfs.sourceforge.io/en/download.html
|
||||
List info: http://vger.kernel.org/vger-lists.html#linux-nilfs
|
||||
|
||||
Caveats
|
||||
|
@ -341,10 +341,7 @@ GuC
|
||||
GuC-specific firmware loader
|
||||
----------------------------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/i915/intel_guc_loader.c
|
||||
:doc: GuC-specific firmware loader
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/i915/intel_guc_loader.c
|
||||
.. kernel-doc:: drivers/gpu/drm/i915/intel_guc_fw.c
|
||||
:internal:
|
||||
|
||||
GuC-based command submission
|
||||
|
@ -200,10 +200,14 @@ module state. Dependency expressions have the following syntax:
|
||||
<expr> ::= <symbol> (1)
|
||||
<symbol> '=' <symbol> (2)
|
||||
<symbol> '!=' <symbol> (3)
|
||||
'(' <expr> ')' (4)
|
||||
'!' <expr> (5)
|
||||
<expr> '&&' <expr> (6)
|
||||
<expr> '||' <expr> (7)
|
||||
<symbol1> '<' <symbol2> (4)
|
||||
<symbol1> '>' <symbol2> (4)
|
||||
<symbol1> '<=' <symbol2> (4)
|
||||
<symbol1> '>=' <symbol2> (4)
|
||||
'(' <expr> ')' (5)
|
||||
'!' <expr> (6)
|
||||
<expr> '&&' <expr> (7)
|
||||
<expr> '||' <expr> (8)
|
||||
|
||||
Expressions are listed in decreasing order of precedence.
|
||||
|
||||
@ -214,10 +218,13 @@ Expressions are listed in decreasing order of precedence.
|
||||
otherwise 'n'.
|
||||
(3) If the values of both symbols are equal, it returns 'n',
|
||||
otherwise 'y'.
|
||||
(4) Returns the value of the expression. Used to override precedence.
|
||||
(5) Returns the result of (2-/expr/).
|
||||
(6) Returns the result of min(/expr/, /expr/).
|
||||
(7) Returns the result of max(/expr/, /expr/).
|
||||
(4) If value of <symbol1> is respectively lower, greater, lower-or-equal,
|
||||
or greater-or-equal than value of <symbol2>, it returns 'y',
|
||||
otherwise 'n'.
|
||||
(5) Returns the value of the expression. Used to override precedence.
|
||||
(6) Returns the result of (2-/expr/).
|
||||
(7) Returns the result of min(/expr/, /expr/).
|
||||
(8) Returns the result of max(/expr/, /expr/).
|
||||
|
||||
An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2
|
||||
respectively for calculations). A menu entry becomes visible when its
|
||||
|
@ -9,6 +9,7 @@ Contents:
|
||||
batman-adv
|
||||
kapi
|
||||
z8530book
|
||||
msg_zerocopy
|
||||
|
||||
.. only:: subproject
|
||||
|
||||
@ -16,4 +17,3 @@ Contents:
|
||||
=======
|
||||
|
||||
* :ref:`genindex`
|
||||
|
||||
|
@ -72,6 +72,10 @@ this flag, a process must first signal intent by setting a socket option:
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &one, sizeof(one)))
|
||||
error(1, errno, "setsockopt zerocopy");
|
||||
|
||||
Setting the socket option only works when the socket is in its initial
|
||||
(TCP_CLOSED) state. Trying to set the option for a socket returned by accept(),
|
||||
for example, will lead to an EBUSY error. In this case, the option should be set
|
||||
to the listening socket and it will be inherited by the accepted sockets.
|
||||
|
||||
Transmission
|
||||
------------
|
||||
|
@ -693,7 +693,7 @@ such specification consists of a number of lines with an inverval value
|
||||
in each line. The rules stated above are best illustrated with an example:
|
||||
|
||||
# mkdir functions/uvc.usb0/control/header/h
|
||||
# cd functions/uvc.usb0/control/header/h
|
||||
# cd functions/uvc.usb0/control/
|
||||
# ln -s header/h class/fs
|
||||
# ln -s header/h class/ss
|
||||
# mkdir -p functions/uvc.usb0/streaming/uncompressed/u/360p
|
||||
|
186
Documentation/x86/pti.txt
Normal file
186
Documentation/x86/pti.txt
Normal file
@ -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.
|
||||
d. 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
|
@ -12,8 +12,9 @@ ffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB)
|
||||
... unused hole ...
|
||||
ffffec0000000000 - fffffbffffffffff (=44 bits) kasan shadow memory (16TB)
|
||||
... unused hole ...
|
||||
fffffe0000000000 - fffffe7fffffffff (=39 bits) LDT remap for PTI
|
||||
fffffe8000000000 - fffffeffffffffff (=39 bits) cpu_entry_area mapping
|
||||
vaddr_end for KASLR
|
||||
fffffe0000000000 - fffffe7fffffffff (=39 bits) cpu_entry_area mapping
|
||||
fffffe8000000000 - fffffeffffffffff (=39 bits) LDT remap for PTI
|
||||
ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks
|
||||
... unused hole ...
|
||||
ffffffef00000000 - fffffffeffffffff (=64 GB) EFI region mapping space
|
||||
@ -37,13 +38,15 @@ ffd4000000000000 - ffd5ffffffffffff (=49 bits) virtual memory map (512TB)
|
||||
... unused hole ...
|
||||
ffdf000000000000 - fffffc0000000000 (=53 bits) kasan shadow memory (8PB)
|
||||
... unused hole ...
|
||||
fffffe8000000000 - fffffeffffffffff (=39 bits) cpu_entry_area mapping
|
||||
vaddr_end for KASLR
|
||||
fffffe0000000000 - fffffe7fffffffff (=39 bits) cpu_entry_area mapping
|
||||
... unused hole ...
|
||||
ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks
|
||||
... unused hole ...
|
||||
ffffffef00000000 - fffffffeffffffff (=64 GB) EFI region mapping space
|
||||
... unused hole ...
|
||||
ffffffff80000000 - ffffffff9fffffff (=512 MB) kernel text mapping, from phys 0
|
||||
ffffffffa0000000 - [fixmap start] (~1526 MB) module mapping space
|
||||
ffffffffa0000000 - fffffffffeffffff (1520 MB) module mapping space
|
||||
[fixmap start] - ffffffffff5fffff kernel-internal fixmap range
|
||||
ffffffffff600000 - ffffffffff600fff (=4 kB) legacy vsyscall ABI
|
||||
ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole
|
||||
@ -67,9 +70,10 @@ memory window (this size is arbitrary, it can be raised later if needed).
|
||||
The mappings are not part of any other kernel PGD and are only available
|
||||
during EFI runtime calls.
|
||||
|
||||
The module mapping space size changes based on the CONFIG requirements for the
|
||||
following fixmap section.
|
||||
|
||||
Note that if CONFIG_RANDOMIZE_MEMORY is enabled, the direct mapping of all
|
||||
physical memory, vmalloc/ioremap space and virtual memory map are randomized.
|
||||
Their order is preserved but their base will be offset early at boot time.
|
||||
|
||||
Be very careful vs. KASLR when changing anything here. The KASLR address
|
||||
range must not overlap with anything except the KASAN shadow area, which is
|
||||
correct as KASAN disables KASLR.
|
||||
|
15
MAINTAINERS
15
MAINTAINERS
@ -321,7 +321,7 @@ F: drivers/acpi/apei/
|
||||
|
||||
ACPI COMPONENT ARCHITECTURE (ACPICA)
|
||||
M: Robert Moore <robert.moore@intel.com>
|
||||
M: Lv Zheng <lv.zheng@intel.com>
|
||||
M: Erik Schmauss <erik.schmauss@intel.com>
|
||||
M: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
|
||||
L: linux-acpi@vger.kernel.org
|
||||
L: devel@acpica.org
|
||||
@ -5149,15 +5149,15 @@ F: sound/usb/misc/ua101.c
|
||||
EFI TEST DRIVER
|
||||
L: linux-efi@vger.kernel.org
|
||||
M: Ivan Hu <ivan.hu@canonical.com>
|
||||
M: Matt Fleming <matt@codeblueprint.co.uk>
|
||||
M: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
S: Maintained
|
||||
F: drivers/firmware/efi/test/
|
||||
|
||||
EFI VARIABLE FILESYSTEM
|
||||
M: Matthew Garrett <matthew.garrett@nebula.com>
|
||||
M: Jeremy Kerr <jk@ozlabs.org>
|
||||
M: Matt Fleming <matt@codeblueprint.co.uk>
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git
|
||||
M: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git
|
||||
L: linux-efi@vger.kernel.org
|
||||
S: Maintained
|
||||
F: fs/efivarfs/
|
||||
@ -5318,7 +5318,6 @@ S: Supported
|
||||
F: security/integrity/evm/
|
||||
|
||||
EXTENSIBLE FIRMWARE INTERFACE (EFI)
|
||||
M: Matt Fleming <matt@codeblueprint.co.uk>
|
||||
M: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
L: linux-efi@vger.kernel.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git
|
||||
@ -9639,8 +9638,8 @@ F: include/uapi/linux/sunrpc/
|
||||
NILFS2 FILESYSTEM
|
||||
M: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
|
||||
L: linux-nilfs@vger.kernel.org
|
||||
W: http://nilfs.sourceforge.net/
|
||||
W: http://nilfs.osdn.jp/
|
||||
W: https://nilfs.sourceforge.io/
|
||||
W: https://nilfs.osdn.jp/
|
||||
T: git git://github.com/konis/nilfs2.git
|
||||
S: Supported
|
||||
F: Documentation/filesystems/nilfs2.txt
|
||||
@ -10135,7 +10134,7 @@ F: drivers/irqchip/irq-ompic.c
|
||||
F: drivers/irqchip/irq-or1k-*
|
||||
|
||||
OPENVSWITCH
|
||||
M: Pravin Shelar <pshelar@nicira.com>
|
||||
M: Pravin B Shelar <pshelar@ovn.org>
|
||||
L: netdev@vger.kernel.org
|
||||
L: dev@openvswitch.org
|
||||
W: http://openvswitch.org
|
||||
|
45
Makefile
45
Makefile
@ -2,7 +2,7 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 15
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc6
|
||||
EXTRAVERSION = -rc8
|
||||
NAME = Fearless Coyote
|
||||
|
||||
# *DOCUMENTATION*
|
||||
@ -484,26 +484,6 @@ CLANG_GCC_TC := --gcc-toolchain=$(GCC_TOOLCHAIN)
|
||||
endif
|
||||
KBUILD_CFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC)
|
||||
KBUILD_AFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC)
|
||||
KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, unused-variable)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, format-invalid-specifier)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, gnu)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member)
|
||||
# Quiet clang warning: comparison of unsigned expression < 0 is always false
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, tautological-compare)
|
||||
# CLANG uses a _MergedGlobals as optimization, but this breaks modpost, as the
|
||||
# source of a reference will be _MergedGlobals and not on of the whitelisted names.
|
||||
# See modpost pattern 2
|
||||
KBUILD_CFLAGS += $(call cc-option, -mno-global-merge,)
|
||||
KBUILD_CFLAGS += $(call cc-option, -fcatch-undefined-behavior)
|
||||
KBUILD_CFLAGS += $(call cc-option, -no-integrated-as)
|
||||
KBUILD_AFLAGS += $(call cc-option, -no-integrated-as)
|
||||
else
|
||||
|
||||
# These warnings generated too much noise in a regular build.
|
||||
# Use make W=1 to enable them (see scripts/Makefile.extrawarn)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, unused-const-variable)
|
||||
endif
|
||||
|
||||
ifeq ($(config-targets),1)
|
||||
@ -716,6 +696,29 @@ ifdef CONFIG_CC_STACKPROTECTOR
|
||||
endif
|
||||
KBUILD_CFLAGS += $(stackp-flag)
|
||||
|
||||
ifeq ($(cc-name),clang)
|
||||
KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, unused-variable)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, format-invalid-specifier)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, gnu)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member)
|
||||
# Quiet clang warning: comparison of unsigned expression < 0 is always false
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, tautological-compare)
|
||||
# CLANG uses a _MergedGlobals as optimization, but this breaks modpost, as the
|
||||
# source of a reference will be _MergedGlobals and not on of the whitelisted names.
|
||||
# See modpost pattern 2
|
||||
KBUILD_CFLAGS += $(call cc-option, -mno-global-merge,)
|
||||
KBUILD_CFLAGS += $(call cc-option, -fcatch-undefined-behavior)
|
||||
KBUILD_CFLAGS += $(call cc-option, -no-integrated-as)
|
||||
KBUILD_AFLAGS += $(call cc-option, -no-integrated-as)
|
||||
else
|
||||
|
||||
# These warnings generated too much noise in a regular build.
|
||||
# Use make W=1 to enable them (see scripts/Makefile.extrawarn)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, unused-const-variable)
|
||||
endif
|
||||
|
||||
ifdef CONFIG_FRAME_POINTER
|
||||
KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
|
||||
else
|
||||
|
@ -35,6 +35,14 @@ core_clk: core-clk@80 {
|
||||
reg = <0x80 0x10>, <0x100 0x10>;
|
||||
#clock-cells = <0>;
|
||||
clocks = <&input_clk>;
|
||||
|
||||
/*
|
||||
* Set initial core pll output frequency to 90MHz.
|
||||
* It will be applied at the core pll driver probing
|
||||
* on early boot.
|
||||
*/
|
||||
assigned-clocks = <&core_clk>;
|
||||
assigned-clock-rates = <90000000>;
|
||||
};
|
||||
|
||||
core_intc: archs-intc@cpu {
|
||||
|
@ -35,6 +35,14 @@ core_clk: core-clk@80 {
|
||||
reg = <0x80 0x10>, <0x100 0x10>;
|
||||
#clock-cells = <0>;
|
||||
clocks = <&input_clk>;
|
||||
|
||||
/*
|
||||
* Set initial core pll output frequency to 100MHz.
|
||||
* It will be applied at the core pll driver probing
|
||||
* on early boot.
|
||||
*/
|
||||
assigned-clocks = <&core_clk>;
|
||||
assigned-clock-rates = <100000000>;
|
||||
};
|
||||
|
||||
core_intc: archs-intc@cpu {
|
||||
|
@ -114,6 +114,14 @@ core_clk: core-clk@0 {
|
||||
reg = <0x00 0x10>, <0x14B8 0x4>;
|
||||
#clock-cells = <0>;
|
||||
clocks = <&input_clk>;
|
||||
|
||||
/*
|
||||
* Set initial core pll output frequency to 1GHz.
|
||||
* It will be applied at the core pll driver probing
|
||||
* on early boot.
|
||||
*/
|
||||
assigned-clocks = <&core_clk>;
|
||||
assigned-clock-rates = <1000000000>;
|
||||
};
|
||||
|
||||
serial: serial@5000 {
|
||||
|
@ -49,10 +49,11 @@ CONFIG_SERIAL_8250_DW=y
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
# CONFIG_HWMON is not set
|
||||
CONFIG_DRM=y
|
||||
# CONFIG_DRM_FBDEV_EMULATION is not set
|
||||
CONFIG_DRM_UDL=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_FB_UDL=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_HCD_PLATFORM=y
|
||||
CONFIG_USB_OHCI_HCD=y
|
||||
|
@ -668,6 +668,7 @@ __arc_strncpy_from_user(char *dst, const char __user *src, long count)
|
||||
return 0;
|
||||
|
||||
__asm__ __volatile__(
|
||||
" mov lp_count, %5 \n"
|
||||
" lp 3f \n"
|
||||
"1: ldb.ab %3, [%2, 1] \n"
|
||||
" breq.d %3, 0, 3f \n"
|
||||
@ -684,8 +685,8 @@ __arc_strncpy_from_user(char *dst, const char __user *src, long count)
|
||||
" .word 1b, 4b \n"
|
||||
" .previous \n"
|
||||
: "+r"(res), "+r"(dst), "+r"(src), "=r"(val)
|
||||
: "g"(-EFAULT), "l"(count)
|
||||
: "memory");
|
||||
: "g"(-EFAULT), "r"(count)
|
||||
: "lp_count", "lp_start", "lp_end", "memory");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ static void read_arc_build_cfg_regs(void)
|
||||
unsigned int exec_ctrl;
|
||||
|
||||
READ_BCR(AUX_EXEC_CTRL, exec_ctrl);
|
||||
cpu->extn.dual_enb = exec_ctrl & 1;
|
||||
cpu->extn.dual_enb = !(exec_ctrl & 1);
|
||||
|
||||
/* dual issue always present for this core */
|
||||
cpu->extn.dual = 1;
|
||||
|
@ -163,7 +163,7 @@ arc_unwind_core(struct task_struct *tsk, struct pt_regs *regs,
|
||||
*/
|
||||
static int __print_sym(unsigned int address, void *unused)
|
||||
{
|
||||
__print_symbol(" %s\n", address);
|
||||
printk(" %pS\n", (void *)address);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -83,6 +83,7 @@ DO_ERROR_INFO(SIGILL, "Illegal Insn (or Seq)", insterror_is_error, ILL_ILLOPC)
|
||||
DO_ERROR_INFO(SIGBUS, "Invalid Mem Access", __weak do_memory_error, BUS_ADRERR)
|
||||
DO_ERROR_INFO(SIGTRAP, "Breakpoint Set", trap_is_brkpt, TRAP_BRKPT)
|
||||
DO_ERROR_INFO(SIGBUS, "Misaligned Access", do_misaligned_error, BUS_ADRALN)
|
||||
DO_ERROR_INFO(SIGSEGV, "gcc generated __builtin_trap", do_trap5_error, 0)
|
||||
|
||||
/*
|
||||
* Entry Point for Misaligned Data access Exception, for emulating in software
|
||||
@ -115,6 +116,8 @@ void do_machine_check_fault(unsigned long address, struct pt_regs *regs)
|
||||
* Thus TRAP_S <n> can be used for specific purpose
|
||||
* -1 used for software breakpointing (gdb)
|
||||
* -2 used by kprobes
|
||||
* -5 __builtin_trap() generated by gcc (2018.03 onwards) for toggle such as
|
||||
* -fno-isolate-erroneous-paths-dereference
|
||||
*/
|
||||
void do_non_swi_trap(unsigned long address, struct pt_regs *regs)
|
||||
{
|
||||
@ -134,6 +137,9 @@ void do_non_swi_trap(unsigned long address, struct pt_regs *regs)
|
||||
kgdb_trap(regs);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
do_trap5_error(address, regs);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -155,3 +161,11 @@ void do_insterror_or_kprobe(unsigned long address, struct pt_regs *regs)
|
||||
|
||||
insterror_is_error(address, regs);
|
||||
}
|
||||
|
||||
/*
|
||||
* abort() call generated by older gcc for __builtin_trap()
|
||||
*/
|
||||
void abort(void)
|
||||
{
|
||||
__asm__ __volatile__("trap_s 5\n");
|
||||
}
|
||||
|
@ -163,6 +163,9 @@ static void show_ecr_verbose(struct pt_regs *regs)
|
||||
else
|
||||
pr_cont("Bus Error, check PRM\n");
|
||||
#endif
|
||||
} else if (vec == ECR_V_TRAP) {
|
||||
if (regs->ecr_param == 5)
|
||||
pr_cont("gcc generated __builtin_trap\n");
|
||||
} else {
|
||||
pr_cont("Check Programmer's Manual\n");
|
||||
}
|
||||
|
@ -317,25 +317,23 @@ static void __init axs103_early_init(void)
|
||||
* Instead of duplicating defconfig/DT for SMP/QUAD, add a small hack
|
||||
* of fudging the freq in DT
|
||||
*/
|
||||
#define AXS103_QUAD_CORE_CPU_FREQ_HZ 50000000
|
||||
|
||||
unsigned int num_cores = (read_aux_reg(ARC_REG_MCIP_BCR) >> 16) & 0x3F;
|
||||
if (num_cores > 2) {
|
||||
u32 freq = 50, orig;
|
||||
/*
|
||||
* TODO: use cpu node "cpu-freq" param instead of platform-specific
|
||||
* "/cpu_card/core_clk" as it works only if we use fixed-clock for cpu.
|
||||
*/
|
||||
u32 freq;
|
||||
int off = fdt_path_offset(initial_boot_params, "/cpu_card/core_clk");
|
||||
const struct fdt_property *prop;
|
||||
|
||||
prop = fdt_get_property(initial_boot_params, off,
|
||||
"clock-frequency", NULL);
|
||||
orig = be32_to_cpu(*(u32*)(prop->data)) / 1000000;
|
||||
"assigned-clock-rates", NULL);
|
||||
freq = be32_to_cpu(*(u32 *)(prop->data));
|
||||
|
||||
/* Patching .dtb in-place with new core clock value */
|
||||
if (freq != orig ) {
|
||||
freq = cpu_to_be32(freq * 1000000);
|
||||
if (freq != AXS103_QUAD_CORE_CPU_FREQ_HZ) {
|
||||
freq = cpu_to_be32(AXS103_QUAD_CORE_CPU_FREQ_HZ);
|
||||
fdt_setprop_inplace(initial_boot_params, off,
|
||||
"clock-frequency", &freq, sizeof(freq));
|
||||
"assigned-clock-rates", &freq, sizeof(freq));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -38,42 +38,6 @@ static void __init hsdk_init_per_cpu(unsigned int cpu)
|
||||
#define CREG_PAE (CREG_BASE + 0x180)
|
||||
#define CREG_PAE_UPDATE (CREG_BASE + 0x194)
|
||||
|
||||
#define CREG_CORE_IF_CLK_DIV (CREG_BASE + 0x4B8)
|
||||
#define CREG_CORE_IF_CLK_DIV_2 0x1
|
||||
#define CGU_BASE ARC_PERIPHERAL_BASE
|
||||
#define CGU_PLL_STATUS (ARC_PERIPHERAL_BASE + 0x4)
|
||||
#define CGU_PLL_CTRL (ARC_PERIPHERAL_BASE + 0x0)
|
||||
#define CGU_PLL_STATUS_LOCK BIT(0)
|
||||
#define CGU_PLL_STATUS_ERR BIT(1)
|
||||
#define CGU_PLL_CTRL_1GHZ 0x3A10
|
||||
#define HSDK_PLL_LOCK_TIMEOUT 500
|
||||
|
||||
#define HSDK_PLL_LOCKED() \
|
||||
!!(ioread32((void __iomem *) CGU_PLL_STATUS) & CGU_PLL_STATUS_LOCK)
|
||||
|
||||
#define HSDK_PLL_ERR() \
|
||||
!!(ioread32((void __iomem *) CGU_PLL_STATUS) & CGU_PLL_STATUS_ERR)
|
||||
|
||||
static void __init hsdk_set_cpu_freq_1ghz(void)
|
||||
{
|
||||
u32 timeout = HSDK_PLL_LOCK_TIMEOUT;
|
||||
|
||||
/*
|
||||
* As we set cpu clock which exceeds 500MHz, the divider for the interface
|
||||
* clock must be programmed to div-by-2.
|
||||
*/
|
||||
iowrite32(CREG_CORE_IF_CLK_DIV_2, (void __iomem *) CREG_CORE_IF_CLK_DIV);
|
||||
|
||||
/* Set cpu clock to 1GHz */
|
||||
iowrite32(CGU_PLL_CTRL_1GHZ, (void __iomem *) CGU_PLL_CTRL);
|
||||
|
||||
while (!HSDK_PLL_LOCKED() && timeout--)
|
||||
cpu_relax();
|
||||
|
||||
if (!HSDK_PLL_LOCKED() || HSDK_PLL_ERR())
|
||||
pr_err("Failed to setup CPU frequency to 1GHz!");
|
||||
}
|
||||
|
||||
#define SDIO_BASE (ARC_PERIPHERAL_BASE + 0xA000)
|
||||
#define SDIO_UHS_REG_EXT (SDIO_BASE + 0x108)
|
||||
#define SDIO_UHS_REG_EXT_DIV_2 (2 << 30)
|
||||
@ -98,12 +62,6 @@ static void __init hsdk_init_early(void)
|
||||
* minimum possible div-by-2.
|
||||
*/
|
||||
iowrite32(SDIO_UHS_REG_EXT_DIV_2, (void __iomem *) SDIO_UHS_REG_EXT);
|
||||
|
||||
/*
|
||||
* Setup CPU frequency to 1GHz.
|
||||
* TODO: remove it after smart hsdk pll driver will be introduced.
|
||||
*/
|
||||
hsdk_set_cpu_freq_1ghz();
|
||||
}
|
||||
|
||||
static const char *hsdk_compat[] __initconst = {
|
||||
|
@ -219,7 +219,7 @@ vuart: serial@1e787000 {
|
||||
compatible = "aspeed,ast2400-vuart";
|
||||
reg = <0x1e787000 0x40>;
|
||||
reg-shift = <2>;
|
||||
interrupts = <10>;
|
||||
interrupts = <8>;
|
||||
clocks = <&clk_uart>;
|
||||
no-loopback-test;
|
||||
status = "disabled";
|
||||
|
@ -221,6 +221,7 @@ &i2c0 {
|
||||
jc42@18 {
|
||||
compatible = "nxp,se97b", "jedec,jc-42.4-temp";
|
||||
reg = <0x18>;
|
||||
smbus-timeout-disable;
|
||||
};
|
||||
|
||||
dpot: mcp4651-104@28 {
|
||||
|
@ -178,7 +178,7 @@ amp: regulator3 {
|
||||
*/
|
||||
battery {
|
||||
pinctrl-names = "default";
|
||||
pintctrl-0 = <&battery_pins>;
|
||||
pinctrl-0 = <&battery_pins>;
|
||||
compatible = "lego,ev3-battery";
|
||||
io-channels = <&adc 4>, <&adc 3>;
|
||||
io-channel-names = "voltage", "current";
|
||||
@ -392,7 +392,7 @@ &gpio {
|
||||
batt_volt_en {
|
||||
gpio-hog;
|
||||
gpios = <6 GPIO_ACTIVE_HIGH>;
|
||||
output-low;
|
||||
output-high;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -664,6 +664,10 @@ &i2s0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&mixer {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* eMMC flash */
|
||||
&mmc_0 {
|
||||
status = "okay";
|
||||
|
@ -215,7 +215,7 @@ codec: sgtl5000@2a {
|
||||
reg = <0x2a>;
|
||||
VDDA-supply = <®_3p3v>;
|
||||
VDDIO-supply = <®_3p3v>;
|
||||
clocks = <&sys_mclk 1>;
|
||||
clocks = <&sys_mclk>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -187,7 +187,7 @@ codec: sgtl5000@a {
|
||||
reg = <0x0a>;
|
||||
VDDA-supply = <®_3p3v>;
|
||||
VDDIO-supply = <®_3p3v>;
|
||||
clocks = <&sys_mclk 1>;
|
||||
clocks = <&sys_mclk>;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -83,6 +83,10 @@ vsys: vsys-regulator {
|
||||
};
|
||||
};
|
||||
|
||||
&cpu0 {
|
||||
cpu0-supply = <&vdd_arm>;
|
||||
};
|
||||
|
||||
&i2c1 {
|
||||
status = "okay";
|
||||
clock-frequency = <400000>;
|
||||
|
@ -956,7 +956,7 @@ crypto: cypto-controller@ff8a0000 {
|
||||
iep_mmu: iommu@ff900800 {
|
||||
compatible = "rockchip,iommu";
|
||||
reg = <0x0 0xff900800 0x0 0x40>;
|
||||
interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "iep_mmu";
|
||||
#iommu-cells = <0>;
|
||||
status = "disabled";
|
||||
|
@ -502,8 +502,8 @@ hdmi: hdmi@1c16000 {
|
||||
reg = <0x01c16000 0x1000>;
|
||||
interrupts = <58>;
|
||||
clocks = <&ccu CLK_AHB_HDMI0>, <&ccu CLK_HDMI>,
|
||||
<&ccu 9>,
|
||||
<&ccu 18>;
|
||||
<&ccu CLK_PLL_VIDEO0_2X>,
|
||||
<&ccu CLK_PLL_VIDEO1_2X>;
|
||||
clock-names = "ahb", "mod", "pll-0", "pll-1";
|
||||
dmas = <&dma SUN4I_DMA_NORMAL 16>,
|
||||
<&dma SUN4I_DMA_NORMAL 16>,
|
||||
|
@ -82,8 +82,8 @@ hdmi: hdmi@1c16000 {
|
||||
reg = <0x01c16000 0x1000>;
|
||||
interrupts = <58>;
|
||||
clocks = <&ccu CLK_AHB_HDMI>, <&ccu CLK_HDMI>,
|
||||
<&ccu 9>,
|
||||
<&ccu 16>;
|
||||
<&ccu CLK_PLL_VIDEO0_2X>,
|
||||
<&ccu CLK_PLL_VIDEO1_2X>;
|
||||
clock-names = "ahb", "mod", "pll-0", "pll-1";
|
||||
dmas = <&dma SUN4I_DMA_NORMAL 16>,
|
||||
<&dma SUN4I_DMA_NORMAL 16>,
|
||||
|
@ -429,8 +429,8 @@ hdmi: hdmi@1c16000 {
|
||||
interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&ccu CLK_AHB1_HDMI>, <&ccu CLK_HDMI>,
|
||||
<&ccu CLK_HDMI_DDC>,
|
||||
<&ccu 7>,
|
||||
<&ccu 13>;
|
||||
<&ccu CLK_PLL_VIDEO0_2X>,
|
||||
<&ccu CLK_PLL_VIDEO1_2X>;
|
||||
clock-names = "ahb", "mod", "ddc", "pll-0", "pll-1";
|
||||
resets = <&ccu RST_AHB1_HDMI>;
|
||||
reset-names = "ahb";
|
||||
|
@ -581,8 +581,8 @@ hdmi: hdmi@1c16000 {
|
||||
reg = <0x01c16000 0x1000>;
|
||||
interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&ccu CLK_AHB_HDMI0>, <&ccu CLK_HDMI>,
|
||||
<&ccu 9>,
|
||||
<&ccu 18>;
|
||||
<&ccu CLK_PLL_VIDEO0_2X>,
|
||||
<&ccu CLK_PLL_VIDEO1_2X>;
|
||||
clock-names = "ahb", "mod", "pll-0", "pll-1";
|
||||
dmas = <&dma SUN4I_DMA_NORMAL 16>,
|
||||
<&dma SUN4I_DMA_NORMAL 16>,
|
||||
|
@ -146,6 +146,7 @@ &r_rsb {
|
||||
status = "okay";
|
||||
|
||||
axp81x: pmic@3a3 {
|
||||
compatible = "x-powers,axp813";
|
||||
reg = <0x3a3>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
|
@ -156,7 +156,6 @@ intc: interrupt-controller@6e000 {
|
||||
reg = <0x6e000 0x400>;
|
||||
ranges = <0 0x6e000 0x400>;
|
||||
interrupt-parent = <&gic>;
|
||||
interrupt-controller;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
|
@ -793,7 +793,6 @@ void abort(void)
|
||||
/* if that doesn't kill us, halt */
|
||||
panic("Oops failed to kill thread");
|
||||
}
|
||||
EXPORT_SYMBOL(abort);
|
||||
|
||||
void __init trap_init(void)
|
||||
{
|
||||
|
@ -868,10 +868,10 @@ static const struct dma_slave_map dm365_edma_map[] = {
|
||||
{ "spi_davinci.0", "rx", EDMA_FILTER_PARAM(0, 17) },
|
||||
{ "spi_davinci.3", "tx", EDMA_FILTER_PARAM(0, 18) },
|
||||
{ "spi_davinci.3", "rx", EDMA_FILTER_PARAM(0, 19) },
|
||||
{ "dm6441-mmc.0", "rx", EDMA_FILTER_PARAM(0, 26) },
|
||||
{ "dm6441-mmc.0", "tx", EDMA_FILTER_PARAM(0, 27) },
|
||||
{ "dm6441-mmc.1", "rx", EDMA_FILTER_PARAM(0, 30) },
|
||||
{ "dm6441-mmc.1", "tx", EDMA_FILTER_PARAM(0, 31) },
|
||||
{ "da830-mmc.0", "rx", EDMA_FILTER_PARAM(0, 26) },
|
||||
{ "da830-mmc.0", "tx", EDMA_FILTER_PARAM(0, 27) },
|
||||
{ "da830-mmc.1", "rx", EDMA_FILTER_PARAM(0, 30) },
|
||||
{ "da830-mmc.1", "tx", EDMA_FILTER_PARAM(0, 31) },
|
||||
};
|
||||
|
||||
static struct edma_soc_info dm365_edma_pdata = {
|
||||
@ -925,12 +925,14 @@ static struct resource edma_resources[] = {
|
||||
/* not using TC*_ERR */
|
||||
};
|
||||
|
||||
static struct platform_device dm365_edma_device = {
|
||||
.name = "edma",
|
||||
.id = 0,
|
||||
.dev.platform_data = &dm365_edma_pdata,
|
||||
.num_resources = ARRAY_SIZE(edma_resources),
|
||||
.resource = edma_resources,
|
||||
static const struct platform_device_info dm365_edma_device __initconst = {
|
||||
.name = "edma",
|
||||
.id = 0,
|
||||
.dma_mask = DMA_BIT_MASK(32),
|
||||
.res = edma_resources,
|
||||
.num_res = ARRAY_SIZE(edma_resources),
|
||||
.data = &dm365_edma_pdata,
|
||||
.size_data = sizeof(dm365_edma_pdata),
|
||||
};
|
||||
|
||||
static struct resource dm365_asp_resources[] = {
|
||||
@ -1428,13 +1430,18 @@ int __init dm365_init_video(struct vpfe_config *vpfe_cfg,
|
||||
|
||||
static int __init dm365_init_devices(void)
|
||||
{
|
||||
struct platform_device *edma_pdev;
|
||||
int ret = 0;
|
||||
|
||||
if (!cpu_is_davinci_dm365())
|
||||
return 0;
|
||||
|
||||
davinci_cfg_reg(DM365_INT_EDMA_CC);
|
||||
platform_device_register(&dm365_edma_device);
|
||||
edma_pdev = platform_device_register_full(&dm365_edma_device);
|
||||
if (IS_ERR(edma_pdev)) {
|
||||
pr_warn("%s: Failed to register eDMA\n", __func__);
|
||||
return PTR_ERR(edma_pdev);
|
||||
}
|
||||
|
||||
platform_device_register(&dm365_mdio_device);
|
||||
platform_device_register(&dm365_emac_device);
|
||||
|
@ -75,6 +75,7 @@ &emac {
|
||||
pinctrl-0 = <&rgmii_pins>;
|
||||
phy-mode = "rgmii";
|
||||
phy-handle = <&ext_rgmii_phy>;
|
||||
phy-supply = <®_dc1sw>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
@ -77,6 +77,7 @@ &emac {
|
||||
pinctrl-0 = <&rmii_pins>;
|
||||
phy-mode = "rmii";
|
||||
phy-handle = <&ext_rmii_phy1>;
|
||||
phy-supply = <®_dc1sw>;
|
||||
status = "okay";
|
||||
|
||||
};
|
||||
|
@ -82,6 +82,7 @@ &emac {
|
||||
pinctrl-0 = <&rgmii_pins>;
|
||||
phy-mode = "rgmii";
|
||||
phy-handle = <&ext_rgmii_phy>;
|
||||
phy-supply = <®_dc1sw>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@ -95,7 +96,7 @@ ext_rgmii_phy: ethernet-phy@1 {
|
||||
&mmc2 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mmc2_pins>;
|
||||
vmmc-supply = <®_vcc3v3>;
|
||||
vmmc-supply = <®_dcdc1>;
|
||||
vqmmc-supply = <®_vcc1v8>;
|
||||
bus-width = <8>;
|
||||
non-removable;
|
||||
|
@ -45,19 +45,10 @@
|
||||
|
||||
#include "sun50i-a64.dtsi"
|
||||
|
||||
/ {
|
||||
reg_vcc3v3: vcc3v3 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc3v3";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
};
|
||||
|
||||
&mmc0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mmc0_pins>;
|
||||
vmmc-supply = <®_vcc3v3>;
|
||||
vmmc-supply = <®_dcdc1>;
|
||||
non-removable;
|
||||
disable-wp;
|
||||
bus-width = <4>;
|
||||
|
@ -71,7 +71,7 @@ &mmc0 {
|
||||
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
|
||||
vmmc-supply = <®_vcc3v3>;
|
||||
bus-width = <4>;
|
||||
cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;
|
||||
cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
@ -255,7 +255,6 @@ &audio_clk_a {
|
||||
&avb {
|
||||
pinctrl-0 = <&avb_pins>;
|
||||
pinctrl-names = "default";
|
||||
renesas,no-ether-link;
|
||||
phy-handle = <&phy0>;
|
||||
status = "okay";
|
||||
|
||||
|
@ -145,7 +145,6 @@ &audio_clk_a {
|
||||
&avb {
|
||||
pinctrl-0 = <&avb_pins>;
|
||||
pinctrl-names = "default";
|
||||
renesas,no-ether-link;
|
||||
phy-handle = <&phy0>;
|
||||
status = "okay";
|
||||
|
||||
|
@ -132,6 +132,8 @@ &gmac2io {
|
||||
assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>;
|
||||
assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>;
|
||||
clock_in_out = "input";
|
||||
/* shows instability at 1GBit right now */
|
||||
max-speed = <100>;
|
||||
phy-supply = <&vcc_io>;
|
||||
phy-mode = "rgmii";
|
||||
pinctrl-names = "default";
|
||||
|
@ -514,7 +514,7 @@ map0 {
|
||||
tsadc: tsadc@ff250000 {
|
||||
compatible = "rockchip,rk3328-tsadc";
|
||||
reg = <0x0 0xff250000 0x0 0x100>;
|
||||
interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
|
||||
assigned-clocks = <&cru SCLK_TSADC>;
|
||||
assigned-clock-rates = <50000>;
|
||||
clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>;
|
||||
|
@ -155,17 +155,6 @@ vcc5v0_sys: vcc5v0-sys {
|
||||
regulator-min-microvolt = <5000000>;
|
||||
regulator-max-microvolt = <5000000>;
|
||||
};
|
||||
|
||||
vdd_log: vdd-log {
|
||||
compatible = "pwm-regulator";
|
||||
pwms = <&pwm2 0 25000 0>;
|
||||
regulator-name = "vdd_log";
|
||||
regulator-min-microvolt = <800000>;
|
||||
regulator-max-microvolt = <1400000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&cpu_b0 {
|
||||
|
@ -198,8 +198,8 @@ gpio: gpio@55000000 {
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
gpio-ranges = <&pinctrl 0 0 0>,
|
||||
<&pinctrl 96 0 0>,
|
||||
<&pinctrl 160 0 0>;
|
||||
<&pinctrl 104 0 0>,
|
||||
<&pinctrl 168 0 0>;
|
||||
gpio-ranges-group-names = "gpio_range0",
|
||||
"gpio_range1",
|
||||
"gpio_range2";
|
||||
|
@ -504,6 +504,11 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
|
||||
if (!(ma->flags & ACPI_SRAT_MEM_ENABLED))
|
||||
return -1;
|
||||
|
||||
if (num_node_memblks >= NR_NODE_MEMBLKS) {
|
||||
pr_err("NUMA: too many memblk ranges\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* record this node in proximity bitmap */
|
||||
pxm_bit_set(pxm);
|
||||
|
||||
|
@ -88,7 +88,7 @@ void vtime_flush(struct task_struct *tsk)
|
||||
}
|
||||
|
||||
if (ti->softirq_time) {
|
||||
delta = cycle_to_nsec(ti->softirq_time));
|
||||
delta = cycle_to_nsec(ti->softirq_time);
|
||||
account_system_index_time(tsk, delta, CPUTIME_SOFTIRQ);
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,6 @@ void abort(void)
|
||||
/* if that doesn't kill us, halt */
|
||||
panic("Oops failed to kill thread");
|
||||
}
|
||||
EXPORT_SYMBOL(abort);
|
||||
|
||||
void __init trap_init(void)
|
||||
{
|
||||
|
@ -235,6 +235,7 @@ LEAF(mips_cps_core_init)
|
||||
has_mt t0, 3f
|
||||
|
||||
.set push
|
||||
.set MIPS_ISA_LEVEL_RAW
|
||||
.set mt
|
||||
|
||||
/* Only allow 1 TC per VPE to execute... */
|
||||
@ -388,6 +389,7 @@ LEAF(mips_cps_boot_vpes)
|
||||
#elif defined(CONFIG_MIPS_MT)
|
||||
|
||||
.set push
|
||||
.set MIPS_ISA_LEVEL_RAW
|
||||
.set mt
|
||||
|
||||
/* If the core doesn't support MT then return */
|
||||
|
@ -705,6 +705,18 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value)
|
||||
struct task_struct *t;
|
||||
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 */
|
||||
if (value & ~known_bits)
|
||||
return -EOPNOTSUPP;
|
||||
|
@ -419,25 +419,38 @@ static int gpr64_set(struct task_struct *target,
|
||||
|
||||
#endif /* CONFIG_64BIT */
|
||||
|
||||
static int fpr_get(struct task_struct *target,
|
||||
const struct user_regset *regset,
|
||||
unsigned int pos, unsigned int count,
|
||||
void *kbuf, void __user *ubuf)
|
||||
/*
|
||||
* Copy the floating-point context to the supplied NT_PRFPREG buffer,
|
||||
* !CONFIG_CPU_HAS_MSA variant. FP context's general register slots
|
||||
* 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;
|
||||
int err;
|
||||
return user_regset_copyout(pos, count, kbuf, ubuf,
|
||||
&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;
|
||||
int err;
|
||||
|
||||
/* XXX fcr31 */
|
||||
|
||||
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));
|
||||
|
||||
BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t));
|
||||
for (i = 0; i < NUM_FPU_REGS; i++) {
|
||||
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),
|
||||
(i + 1) * sizeof(elf_fpreg_t));
|
||||
if (err)
|
||||
@ -447,27 +460,64 @@ static int fpr_get(struct task_struct *target,
|
||||
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,
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
/* 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));
|
||||
int err;
|
||||
|
||||
BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t));
|
||||
for (i = 0; i < NUM_FPU_REGS && count >= sizeof(elf_fpreg_t); i++) {
|
||||
err = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||
for (i = 0; i < NUM_FPU_REGS && *count > 0; i++) {
|
||||
err = user_regset_copyin(pos, count, kbuf, ubuf,
|
||||
&fpr_val, i * sizeof(elf_fpreg_t),
|
||||
(i + 1) * sizeof(elf_fpreg_t));
|
||||
if (err)
|
||||
@ -478,6 +528,53 @@ static int fpr_set(struct task_struct *target,
|
||||
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 {
|
||||
REGSET_GPR,
|
||||
REGSET_FPR,
|
||||
|
@ -12,6 +12,7 @@
|
||||
for the semaphore. */
|
||||
|
||||
#define __PA_LDCW_ALIGNMENT 16
|
||||
#define __PA_LDCW_ALIGN_ORDER 4
|
||||
#define __ldcw_align(a) ({ \
|
||||
unsigned long __ret = (unsigned long) &(a)->lock[0]; \
|
||||
__ret = (__ret + __PA_LDCW_ALIGNMENT - 1) \
|
||||
@ -29,6 +30,7 @@
|
||||
ldcd). */
|
||||
|
||||
#define __PA_LDCW_ALIGNMENT 4
|
||||
#define __PA_LDCW_ALIGN_ORDER 2
|
||||
#define __ldcw_align(a) (&(a)->slock)
|
||||
#define __LDCW "ldcw,co"
|
||||
|
||||
|
@ -870,7 +870,7 @@ static void print_parisc_device(struct parisc_device *dev)
|
||||
static int count;
|
||||
|
||||
print_pa_hwpath(dev, hw_path);
|
||||
printk(KERN_INFO "%d. %s at 0x%p [%s] { %d, 0x%x, 0x%.3x, 0x%.5x }",
|
||||
printk(KERN_INFO "%d. %s at 0x%px [%s] { %d, 0x%x, 0x%.3x, 0x%.5x }",
|
||||
++count, dev->name, (void*) dev->hpa.start, hw_path, dev->id.hw_type,
|
||||
dev->id.hversion_rev, dev->id.hversion, dev->id.sversion);
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/signal.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/ldcw.h>
|
||||
#include <asm/thread_info.h>
|
||||
|
||||
#include <linux/linkage.h>
|
||||
@ -46,6 +47,14 @@
|
||||
#endif
|
||||
|
||||
.import pa_tlb_lock,data
|
||||
.macro load_pa_tlb_lock reg
|
||||
#if __PA_LDCW_ALIGNMENT > 4
|
||||
load32 PA(pa_tlb_lock) + __PA_LDCW_ALIGNMENT-1, \reg
|
||||
depi 0,31,__PA_LDCW_ALIGN_ORDER, \reg
|
||||
#else
|
||||
load32 PA(pa_tlb_lock), \reg
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/* space_to_prot macro creates a prot id from a space id */
|
||||
|
||||
@ -457,7 +466,7 @@
|
||||
.macro tlb_lock spc,ptp,pte,tmp,tmp1,fault
|
||||
#ifdef CONFIG_SMP
|
||||
cmpib,COND(=),n 0,\spc,2f
|
||||
load32 PA(pa_tlb_lock),\tmp
|
||||
load_pa_tlb_lock \tmp
|
||||
1: LDCW 0(\tmp),\tmp1
|
||||
cmpib,COND(=) 0,\tmp1,1b
|
||||
nop
|
||||
@ -480,7 +489,7 @@
|
||||
/* Release pa_tlb_lock lock. */
|
||||
.macro tlb_unlock1 spc,tmp
|
||||
#ifdef CONFIG_SMP
|
||||
load32 PA(pa_tlb_lock),\tmp
|
||||
load_pa_tlb_lock \tmp
|
||||
tlb_unlock0 \spc,\tmp
|
||||
#endif
|
||||
.endm
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <asm/assembly.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/cache.h>
|
||||
#include <asm/ldcw.h>
|
||||
#include <linux/linkage.h>
|
||||
|
||||
.text
|
||||
@ -333,8 +334,12 @@ ENDPROC_CFI(flush_data_cache_local)
|
||||
|
||||
.macro tlb_lock la,flags,tmp
|
||||
#ifdef CONFIG_SMP
|
||||
ldil L%pa_tlb_lock,%r1
|
||||
ldo R%pa_tlb_lock(%r1),\la
|
||||
#if __PA_LDCW_ALIGNMENT > 4
|
||||
load32 pa_tlb_lock + __PA_LDCW_ALIGNMENT-1, \la
|
||||
depi 0,31,__PA_LDCW_ALIGN_ORDER, \la
|
||||
#else
|
||||
load32 pa_tlb_lock, \la
|
||||
#endif
|
||||
rsm PSW_SM_I,\flags
|
||||
1: LDCW 0(\la),\tmp
|
||||
cmpib,<>,n 0,\tmp,3f
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/personality.h>
|
||||
#include <linux/ptrace.h>
|
||||
@ -183,6 +184,44 @@ int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Idle thread support
|
||||
*
|
||||
* Detect when running on QEMU with SeaBIOS PDC Firmware and let
|
||||
* QEMU idle the host too.
|
||||
*/
|
||||
|
||||
int running_on_qemu __read_mostly;
|
||||
|
||||
void __cpuidle arch_cpu_idle_dead(void)
|
||||
{
|
||||
/* nop on real hardware, qemu will offline CPU. */
|
||||
asm volatile("or %%r31,%%r31,%%r31\n":::);
|
||||
}
|
||||
|
||||
void __cpuidle arch_cpu_idle(void)
|
||||
{
|
||||
local_irq_enable();
|
||||
|
||||
/* nop on real hardware, qemu will idle sleep. */
|
||||
asm volatile("or %%r10,%%r10,%%r10\n":::);
|
||||
}
|
||||
|
||||
static int __init parisc_idle_init(void)
|
||||
{
|
||||
const char *marker;
|
||||
|
||||
/* check QEMU/SeaBIOS marker in PAGE0 */
|
||||
marker = (char *) &PAGE0->pad0;
|
||||
running_on_qemu = (memcmp(marker, "SeaBIOS", 8) == 0);
|
||||
|
||||
if (!running_on_qemu)
|
||||
cpu_idle_poll_ctrl(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(parisc_idle_init);
|
||||
|
||||
/*
|
||||
* Copy architecture-specific thread state
|
||||
*/
|
||||
|
@ -631,11 +631,11 @@ void __init mem_init(void)
|
||||
mem_init_print_info(NULL);
|
||||
#ifdef CONFIG_DEBUG_KERNEL /* double-sanity-check paranoia */
|
||||
printk("virtual kernel memory layout:\n"
|
||||
" vmalloc : 0x%p - 0x%p (%4ld MB)\n"
|
||||
" memory : 0x%p - 0x%p (%4ld MB)\n"
|
||||
" .init : 0x%p - 0x%p (%4ld kB)\n"
|
||||
" .data : 0x%p - 0x%p (%4ld kB)\n"
|
||||
" .text : 0x%p - 0x%p (%4ld kB)\n",
|
||||
" vmalloc : 0x%px - 0x%px (%4ld MB)\n"
|
||||
" memory : 0x%px - 0x%px (%4ld MB)\n"
|
||||
" .init : 0x%px - 0x%px (%4ld kB)\n"
|
||||
" .data : 0x%px - 0x%px (%4ld kB)\n"
|
||||
" .text : 0x%px - 0x%px (%4ld kB)\n",
|
||||
|
||||
(void*)VMALLOC_START, (void*)VMALLOC_END,
|
||||
(VMALLOC_END - VMALLOC_START) >> 20,
|
||||
|
@ -209,5 +209,11 @@ exc_##label##_book3e:
|
||||
ori r3,r3,vector_offset@l; \
|
||||
mtspr SPRN_IVOR##vector_number,r3;
|
||||
|
||||
#define RFI_TO_KERNEL \
|
||||
rfi
|
||||
|
||||
#define RFI_TO_USER \
|
||||
rfi
|
||||
|
||||
#endif /* _ASM_POWERPC_EXCEPTION_64E_H */
|
||||
|
||||
|
@ -74,6 +74,59 @@
|
||||
*/
|
||||
#define EX_R3 EX_DAR
|
||||
|
||||
/*
|
||||
* 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
|
||||
#define __EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \
|
||||
mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \
|
||||
@ -218,7 +271,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
|
||||
mtspr SPRN_##h##SRR0,r12; \
|
||||
mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \
|
||||
mtspr SPRN_##h##SRR1,r10; \
|
||||
h##rfid; \
|
||||
h##RFI_TO_KERNEL; \
|
||||
b . /* prevent speculative execution */
|
||||
#define EXCEPTION_PROLOG_PSERIES_1(label, h) \
|
||||
__EXCEPTION_PROLOG_PSERIES_1(label, h)
|
||||
@ -232,7 +285,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
|
||||
mtspr SPRN_##h##SRR0,r12; \
|
||||
mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \
|
||||
mtspr SPRN_##h##SRR1,r10; \
|
||||
h##rfid; \
|
||||
h##RFI_TO_KERNEL; \
|
||||
b . /* prevent speculative execution */
|
||||
|
||||
#define EXCEPTION_PROLOG_PSERIES_1_NORI(label, h) \
|
||||
|
@ -187,7 +187,20 @@ label##3: \
|
||||
FTR_ENTRY_OFFSET label##1b-label##3b; \
|
||||
.popsection;
|
||||
|
||||
#define RFI_FLUSH_FIXUP_SECTION \
|
||||
951: \
|
||||
.pushsection __rfi_flush_fixup,"a"; \
|
||||
.align 2; \
|
||||
952: \
|
||||
FTR_ENTRY_OFFSET 951b-952b; \
|
||||
.popsection;
|
||||
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <linux/types.h>
|
||||
|
||||
extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup;
|
||||
|
||||
void apply_feature_fixups(void);
|
||||
void setup_feature_keys(void);
|
||||
#endif
|
||||
|
@ -241,6 +241,7 @@
|
||||
#define H_GET_HCA_INFO 0x1B8
|
||||
#define H_GET_PERF_COUNT 0x1BC
|
||||
#define H_MANAGE_TRACE 0x1C0
|
||||
#define H_GET_CPU_CHARACTERISTICS 0x1C8
|
||||
#define H_FREE_LOGICAL_LAN_BUFFER 0x1D4
|
||||
#define H_QUERY_INT_STATE 0x1E4
|
||||
#define H_POLL_PENDING 0x1D8
|
||||
@ -330,6 +331,17 @@
|
||||
#define H_SIGNAL_SYS_RESET_ALL_OTHERS -2
|
||||
/* >= 0 values are CPU number */
|
||||
|
||||
/* 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
|
||||
|
||||
/* Flag values used in H_REGISTER_PROC_TBL hcall */
|
||||
#define PROC_TABLE_OP_MASK 0x18
|
||||
#define PROC_TABLE_DEREG 0x10
|
||||
@ -436,6 +448,11 @@ static inline unsigned int get_longbusy_msecs(int longbusy_rc)
|
||||
}
|
||||
}
|
||||
|
||||
struct h_cpu_char_result {
|
||||
u64 character;
|
||||
u64 behaviour;
|
||||
};
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _ASM_POWERPC_HVCALL_H */
|
||||
|
@ -232,6 +232,16 @@ struct paca_struct {
|
||||
struct sibling_subcore_state *sibling_subcore_state;
|
||||
#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[EX_SIZE] __aligned(0x80);
|
||||
void *rfi_flush_fallback_area;
|
||||
u64 l1d_flush_congruence;
|
||||
u64 l1d_flush_sets;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern void copy_mm_to_paca(struct mm_struct *mm);
|
||||
|
@ -326,4 +326,18 @@ static inline long plapr_signal_sys_reset(long cpu)
|
||||
return plpar_hcall_norets(H_SIGNAL_SYS_RESET, cpu);
|
||||
}
|
||||
|
||||
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 */
|
||||
|
@ -39,6 +39,19 @@ static inline void pseries_big_endian_exceptions(void) {}
|
||||
static inline void pseries_little_endian_exceptions(void) {}
|
||||
#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 /* _ASM_POWERPC_SETUP_H */
|
||||
|
@ -237,6 +237,11 @@ int main(void)
|
||||
OFFSET(PACA_NMI_EMERG_SP, paca_struct, nmi_emergency_sp);
|
||||
OFFSET(PACA_IN_MCE, paca_struct, in_mce);
|
||||
OFFSET(PACA_IN_NMI, paca_struct, in_nmi);
|
||||
OFFSET(PACA_RFI_FLUSH_FALLBACK_AREA, paca_struct, rfi_flush_fallback_area);
|
||||
OFFSET(PACA_EXRFI, paca_struct, exrfi);
|
||||
OFFSET(PACA_L1D_FLUSH_CONGRUENCE, paca_struct, l1d_flush_congruence);
|
||||
OFFSET(PACA_L1D_FLUSH_SETS, paca_struct, l1d_flush_sets);
|
||||
|
||||
#endif
|
||||
OFFSET(PACAHWCPUID, paca_struct, hw_cpu_id);
|
||||
OFFSET(PACAKEXECSTATE, paca_struct, kexec_state);
|
||||
|
@ -37,6 +37,11 @@
|
||||
#include <asm/tm.h>
|
||||
#include <asm/ppc-opcode.h>
|
||||
#include <asm/export.h>
|
||||
#ifdef CONFIG_PPC_BOOK3S
|
||||
#include <asm/exception-64s.h>
|
||||
#else
|
||||
#include <asm/exception-64e.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* System calls.
|
||||
@ -262,13 +267,23 @@ BEGIN_FTR_SECTION
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
|
||||
|
||||
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)
|
||||
ld r1,GPR1(r1)
|
||||
mtlr r4
|
||||
mtcr r5
|
||||
mtspr SPRN_SRR0,r7
|
||||
mtspr SPRN_SRR1,r8
|
||||
RFI
|
||||
RFI_TO_KERNEL
|
||||
b . /* prevent speculative execution */
|
||||
|
||||
.Lsyscall_error:
|
||||
@ -397,8 +412,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
|
||||
mtmsrd r10, 1
|
||||
mtspr SPRN_SRR0, r11
|
||||
mtspr SPRN_SRR1, r12
|
||||
|
||||
rfid
|
||||
RFI_TO_USER
|
||||
b . /* prevent speculative execution */
|
||||
#endif
|
||||
_ASM_NOKPROBE_SYMBOL(system_call_common);
|
||||
@ -878,7 +892,7 @@ BEGIN_FTR_SECTION
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
|
||||
ACCOUNT_CPU_USER_EXIT(r13, r2, r4)
|
||||
REST_GPR(13, r1)
|
||||
1:
|
||||
|
||||
mtspr SPRN_SRR1,r3
|
||||
|
||||
ld r2,_CCR(r1)
|
||||
@ -891,8 +905,22 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
|
||||
ld r3,GPR3(r1)
|
||||
ld r4,GPR4(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 */
|
||||
|
||||
#endif /* CONFIG_PPC_BOOK3E */
|
||||
@ -1073,7 +1101,7 @@ __enter_rtas:
|
||||
|
||||
mtspr SPRN_SRR0,r5
|
||||
mtspr SPRN_SRR1,r6
|
||||
rfid
|
||||
RFI_TO_KERNEL
|
||||
b . /* prevent speculative execution */
|
||||
|
||||
rtas_return_loc:
|
||||
@ -1098,7 +1126,7 @@ rtas_return_loc:
|
||||
|
||||
mtspr SPRN_SRR0,r3
|
||||
mtspr SPRN_SRR1,r4
|
||||
rfid
|
||||
RFI_TO_KERNEL
|
||||
b . /* prevent speculative execution */
|
||||
_ASM_NOKPROBE_SYMBOL(__enter_rtas)
|
||||
_ASM_NOKPROBE_SYMBOL(rtas_return_loc)
|
||||
@ -1171,7 +1199,7 @@ _GLOBAL(enter_prom)
|
||||
LOAD_REG_IMMEDIATE(r12, MSR_SF | MSR_ISF | MSR_LE)
|
||||
andc r11,r11,r12
|
||||
mtsrr1 r11
|
||||
rfid
|
||||
RFI_TO_KERNEL
|
||||
#endif /* CONFIG_PPC_BOOK3E */
|
||||
|
||||
1: /* Return from OF */
|
||||
|
@ -256,7 +256,7 @@ BEGIN_FTR_SECTION
|
||||
LOAD_HANDLER(r12, machine_check_handle_early)
|
||||
1: mtspr SPRN_SRR0,r12
|
||||
mtspr SPRN_SRR1,r11
|
||||
rfid
|
||||
RFI_TO_KERNEL
|
||||
b . /* prevent speculative execution */
|
||||
2:
|
||||
/* Stack overflow. Stay on emergency stack and panic.
|
||||
@ -445,7 +445,7 @@ EXC_COMMON_BEGIN(machine_check_handle_early)
|
||||
li r3,MSR_ME
|
||||
andc r10,r10,r3 /* Turn off MSR_ME */
|
||||
mtspr SPRN_SRR1,r10
|
||||
rfid
|
||||
RFI_TO_KERNEL
|
||||
b .
|
||||
2:
|
||||
/*
|
||||
@ -463,7 +463,7 @@ EXC_COMMON_BEGIN(machine_check_handle_early)
|
||||
*/
|
||||
bl machine_check_queue_event
|
||||
MACHINE_CHECK_HANDLER_WINDUP
|
||||
rfid
|
||||
RFI_TO_USER_OR_KERNEL
|
||||
9:
|
||||
/* Deliver the machine check to host kernel in V mode. */
|
||||
MACHINE_CHECK_HANDLER_WINDUP
|
||||
@ -598,6 +598,9 @@ EXC_COMMON_BEGIN(slb_miss_common)
|
||||
stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
|
||||
std r10,PACA_EXSLB+EX_LR(r13) /* save LR */
|
||||
|
||||
andi. r9,r11,MSR_PR // Check for exception from userspace
|
||||
cmpdi cr4,r9,MSR_PR // And save the result in CR4 for later
|
||||
|
||||
/*
|
||||
* Test MSR_RI before calling slb_allocate_realmode, because the
|
||||
* MSR in r11 gets clobbered. However we still want to allocate
|
||||
@ -624,9 +627,12 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX)
|
||||
|
||||
/* All done -- return from exception. */
|
||||
|
||||
bne cr4,1f /* returning to kernel */
|
||||
|
||||
.machine push
|
||||
.machine "power4"
|
||||
mtcrf 0x80,r9
|
||||
mtcrf 0x08,r9 /* MSR[PR] indication is in cr4 */
|
||||
mtcrf 0x04,r9 /* MSR[RI] indication is in cr5 */
|
||||
mtcrf 0x02,r9 /* I/D indication is in cr6 */
|
||||
mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */
|
||||
@ -640,8 +646,29 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX)
|
||||
ld r11,PACA_EXSLB+EX_R11(r13)
|
||||
ld r12,PACA_EXSLB+EX_R12(r13)
|
||||
ld r13,PACA_EXSLB+EX_R13(r13)
|
||||
rfid
|
||||
RFI_TO_USER
|
||||
b . /* prevent speculative execution */
|
||||
1:
|
||||
.machine push
|
||||
.machine "power4"
|
||||
mtcrf 0x80,r9
|
||||
mtcrf 0x08,r9 /* MSR[PR] indication is in cr4 */
|
||||
mtcrf 0x04,r9 /* MSR[RI] indication is in cr5 */
|
||||
mtcrf 0x02,r9 /* I/D indication is in cr6 */
|
||||
mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */
|
||||
.machine pop
|
||||
|
||||
RESTORE_CTR(r9, PACA_EXSLB)
|
||||
RESTORE_PPR_PACA(PACA_EXSLB, r9)
|
||||
mr r3,r12
|
||||
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_KERNEL
|
||||
b . /* prevent speculative execution */
|
||||
|
||||
|
||||
2: std r3,PACA_EXSLB+EX_DAR(r13)
|
||||
mr r3,r12
|
||||
@ -651,7 +678,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX)
|
||||
mtspr SPRN_SRR0,r10
|
||||
ld r10,PACAKMSR(r13)
|
||||
mtspr SPRN_SRR1,r10
|
||||
rfid
|
||||
RFI_TO_KERNEL
|
||||
b .
|
||||
|
||||
8: std r3,PACA_EXSLB+EX_DAR(r13)
|
||||
@ -662,7 +689,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX)
|
||||
mtspr SPRN_SRR0,r10
|
||||
ld r10,PACAKMSR(r13)
|
||||
mtspr SPRN_SRR1,r10
|
||||
rfid
|
||||
RFI_TO_KERNEL
|
||||
b .
|
||||
|
||||
EXC_COMMON_BEGIN(unrecov_slb)
|
||||
@ -901,7 +928,7 @@ EXC_COMMON(trap_0b_common, 0xb00, unknown_exception)
|
||||
mtspr SPRN_SRR0,r10 ; \
|
||||
ld r10,PACAKMSR(r13) ; \
|
||||
mtspr SPRN_SRR1,r10 ; \
|
||||
rfid ; \
|
||||
RFI_TO_KERNEL ; \
|
||||
b . ; /* prevent speculative execution */
|
||||
|
||||
#ifdef CONFIG_PPC_FAST_ENDIAN_SWITCH
|
||||
@ -917,7 +944,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) \
|
||||
xori r12,r12,MSR_LE ; \
|
||||
mtspr SPRN_SRR1,r12 ; \
|
||||
mr r13,r9 ; \
|
||||
rfid ; /* return to userspace */ \
|
||||
RFI_TO_USER ; /* return to userspace */ \
|
||||
b . ; /* prevent speculative execution */
|
||||
#else
|
||||
#define SYSCALL_FASTENDIAN_TEST
|
||||
@ -1063,7 +1090,7 @@ TRAMP_REAL_BEGIN(hmi_exception_early)
|
||||
mtcr r11
|
||||
REST_GPR(11, r1)
|
||||
ld r1,GPR1(r1)
|
||||
hrfid
|
||||
HRFI_TO_USER_OR_KERNEL
|
||||
|
||||
1: mtcr r11
|
||||
REST_GPR(11, r1)
|
||||
@ -1314,7 +1341,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
|
||||
ld r11,PACA_EXGEN+EX_R11(r13)
|
||||
ld r12,PACA_EXGEN+EX_R12(r13)
|
||||
ld r13,PACA_EXGEN+EX_R13(r13)
|
||||
HRFID
|
||||
HRFI_TO_UNKNOWN
|
||||
b .
|
||||
#endif
|
||||
|
||||
@ -1418,10 +1445,94 @@ masked_##_H##interrupt: \
|
||||
ld r10,PACA_EXGEN+EX_R10(r13); \
|
||||
ld r11,PACA_EXGEN+EX_R11(r13); \
|
||||
/* returns to kernel where r13 must be set up, so don't restore it */ \
|
||||
##_H##rfid; \
|
||||
##_H##RFI_TO_KERNEL; \
|
||||
b .; \
|
||||
MASKED_DEC_HANDLER(_H)
|
||||
|
||||
TRAMP_REAL_BEGIN(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)
|
||||
std r12,PACA_EXRFI+EX_R12(r13)
|
||||
std r8,PACA_EXRFI+EX_R13(r13)
|
||||
mfctr r9
|
||||
ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13)
|
||||
ld r11,PACA_L1D_FLUSH_SETS(r13)
|
||||
ld r12,PACA_L1D_FLUSH_CONGRUENCE(r13)
|
||||
/*
|
||||
* The load adresses are at staggered offsets within cachelines,
|
||||
* which suits some pipelines better (on others it should not
|
||||
* hurt).
|
||||
*/
|
||||
addi r12,r12,8
|
||||
mtctr r11
|
||||
DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */
|
||||
|
||||
/* order ld/st prior to dcbt stop all streams with flushing */
|
||||
sync
|
||||
1: li r8,0
|
||||
.rept 8 /* 8-way set associative */
|
||||
ldx r11,r10,r8
|
||||
add r8,r8,r12
|
||||
xor r11,r11,r11 // Ensure r11 is 0 even if fallback area is not
|
||||
add r8,r8,r11 // Add 0, this creates a dependency on the ldx
|
||||
.endr
|
||||
addi r10,r10,128 /* 128 byte cache line */
|
||||
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)
|
||||
ld r12,PACA_EXRFI+EX_R12(r13)
|
||||
ld r8,PACA_EXRFI+EX_R13(r13)
|
||||
GET_SCRATCH0(r13);
|
||||
rfid
|
||||
|
||||
TRAMP_REAL_BEGIN(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)
|
||||
std r12,PACA_EXRFI+EX_R12(r13)
|
||||
std r8,PACA_EXRFI+EX_R13(r13)
|
||||
mfctr r9
|
||||
ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13)
|
||||
ld r11,PACA_L1D_FLUSH_SETS(r13)
|
||||
ld r12,PACA_L1D_FLUSH_CONGRUENCE(r13)
|
||||
/*
|
||||
* The load adresses are at staggered offsets within cachelines,
|
||||
* which suits some pipelines better (on others it should not
|
||||
* hurt).
|
||||
*/
|
||||
addi r12,r12,8
|
||||
mtctr r11
|
||||
DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */
|
||||
|
||||
/* order ld/st prior to dcbt stop all streams with flushing */
|
||||
sync
|
||||
1: li r8,0
|
||||
.rept 8 /* 8-way set associative */
|
||||
ldx r11,r10,r8
|
||||
add r8,r8,r12
|
||||
xor r11,r11,r11 // Ensure r11 is 0 even if fallback area is not
|
||||
add r8,r8,r11 // Add 0, this creates a dependency on the ldx
|
||||
.endr
|
||||
addi r10,r10,128 /* 128 byte cache line */
|
||||
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)
|
||||
ld r12,PACA_EXRFI+EX_R12(r13)
|
||||
ld r8,PACA_EXRFI+EX_R13(r13)
|
||||
GET_SCRATCH0(r13);
|
||||
hrfid
|
||||
|
||||
/*
|
||||
* Real mode exceptions actually use this too, but alternate
|
||||
* instruction code patches (which end up in the common .text area)
|
||||
@ -1441,7 +1552,7 @@ TRAMP_REAL_BEGIN(kvmppc_skip_interrupt)
|
||||
addi r13, r13, 4
|
||||
mtspr SPRN_SRR0, r13
|
||||
GET_SCRATCH0(r13)
|
||||
rfid
|
||||
RFI_TO_KERNEL
|
||||
b .
|
||||
|
||||
TRAMP_REAL_BEGIN(kvmppc_skip_Hinterrupt)
|
||||
@ -1453,7 +1564,7 @@ TRAMP_REAL_BEGIN(kvmppc_skip_Hinterrupt)
|
||||
addi r13, r13, 4
|
||||
mtspr SPRN_HSRR0, r13
|
||||
GET_SCRATCH0(r13)
|
||||
hrfid
|
||||
HRFI_TO_KERNEL
|
||||
b .
|
||||
#endif
|
||||
|
||||
|
@ -801,3 +801,104 @@ static int __init disable_hardlockup_detector(void)
|
||||
return 0;
|
||||
}
|
||||
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.l1d.size;
|
||||
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) {
|
||||
/*
|
||||
* The fallback flush is currently coded for 8-way
|
||||
* associativity. Different associativity is possible, but it
|
||||
* will be treated as 8-way and may not evict the lines as
|
||||
* effectively.
|
||||
*
|
||||
* 128 byte lines are mandatory.
|
||||
*/
|
||||
u64 c = l1d_size / 8;
|
||||
|
||||
paca[cpu].rfi_flush_fallback_area = l1d_flush_fallback_area;
|
||||
paca[cpu].l1d_flush_congruence = c;
|
||||
paca[cpu].l1d_flush_sets = c / 128;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
#endif /* CONFIG_PPC_BOOK3S_64 */
|
||||
|
@ -132,6 +132,15 @@ SECTIONS
|
||||
/* Read-only data */
|
||||
RO_DATA(PAGE_SIZE)
|
||||
|
||||
#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)
|
||||
|
||||
NOTES :kernel :notes
|
||||
|
@ -235,6 +235,7 @@ static int kvmppc_mmu_book3s_64_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
|
||||
gpte->may_read = true;
|
||||
gpte->may_write = true;
|
||||
gpte->page_size = MMU_PAGE_4K;
|
||||
gpte->wimg = HPTE_R_M;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -65,11 +65,17 @@ struct kvm_resize_hpt {
|
||||
u32 order;
|
||||
|
||||
/* These fields protected by kvm->lock */
|
||||
int error;
|
||||
bool prepare_done;
|
||||
|
||||
/* Private to the work thread, until prepare_done is true,
|
||||
* then protected by kvm->resize_hpt_sem */
|
||||
/* Possible values and their usage:
|
||||
* <0 an error occurred during allocation,
|
||||
* -EBUSY allocation is in the progress,
|
||||
* 0 allocation made successfuly.
|
||||
*/
|
||||
int error;
|
||||
|
||||
/* Private to the work thread, until error != -EBUSY,
|
||||
* then protected by kvm->lock.
|
||||
*/
|
||||
struct kvm_hpt_info hpt;
|
||||
};
|
||||
|
||||
@ -159,8 +165,6 @@ long kvmppc_alloc_reset_hpt(struct kvm *kvm, int order)
|
||||
* Reset all the reverse-mapping chains for all memslots
|
||||
*/
|
||||
kvmppc_rmap_reset(kvm);
|
||||
/* Ensure that each vcpu will flush its TLB on next entry. */
|
||||
cpumask_setall(&kvm->arch.need_tlb_flush);
|
||||
err = 0;
|
||||
goto out;
|
||||
}
|
||||
@ -176,6 +180,10 @@ long kvmppc_alloc_reset_hpt(struct kvm *kvm, int order)
|
||||
kvmppc_set_hpt(kvm, &info);
|
||||
|
||||
out:
|
||||
if (err == 0)
|
||||
/* Ensure that each vcpu will flush its TLB on next entry. */
|
||||
cpumask_setall(&kvm->arch.need_tlb_flush);
|
||||
|
||||
mutex_unlock(&kvm->lock);
|
||||
return err;
|
||||
}
|
||||
@ -1413,16 +1421,20 @@ static void resize_hpt_pivot(struct kvm_resize_hpt *resize)
|
||||
|
||||
static void resize_hpt_release(struct kvm *kvm, struct kvm_resize_hpt *resize)
|
||||
{
|
||||
BUG_ON(kvm->arch.resize_hpt != resize);
|
||||
if (WARN_ON(!mutex_is_locked(&kvm->lock)))
|
||||
return;
|
||||
|
||||
if (!resize)
|
||||
return;
|
||||
|
||||
if (resize->hpt.virt)
|
||||
kvmppc_free_hpt(&resize->hpt);
|
||||
if (resize->error != -EBUSY) {
|
||||
if (resize->hpt.virt)
|
||||
kvmppc_free_hpt(&resize->hpt);
|
||||
kfree(resize);
|
||||
}
|
||||
|
||||
kvm->arch.resize_hpt = NULL;
|
||||
kfree(resize);
|
||||
if (kvm->arch.resize_hpt == resize)
|
||||
kvm->arch.resize_hpt = NULL;
|
||||
}
|
||||
|
||||
static void resize_hpt_prepare_work(struct work_struct *work)
|
||||
@ -1431,17 +1443,41 @@ static void resize_hpt_prepare_work(struct work_struct *work)
|
||||
struct kvm_resize_hpt,
|
||||
work);
|
||||
struct kvm *kvm = resize->kvm;
|
||||
int err;
|
||||
int err = 0;
|
||||
|
||||
resize_hpt_debug(resize, "resize_hpt_prepare_work(): order = %d\n",
|
||||
resize->order);
|
||||
|
||||
err = resize_hpt_allocate(resize);
|
||||
if (WARN_ON(resize->error != -EBUSY))
|
||||
return;
|
||||
|
||||
mutex_lock(&kvm->lock);
|
||||
|
||||
/* Request is still current? */
|
||||
if (kvm->arch.resize_hpt == resize) {
|
||||
/* We may request large allocations here:
|
||||
* do not sleep with kvm->lock held for a while.
|
||||
*/
|
||||
mutex_unlock(&kvm->lock);
|
||||
|
||||
resize_hpt_debug(resize, "resize_hpt_prepare_work(): order = %d\n",
|
||||
resize->order);
|
||||
|
||||
err = resize_hpt_allocate(resize);
|
||||
|
||||
/* We have strict assumption about -EBUSY
|
||||
* when preparing for HPT resize.
|
||||
*/
|
||||
if (WARN_ON(err == -EBUSY))
|
||||
err = -EINPROGRESS;
|
||||
|
||||
mutex_lock(&kvm->lock);
|
||||
/* It is possible that kvm->arch.resize_hpt != resize
|
||||
* after we grab kvm->lock again.
|
||||
*/
|
||||
}
|
||||
|
||||
resize->error = err;
|
||||
resize->prepare_done = true;
|
||||
|
||||
if (kvm->arch.resize_hpt != resize)
|
||||
resize_hpt_release(kvm, resize);
|
||||
|
||||
mutex_unlock(&kvm->lock);
|
||||
}
|
||||
@ -1466,14 +1502,12 @@ long kvm_vm_ioctl_resize_hpt_prepare(struct kvm *kvm,
|
||||
|
||||
if (resize) {
|
||||
if (resize->order == shift) {
|
||||
/* Suitable resize in progress */
|
||||
if (resize->prepare_done) {
|
||||
ret = resize->error;
|
||||
if (ret != 0)
|
||||
resize_hpt_release(kvm, resize);
|
||||
} else {
|
||||
/* Suitable resize in progress? */
|
||||
ret = resize->error;
|
||||
if (ret == -EBUSY)
|
||||
ret = 100; /* estimated time in ms */
|
||||
}
|
||||
else if (ret)
|
||||
resize_hpt_release(kvm, resize);
|
||||
|
||||
goto out;
|
||||
}
|
||||
@ -1493,6 +1527,8 @@ long kvm_vm_ioctl_resize_hpt_prepare(struct kvm *kvm,
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
resize->error = -EBUSY;
|
||||
resize->order = shift;
|
||||
resize->kvm = kvm;
|
||||
INIT_WORK(&resize->work, resize_hpt_prepare_work);
|
||||
@ -1547,16 +1583,12 @@ long kvm_vm_ioctl_resize_hpt_commit(struct kvm *kvm,
|
||||
if (!resize || (resize->order != shift))
|
||||
goto out;
|
||||
|
||||
ret = -EBUSY;
|
||||
if (!resize->prepare_done)
|
||||
goto out;
|
||||
|
||||
ret = resize->error;
|
||||
if (ret != 0)
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = resize_hpt_rehash(resize);
|
||||
if (ret != 0)
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
resize_hpt_pivot(resize);
|
||||
|
@ -79,7 +79,7 @@ _GLOBAL_TOC(kvmppc_hv_entry_trampoline)
|
||||
mtmsrd r0,1 /* clear RI in MSR */
|
||||
mtsrr0 r5
|
||||
mtsrr1 r6
|
||||
RFI
|
||||
RFI_TO_KERNEL
|
||||
|
||||
kvmppc_call_hv_entry:
|
||||
BEGIN_FTR_SECTION
|
||||
@ -199,7 +199,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
|
||||
mtmsrd r6, 1 /* Clear RI in MSR */
|
||||
mtsrr0 r8
|
||||
mtsrr1 r7
|
||||
RFI
|
||||
RFI_TO_KERNEL
|
||||
|
||||
/* Virtual-mode return */
|
||||
.Lvirt_return:
|
||||
@ -1167,8 +1167,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
|
||||
|
||||
ld r0, VCPU_GPR(R0)(r4)
|
||||
ld r4, VCPU_GPR(R4)(r4)
|
||||
|
||||
hrfid
|
||||
HRFI_TO_GUEST
|
||||
b .
|
||||
|
||||
secondary_too_late:
|
||||
@ -3320,7 +3319,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_RADIX)
|
||||
ld r4, PACAKMSR(r13)
|
||||
mtspr SPRN_SRR0, r3
|
||||
mtspr SPRN_SRR1, r4
|
||||
rfid
|
||||
RFI_TO_KERNEL
|
||||
9: addi r3, r1, STACK_FRAME_OVERHEAD
|
||||
bl kvmppc_bad_interrupt
|
||||
b 9b
|
||||
|
@ -60,6 +60,7 @@ static void kvmppc_giveup_fac(struct kvm_vcpu *vcpu, ulong fac);
|
||||
#define MSR_USER32 MSR_USER
|
||||
#define MSR_USER64 MSR_USER
|
||||
#define HW_PAGE_SIZE PAGE_SIZE
|
||||
#define HPTE_R_M _PAGE_COHERENT
|
||||
#endif
|
||||
|
||||
static bool kvmppc_is_split_real(struct kvm_vcpu *vcpu)
|
||||
@ -557,6 +558,7 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu,
|
||||
pte.eaddr = eaddr;
|
||||
pte.vpage = eaddr >> 12;
|
||||
pte.page_size = MMU_PAGE_64K;
|
||||
pte.wimg = HPTE_R_M;
|
||||
}
|
||||
|
||||
switch (kvmppc_get_msr(vcpu) & (MSR_DR|MSR_IR)) {
|
||||
|
@ -46,6 +46,9 @@
|
||||
|
||||
#define FUNC(name) name
|
||||
|
||||
#define RFI_TO_KERNEL RFI
|
||||
#define RFI_TO_GUEST RFI
|
||||
|
||||
.macro INTERRUPT_TRAMPOLINE intno
|
||||
|
||||
.global kvmppc_trampoline_\intno
|
||||
@ -141,7 +144,7 @@ kvmppc_handler_skip_ins:
|
||||
GET_SCRATCH0(r13)
|
||||
|
||||
/* And get back into the code */
|
||||
RFI
|
||||
RFI_TO_KERNEL
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -164,6 +167,6 @@ _GLOBAL_TOC(kvmppc_entry_trampoline)
|
||||
ori r5, r5, MSR_EE
|
||||
mtsrr0 r7
|
||||
mtsrr1 r6
|
||||
RFI
|
||||
RFI_TO_KERNEL
|
||||
|
||||
#include "book3s_segment.S"
|
||||
|
@ -156,7 +156,7 @@ no_dcbz32_on:
|
||||
PPC_LL r9, SVCPU_R9(r3)
|
||||
PPC_LL r3, (SVCPU_R3)(r3)
|
||||
|
||||
RFI
|
||||
RFI_TO_GUEST
|
||||
kvmppc_handler_trampoline_enter_end:
|
||||
|
||||
|
||||
@ -407,5 +407,5 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
|
||||
cmpwi r12, BOOK3S_INTERRUPT_DOORBELL
|
||||
beqa BOOK3S_INTERRUPT_DOORBELL
|
||||
|
||||
RFI
|
||||
RFI_TO_KERNEL
|
||||
kvmppc_handler_trampoline_exit_end:
|
||||
|
@ -116,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)
|
||||
{
|
||||
long *start, *end;
|
||||
|
@ -145,6 +145,11 @@ static noinline int bad_area(struct pt_regs *regs, unsigned long address)
|
||||
return __bad_area(regs, address, SEGV_MAPERR);
|
||||
}
|
||||
|
||||
static noinline int bad_access(struct pt_regs *regs, unsigned long address)
|
||||
{
|
||||
return __bad_area(regs, address, SEGV_ACCERR);
|
||||
}
|
||||
|
||||
static int do_sigbus(struct pt_regs *regs, unsigned long address,
|
||||
unsigned int fault)
|
||||
{
|
||||
@ -490,7 +495,7 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,
|
||||
|
||||
good_area:
|
||||
if (unlikely(access_error(is_write, is_exec, vma)))
|
||||
return bad_area(regs, address);
|
||||
return bad_access(regs, address);
|
||||
|
||||
/*
|
||||
* If for any reason at all we couldn't handle the fault,
|
||||
|
@ -37,13 +37,62 @@
|
||||
#include <asm/kexec.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/tm.h>
|
||||
#include <asm/setup.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)
|
||||
{
|
||||
set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT);
|
||||
|
||||
pnv_setup_rfi_flush();
|
||||
|
||||
/* Initialize SMP */
|
||||
pnv_smp_init();
|
||||
|
||||
|
@ -574,11 +574,26 @@ static ssize_t dlpar_show(struct class *class, struct class_attribute *attr,
|
||||
|
||||
static CLASS_ATTR_RW(dlpar);
|
||||
|
||||
static int __init pseries_dlpar_init(void)
|
||||
int __init dlpar_workqueue_init(void)
|
||||
{
|
||||
if (pseries_hp_wq)
|
||||
return 0;
|
||||
|
||||
pseries_hp_wq = alloc_workqueue("pseries hotplug workqueue",
|
||||
WQ_UNBOUND, 1);
|
||||
WQ_UNBOUND, 1);
|
||||
|
||||
return pseries_hp_wq ? 0 : -ENOMEM;
|
||||
}
|
||||
|
||||
static int __init dlpar_sysfs_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = dlpar_workqueue_init();
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
return sysfs_create_file(kernel_kobj, &class_attr_dlpar.attr);
|
||||
}
|
||||
machine_device_initcall(pseries, pseries_dlpar_init);
|
||||
machine_device_initcall(pseries, dlpar_sysfs_init);
|
||||
|
||||
|
@ -98,4 +98,6 @@ static inline unsigned long cmo_get_page_size(void)
|
||||
return CMO_PageSize;
|
||||
}
|
||||
|
||||
int dlpar_workqueue_init(void);
|
||||
|
||||
#endif /* _PSERIES_PSERIES_H */
|
||||
|
@ -69,7 +69,8 @@ static int __init init_ras_IRQ(void)
|
||||
/* Hotplug Events */
|
||||
np = of_find_node_by_path("/event-sources/hot-plug-events");
|
||||
if (np != NULL) {
|
||||
request_event_sources_irqs(np, ras_hotplug_interrupt,
|
||||
if (dlpar_workqueue_init() == 0)
|
||||
request_event_sources_irqs(np, ras_hotplug_interrupt,
|
||||
"RAS_HOTPLUG");
|
||||
of_node_put(np);
|
||||
}
|
||||
|
@ -459,6 +459,39 @@ static void __init find_and_init_phbs(void)
|
||||
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)
|
||||
{
|
||||
set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT);
|
||||
@ -476,6 +509,8 @@ static void __init pSeries_setup_arch(void)
|
||||
|
||||
fwnmi_init();
|
||||
|
||||
pseries_setup_rfi_flush();
|
||||
|
||||
/* By default, only probe PCI (can be overridden by rtas_pci) */
|
||||
pci_add_flags(PCI_PROBE_ONLY);
|
||||
|
||||
|
@ -0,0 +1,75 @@
|
||||
CONFIG_SMP=y
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCIE_XILINX=y
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_CGROUPS=y
|
||||
CONFIG_CGROUP_SCHED=y
|
||||
CONFIG_CFS_BANDWIDTH=y
|
||||
CONFIG_CGROUP_BPF=y
|
||||
CONFIG_NAMESPACES=y
|
||||
CONFIG_USER_NS=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_EXPERT=y
|
||||
CONFIG_CHECKPOINT_RESTORE=y
|
||||
CONFIG_BPF_SYSCALL=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_IP_ADVANCED_ROUTER=y
|
||||
CONFIG_IP_PNP=y
|
||||
CONFIG_IP_PNP_DHCP=y
|
||||
CONFIG_IP_PNP_BOOTP=y
|
||||
CONFIG_IP_PNP_RARP=y
|
||||
CONFIG_NETLINK_DIAG=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_VIRTIO_BLK=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_BLK_DEV_SR=y
|
||||
CONFIG_ATA=y
|
||||
CONFIG_SATA_AHCI=y
|
||||
CONFIG_SATA_AHCI_PLATFORM=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_VIRTIO_NET=y
|
||||
CONFIG_MACB=y
|
||||
CONFIG_E1000E=y
|
||||
CONFIG_R8169=y
|
||||
CONFIG_MICROSEMI_PHY=y
|
||||
CONFIG_INPUT_MOUSEDEV=y
|
||||
CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
# CONFIG_PTP_1588_CLOCK is not set
|
||||
CONFIG_DRM=y
|
||||
CONFIG_DRM_RADEON=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_XHCI_HCD=y
|
||||
CONFIG_USB_XHCI_PLATFORM=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_HCD_PLATFORM=y
|
||||
CONFIG_USB_OHCI_HCD=y
|
||||
CONFIG_USB_OHCI_HCD_PLATFORM=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_UAS=y
|
||||
CONFIG_VIRTIO_MMIO=y
|
||||
CONFIG_RAS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_AUTOFS4_FS=y
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_NFS_FS=y
|
||||
CONFIG_NFS_V4=y
|
||||
CONFIG_NFS_V4_1=y
|
||||
CONFIG_NFS_V4_2=y
|
||||
CONFIG_ROOT_NFS=y
|
||||
# CONFIG_RCU_TRACE is not set
|
||||
CONFIG_CRYPTO_USER_API_HASH=y
|
@ -17,10 +17,10 @@
|
||||
#include <linux/const.h>
|
||||
|
||||
/* Status register flags */
|
||||
#define SR_IE _AC(0x00000002, UL) /* Interrupt Enable */
|
||||
#define SR_PIE _AC(0x00000020, UL) /* Previous IE */
|
||||
#define SR_PS _AC(0x00000100, UL) /* Previously Supervisor */
|
||||
#define SR_SUM _AC(0x00040000, UL) /* Supervisor may access User Memory */
|
||||
#define SR_SIE _AC(0x00000002, UL) /* Supervisor Interrupt Enable */
|
||||
#define SR_SPIE _AC(0x00000020, UL) /* Previous Supervisor IE */
|
||||
#define SR_SPP _AC(0x00000100, UL) /* Previously Supervisor */
|
||||
#define SR_SUM _AC(0x00040000, UL) /* Supervisor may access User Memory */
|
||||
|
||||
#define SR_FS _AC(0x00006000, UL) /* Floating-point Status */
|
||||
#define SR_FS_OFF _AC(0x00000000, UL)
|
||||
|
@ -21,8 +21,6 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
|
||||
extern void __iomem *ioremap(phys_addr_t offset, unsigned long size);
|
||||
|
||||
/*
|
||||
@ -36,8 +34,6 @@ extern void __iomem *ioremap(phys_addr_t offset, unsigned long size);
|
||||
|
||||
extern void iounmap(volatile void __iomem *addr);
|
||||
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
/* Generic IO read/write. These perform native-endian accesses. */
|
||||
#define __raw_writeb __raw_writeb
|
||||
static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
|
||||
|
@ -27,25 +27,25 @@ static inline unsigned long arch_local_save_flags(void)
|
||||
/* unconditionally enable interrupts */
|
||||
static inline void arch_local_irq_enable(void)
|
||||
{
|
||||
csr_set(sstatus, SR_IE);
|
||||
csr_set(sstatus, SR_SIE);
|
||||
}
|
||||
|
||||
/* unconditionally disable interrupts */
|
||||
static inline void arch_local_irq_disable(void)
|
||||
{
|
||||
csr_clear(sstatus, SR_IE);
|
||||
csr_clear(sstatus, SR_SIE);
|
||||
}
|
||||
|
||||
/* get status and disable interrupts */
|
||||
static inline unsigned long arch_local_irq_save(void)
|
||||
{
|
||||
return csr_read_clear(sstatus, SR_IE);
|
||||
return csr_read_clear(sstatus, SR_SIE);
|
||||
}
|
||||
|
||||
/* test flags */
|
||||
static inline int arch_irqs_disabled_flags(unsigned long flags)
|
||||
{
|
||||
return !(flags & SR_IE);
|
||||
return !(flags & SR_SIE);
|
||||
}
|
||||
|
||||
/* test hardware interrupt enable bit */
|
||||
@ -57,7 +57,7 @@ static inline int arch_irqs_disabled(void)
|
||||
/* set interrupt enabled status */
|
||||
static inline void arch_local_irq_restore(unsigned long flags)
|
||||
{
|
||||
csr_set(sstatus, flags & SR_IE);
|
||||
csr_set(sstatus, flags & SR_SIE);
|
||||
}
|
||||
|
||||
#endif /* _ASM_RISCV_IRQFLAGS_H */
|
||||
|
@ -20,8 +20,6 @@
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
|
||||
/* Page Upper Directory not used in RISC-V */
|
||||
#include <asm-generic/pgtable-nopud.h>
|
||||
#include <asm/page.h>
|
||||
@ -413,8 +411,6 @@ static inline void pgtable_cache_init(void)
|
||||
/* No page table caches to initialize */
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
#define VMALLOC_SIZE (KERN_VIRT_SIZE >> 1)
|
||||
#define VMALLOC_END (PAGE_OFFSET - 1)
|
||||
#define VMALLOC_START (PAGE_OFFSET - VMALLOC_SIZE)
|
||||
|
@ -66,7 +66,7 @@ struct pt_regs {
|
||||
#define REG_FMT "%08lx"
|
||||
#endif
|
||||
|
||||
#define user_mode(regs) (((regs)->sstatus & SR_PS) == 0)
|
||||
#define user_mode(regs) (((regs)->sstatus & SR_SPP) == 0)
|
||||
|
||||
|
||||
/* Helpers for working with the instruction pointer */
|
||||
|
@ -15,8 +15,6 @@
|
||||
#ifndef _ASM_RISCV_TLBFLUSH_H
|
||||
#define _ASM_RISCV_TLBFLUSH_H
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
|
||||
#include <linux/mm_types.h>
|
||||
|
||||
/*
|
||||
@ -64,6 +62,4 @@ static inline void flush_tlb_kernel_range(unsigned long start,
|
||||
flush_tlb_all();
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
#endif /* _ASM_RISCV_TLBFLUSH_H */
|
||||
|
@ -127,7 +127,6 @@ extern int fixup_exception(struct pt_regs *state);
|
||||
* call.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
#define __get_user_asm(insn, x, ptr, err) \
|
||||
do { \
|
||||
uintptr_t __tmp; \
|
||||
@ -153,13 +152,11 @@ do { \
|
||||
__disable_user_access(); \
|
||||
(x) = __x; \
|
||||
} while (0)
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
#define __get_user_8(x, ptr, err) \
|
||||
__get_user_asm("ld", x, ptr, err)
|
||||
#else /* !CONFIG_64BIT */
|
||||
#ifdef CONFIG_MMU
|
||||
#define __get_user_8(x, ptr, err) \
|
||||
do { \
|
||||
u32 __user *__ptr = (u32 __user *)(ptr); \
|
||||
@ -193,7 +190,6 @@ do { \
|
||||
(x) = (__typeof__(x))((__typeof__((x)-(x)))( \
|
||||
(((u64)__hi << 32) | __lo))); \
|
||||
} while (0)
|
||||
#endif /* CONFIG_MMU */
|
||||
#endif /* CONFIG_64BIT */
|
||||
|
||||
|
||||
@ -267,8 +263,6 @@ do { \
|
||||
((x) = 0, -EFAULT); \
|
||||
})
|
||||
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
#define __put_user_asm(insn, x, ptr, err) \
|
||||
do { \
|
||||
uintptr_t __tmp; \
|
||||
@ -292,14 +286,11 @@ do { \
|
||||
: "rJ" (__x), "i" (-EFAULT)); \
|
||||
__disable_user_access(); \
|
||||
} while (0)
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
#define __put_user_8(x, ptr, err) \
|
||||
__put_user_asm("sd", x, ptr, err)
|
||||
#else /* !CONFIG_64BIT */
|
||||
#ifdef CONFIG_MMU
|
||||
#define __put_user_8(x, ptr, err) \
|
||||
do { \
|
||||
u32 __user *__ptr = (u32 __user *)(ptr); \
|
||||
@ -329,7 +320,6 @@ do { \
|
||||
: "rJ" (__x), "rJ" (__x >> 32), "i" (-EFAULT)); \
|
||||
__disable_user_access(); \
|
||||
} while (0)
|
||||
#endif /* CONFIG_MMU */
|
||||
#endif /* CONFIG_64BIT */
|
||||
|
||||
|
||||
@ -438,7 +428,6 @@ unsigned long __must_check clear_user(void __user *to, unsigned long n)
|
||||
* will set "err" to -EFAULT, while successful accesses return the previous
|
||||
* value.
|
||||
*/
|
||||
#ifdef CONFIG_MMU
|
||||
#define __cmpxchg_user(ptr, old, new, err, size, lrb, scb) \
|
||||
({ \
|
||||
__typeof__(ptr) __ptr = (ptr); \
|
||||
@ -508,6 +497,5 @@ unsigned long __must_check clear_user(void __user *to, unsigned long n)
|
||||
(err) = __err; \
|
||||
__ret; \
|
||||
})
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
#endif /* _ASM_RISCV_UACCESS_H */
|
||||
|
@ -14,3 +14,4 @@
|
||||
#define __ARCH_HAVE_MMU
|
||||
#define __ARCH_WANT_SYS_CLONE
|
||||
#include <uapi/asm/unistd.h>
|
||||
#include <uapi/asm/syscalls.h>
|
||||
|
@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 SiFive
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _ASM_RISCV_VDSO_SYSCALLS_H
|
||||
#define _ASM_RISCV_VDSO_SYSCALLS_H
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
/* These syscalls are only used by the vDSO and are not in the uapi. */
|
||||
#define __NR_riscv_flush_icache (__NR_arch_specific_syscall + 15)
|
||||
__SYSCALL(__NR_riscv_flush_icache, sys_riscv_flush_icache)
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_RISCV_VDSO_H */
|
26
arch/riscv/include/uapi/asm/syscalls.h
Normal file
26
arch/riscv/include/uapi/asm/syscalls.h
Normal file
@ -0,0 +1,26 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2017 SiFive
|
||||
*/
|
||||
|
||||
#ifndef _ASM__UAPI__SYSCALLS_H
|
||||
#define _ASM__UAPI__SYSCALLS_H
|
||||
|
||||
/*
|
||||
* Allows the instruction cache to be flushed from userspace. Despite RISC-V
|
||||
* having a direct 'fence.i' instruction available to userspace (which we
|
||||
* can't trap!), that's not actually viable when running on Linux because the
|
||||
* kernel might schedule a process on another hart. There is no way for
|
||||
* userspace to handle this without invoking the kernel (as it doesn't know the
|
||||
* thread->hart mappings), so we've defined a RISC-V specific system call to
|
||||
* flush the instruction cache.
|
||||
*
|
||||
* __NR_riscv_flush_icache is defined to flush the instruction cache over an
|
||||
* address range, with the flush applying to either all threads or just the
|
||||
* caller. We don't currently do anything with the address range, that's just
|
||||
* in there for forwards compatibility.
|
||||
*/
|
||||
#define __NR_riscv_flush_icache (__NR_arch_specific_syscall + 15)
|
||||
__SYSCALL(__NR_riscv_flush_icache, sys_riscv_flush_icache)
|
||||
|
||||
#endif
|
@ -196,7 +196,7 @@ handle_syscall:
|
||||
addi s2, s2, 0x4
|
||||
REG_S s2, PT_SEPC(sp)
|
||||
/* System calls run with interrupts enabled */
|
||||
csrs sstatus, SR_IE
|
||||
csrs sstatus, SR_SIE
|
||||
/* Trace syscalls, but only if requested by the user. */
|
||||
REG_L t0, TASK_TI_FLAGS(tp)
|
||||
andi t0, t0, _TIF_SYSCALL_TRACE
|
||||
@ -224,8 +224,8 @@ ret_from_syscall:
|
||||
|
||||
ret_from_exception:
|
||||
REG_L s0, PT_SSTATUS(sp)
|
||||
csrc sstatus, SR_IE
|
||||
andi s0, s0, SR_PS
|
||||
csrc sstatus, SR_SIE
|
||||
andi s0, s0, SR_SPP
|
||||
bnez s0, restore_all
|
||||
|
||||
resume_userspace:
|
||||
@ -255,7 +255,7 @@ work_pending:
|
||||
bnez s1, work_resched
|
||||
work_notifysig:
|
||||
/* Handle pending signals and notify-resume requests */
|
||||
csrs sstatus, SR_IE /* Enable interrupts for do_notify_resume() */
|
||||
csrs sstatus, SR_SIE /* Enable interrupts for do_notify_resume() */
|
||||
move a0, sp /* pt_regs */
|
||||
move a1, s0 /* current_thread_info->flags */
|
||||
tail do_notify_resume
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user