mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 22:14:04 +02:00
Linux 5.3-rc4
-----BEGIN PGP SIGNATURE----- iQFSBAABCAA8FiEEq68RxlopcLEwq+PEeb4+QwBBGIYFAl1QegseHHRvcnZhbGRz QGxpbnV4LWZvdW5kYXRpb24ub3JnAAoJEHm+PkMAQRiGavMH/RBaR39ct3XXpPzC yxmKJn/n692NXFKusfsfasitGHMdFom6HaCcKx4PpzX1QHnR34LJtMd1QvwM8cHz FtbC68HyZBB91JOUzC38GbRufvVUsSeXg8YeBiF6BOoOP06OcOG+DKoPcKBOMXsR MtJmgxEyedLT7ozEPTpowVBWulELJxkbe1MCc93xDXdOqT+aMuxZBASMJIgrufS7 uJTsJ/afHz6F29Mj6Q9lfIJJSHqSfMK/rPGP54xRdBgMWmAmNjA2aExyCK8PE/Yb TChsrDjDz38ePuVaWfjtwFNWlWcq0Do8vJdPuAxZDdfaJlQDXQHCWXsJjrWD6oNy ZhCq0zE= =HcEO -----END PGP SIGNATURE----- Merge 5.3-rc4 into android-mainline. Merge 5.3-rc4 into android-mainline. Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I09aa35f99fbc876687f3778458f833d2573a7f1a
This commit is contained in:
commit
41f0b8f4d3
|
|
@ -41,10 +41,11 @@ Related CVEs
|
|||
|
||||
The following CVE entries describe Spectre variants:
|
||||
|
||||
============= ======================= =================
|
||||
============= ======================= ==========================
|
||||
CVE-2017-5753 Bounds check bypass Spectre variant 1
|
||||
CVE-2017-5715 Branch target injection Spectre variant 2
|
||||
============= ======================= =================
|
||||
CVE-2019-1125 Spectre v1 swapgs Spectre variant 1 (swapgs)
|
||||
============= ======================= ==========================
|
||||
|
||||
Problem
|
||||
-------
|
||||
|
|
@ -78,6 +79,13 @@ There are some extensions of Spectre variant 1 attacks for reading data
|
|||
over the network, see :ref:`[12] <spec_ref12>`. However such attacks
|
||||
are difficult, low bandwidth, fragile, and are considered low risk.
|
||||
|
||||
Note that, despite "Bounds Check Bypass" name, Spectre variant 1 is not
|
||||
only about user-controlled array bounds checks. It can affect any
|
||||
conditional checks. The kernel entry code interrupt, exception, and NMI
|
||||
handlers all have conditional swapgs checks. Those may be problematic
|
||||
in the context of Spectre v1, as kernel code can speculatively run with
|
||||
a user GS.
|
||||
|
||||
Spectre variant 2 (Branch Target Injection)
|
||||
-------------------------------------------
|
||||
|
||||
|
|
@ -132,6 +140,9 @@ not cover all possible attack vectors.
|
|||
1. A user process attacking the kernel
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Spectre variant 1
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
The attacker passes a parameter to the kernel via a register or
|
||||
via a known address in memory during a syscall. Such parameter may
|
||||
be used later by the kernel as an index to an array or to derive
|
||||
|
|
@ -144,7 +155,40 @@ not cover all possible attack vectors.
|
|||
potentially be influenced for Spectre attacks, new "nospec" accessor
|
||||
macros are used to prevent speculative loading of data.
|
||||
|
||||
Spectre variant 2 attacker can :ref:`poison <poison_btb>` the branch
|
||||
Spectre variant 1 (swapgs)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
An attacker can train the branch predictor to speculatively skip the
|
||||
swapgs path for an interrupt or exception. If they initialize
|
||||
the GS register to a user-space value, if the swapgs is speculatively
|
||||
skipped, subsequent GS-related percpu accesses in the speculation
|
||||
window will be done with the attacker-controlled GS value. This
|
||||
could cause privileged memory to be accessed and leaked.
|
||||
|
||||
For example:
|
||||
|
||||
::
|
||||
|
||||
if (coming from user space)
|
||||
swapgs
|
||||
mov %gs:<percpu_offset>, %reg
|
||||
mov (%reg), %reg1
|
||||
|
||||
When coming from user space, the CPU can speculatively skip the
|
||||
swapgs, and then do a speculative percpu load using the user GS
|
||||
value. So the user can speculatively force a read of any kernel
|
||||
value. If a gadget exists which uses the percpu value as an address
|
||||
in another load/store, then the contents of the kernel value may
|
||||
become visible via an L1 side channel attack.
|
||||
|
||||
A similar attack exists when coming from kernel space. The CPU can
|
||||
speculatively do the swapgs, causing the user GS to get used for the
|
||||
rest of the speculative window.
|
||||
|
||||
Spectre variant 2
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
A spectre variant 2 attacker can :ref:`poison <poison_btb>` the branch
|
||||
target buffer (BTB) before issuing syscall to launch an attack.
|
||||
After entering the kernel, the kernel could use the poisoned branch
|
||||
target buffer on indirect jump and jump to gadget code in speculative
|
||||
|
|
@ -280,11 +324,18 @@ The sysfs file showing Spectre variant 1 mitigation status is:
|
|||
|
||||
The possible values in this file are:
|
||||
|
||||
======================================= =================================
|
||||
'Mitigation: __user pointer sanitation' Protection in kernel on a case by
|
||||
case base with explicit pointer
|
||||
sanitation.
|
||||
======================================= =================================
|
||||
.. list-table::
|
||||
|
||||
* - 'Not affected'
|
||||
- The processor is not vulnerable.
|
||||
* - 'Vulnerable: __user pointer sanitization and usercopy barriers only; no swapgs barriers'
|
||||
- The swapgs protections are disabled; otherwise it has
|
||||
protection in the kernel on a case by case base with explicit
|
||||
pointer sanitation and usercopy LFENCE barriers.
|
||||
* - 'Mitigation: usercopy/swapgs barriers and __user pointer sanitization'
|
||||
- Protection in the kernel on a case by case base with explicit
|
||||
pointer sanitation, usercopy LFENCE barriers, and swapgs LFENCE
|
||||
barriers.
|
||||
|
||||
However, the protections are put in place on a case by case basis,
|
||||
and there is no guarantee that all possible attack vectors for Spectre
|
||||
|
|
@ -366,12 +417,27 @@ Turning on mitigation for Spectre variant 1 and Spectre variant 2
|
|||
1. Kernel mitigation
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Spectre variant 1
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
For the Spectre variant 1, vulnerable kernel code (as determined
|
||||
by code audit or scanning tools) is annotated on a case by case
|
||||
basis to use nospec accessor macros for bounds clipping :ref:`[2]
|
||||
<spec_ref2>` to avoid any usable disclosure gadgets. However, it may
|
||||
not cover all attack vectors for Spectre variant 1.
|
||||
|
||||
Copy-from-user code has an LFENCE barrier to prevent the access_ok()
|
||||
check from being mis-speculated. The barrier is done by the
|
||||
barrier_nospec() macro.
|
||||
|
||||
For the swapgs variant of Spectre variant 1, LFENCE barriers are
|
||||
added to interrupt, exception and NMI entry where needed. These
|
||||
barriers are done by the FENCE_SWAPGS_KERNEL_ENTRY and
|
||||
FENCE_SWAPGS_USER_ENTRY macros.
|
||||
|
||||
Spectre variant 2
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
For Spectre variant 2 mitigation, the compiler turns indirect calls or
|
||||
jumps in the kernel into equivalent return trampolines (retpolines)
|
||||
:ref:`[3] <spec_ref3>` :ref:`[9] <spec_ref9>` to go to the target
|
||||
|
|
@ -473,6 +539,12 @@ Mitigation control on the kernel command line
|
|||
Spectre variant 2 mitigation can be disabled or force enabled at the
|
||||
kernel command line.
|
||||
|
||||
nospectre_v1
|
||||
|
||||
[X86,PPC] Disable mitigations for Spectre Variant 1
|
||||
(bounds check bypass). With this option data leaks are
|
||||
possible in the system.
|
||||
|
||||
nospectre_v2
|
||||
|
||||
[X86] Disable all mitigations for the Spectre variant 2
|
||||
|
|
|
|||
|
|
@ -2604,7 +2604,7 @@
|
|||
expose users to several CPU vulnerabilities.
|
||||
Equivalent to: nopti [X86,PPC]
|
||||
kpti=0 [ARM64]
|
||||
nospectre_v1 [PPC]
|
||||
nospectre_v1 [X86,PPC]
|
||||
nobp=0 [S390]
|
||||
nospectre_v2 [X86,PPC,S390,ARM64]
|
||||
spectre_v2_user=off [X86]
|
||||
|
|
@ -2965,9 +2965,9 @@
|
|||
nosmt=force: Force disable SMT, cannot be undone
|
||||
via the sysfs control file.
|
||||
|
||||
nospectre_v1 [PPC] Disable mitigations for Spectre Variant 1 (bounds
|
||||
check bypass). With this option data leaks are possible
|
||||
in the system.
|
||||
nospectre_v1 [X86,PPC] Disable mitigations for Spectre Variant 1
|
||||
(bounds check bypass). With this option data leaks are
|
||||
possible in the system.
|
||||
|
||||
nospectre_v2 [X86,PPC_FSL_BOOK3E,ARM64] Disable all mitigations for
|
||||
the Spectre variant 2 (indirect branch prediction)
|
||||
|
|
|
|||
|
|
@ -1,162 +0,0 @@
|
|||
===================
|
||||
RISC-V CPU Bindings
|
||||
===================
|
||||
|
||||
The device tree allows to describe the layout of CPUs in a system through
|
||||
the "cpus" node, which in turn contains a number of subnodes (ie "cpu")
|
||||
defining properties for every cpu.
|
||||
|
||||
Bindings for CPU nodes follow the Devicetree Specification, available from:
|
||||
|
||||
https://www.devicetree.org/specifications/
|
||||
|
||||
with updates for 32-bit and 64-bit RISC-V systems provided in this document.
|
||||
|
||||
===========
|
||||
Terminology
|
||||
===========
|
||||
|
||||
This document uses some terminology common to the RISC-V community that is not
|
||||
widely used, the definitions of which are listed here:
|
||||
|
||||
* hart: A hardware execution context, which contains all the state mandated by
|
||||
the RISC-V ISA: a PC and some registers. This terminology is designed to
|
||||
disambiguate software's view of execution contexts from any particular
|
||||
microarchitectural implementation strategy. For example, my Intel laptop is
|
||||
described as having one socket with two cores, each of which has two hyper
|
||||
threads. Therefore this system has four harts.
|
||||
|
||||
=====================================
|
||||
cpus and cpu node bindings definition
|
||||
=====================================
|
||||
|
||||
The RISC-V architecture, in accordance with the Devicetree Specification,
|
||||
requires the cpus and cpu nodes to be present and contain the properties
|
||||
described below.
|
||||
|
||||
- cpus node
|
||||
|
||||
Description: Container of cpu nodes
|
||||
|
||||
The node name must be "cpus".
|
||||
|
||||
A cpus node must define the following properties:
|
||||
|
||||
- #address-cells
|
||||
Usage: required
|
||||
Value type: <u32>
|
||||
Definition: must be set to 1
|
||||
- #size-cells
|
||||
Usage: required
|
||||
Value type: <u32>
|
||||
Definition: must be set to 0
|
||||
|
||||
- cpu node
|
||||
|
||||
Description: Describes a hart context
|
||||
|
||||
PROPERTIES
|
||||
|
||||
- device_type
|
||||
Usage: required
|
||||
Value type: <string>
|
||||
Definition: must be "cpu"
|
||||
- reg
|
||||
Usage: required
|
||||
Value type: <u32>
|
||||
Definition: The hart ID of this CPU node
|
||||
- compatible:
|
||||
Usage: required
|
||||
Value type: <stringlist>
|
||||
Definition: must contain "riscv", may contain one of
|
||||
"sifive,rocket0"
|
||||
- mmu-type:
|
||||
Usage: optional
|
||||
Value type: <string>
|
||||
Definition: Specifies the CPU's MMU type. Possible values are
|
||||
"riscv,sv32"
|
||||
"riscv,sv39"
|
||||
"riscv,sv48"
|
||||
- riscv,isa:
|
||||
Usage: required
|
||||
Value type: <string>
|
||||
Definition: Contains the RISC-V ISA string of this hart. These
|
||||
ISA strings are defined by the RISC-V ISA manual.
|
||||
|
||||
Example: SiFive Freedom U540G Development Kit
|
||||
---------------------------------------------
|
||||
|
||||
This system contains two harts: a hart marked as disabled that's used for
|
||||
low-level system tasks and should be ignored by Linux, and a second hart that
|
||||
Linux is allowed to run on.
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
timebase-frequency = <1000000>;
|
||||
cpu@0 {
|
||||
clock-frequency = <1600000000>;
|
||||
compatible = "sifive,rocket0", "riscv";
|
||||
device_type = "cpu";
|
||||
i-cache-block-size = <64>;
|
||||
i-cache-sets = <128>;
|
||||
i-cache-size = <16384>;
|
||||
next-level-cache = <&L15 &L0>;
|
||||
reg = <0>;
|
||||
riscv,isa = "rv64imac";
|
||||
status = "disabled";
|
||||
L10: interrupt-controller {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "riscv,cpu-intc";
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
cpu@1 {
|
||||
clock-frequency = <1600000000>;
|
||||
compatible = "sifive,rocket0", "riscv";
|
||||
d-cache-block-size = <64>;
|
||||
d-cache-sets = <64>;
|
||||
d-cache-size = <32768>;
|
||||
d-tlb-sets = <1>;
|
||||
d-tlb-size = <32>;
|
||||
device_type = "cpu";
|
||||
i-cache-block-size = <64>;
|
||||
i-cache-sets = <64>;
|
||||
i-cache-size = <32768>;
|
||||
i-tlb-sets = <1>;
|
||||
i-tlb-size = <32>;
|
||||
mmu-type = "riscv,sv39";
|
||||
next-level-cache = <&L15 &L0>;
|
||||
reg = <1>;
|
||||
riscv,isa = "rv64imafdc";
|
||||
status = "okay";
|
||||
tlb-split;
|
||||
L13: interrupt-controller {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "riscv,cpu-intc";
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
Example: Spike ISA Simulator with 1 Hart
|
||||
----------------------------------------
|
||||
|
||||
This device tree matches the Spike ISA golden model as run with `spike -p1`.
|
||||
|
||||
cpus {
|
||||
cpu@0 {
|
||||
device_type = "cpu";
|
||||
reg = <0x00000000>;
|
||||
status = "okay";
|
||||
compatible = "riscv";
|
||||
riscv,isa = "rv64imafdc";
|
||||
mmu-type = "riscv,sv48";
|
||||
clock-frequency = <0x3b9aca00>;
|
||||
interrupt-controller {
|
||||
#interrupt-cells = <0x00000001>;
|
||||
interrupt-controller;
|
||||
compatible = "riscv,cpu-intc";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10,6 +10,18 @@ maintainers:
|
|||
- Paul Walmsley <paul.walmsley@sifive.com>
|
||||
- Palmer Dabbelt <palmer@sifive.com>
|
||||
|
||||
description: |
|
||||
This document uses some terminology common to the RISC-V community
|
||||
that is not widely used, the definitions of which are listed here:
|
||||
|
||||
hart: A hardware execution context, which contains all the state
|
||||
mandated by the RISC-V ISA: a PC and some registers. This
|
||||
terminology is designed to disambiguate software's view of execution
|
||||
contexts from any particular microarchitectural implementation
|
||||
strategy. For example, an Intel laptop containing one socket with
|
||||
two cores, each of which has two hyperthreads, could be described as
|
||||
having four harts.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
|
|
@ -50,6 +62,10 @@ properties:
|
|||
User-Level ISA document, available from
|
||||
https://riscv.org/specifications/
|
||||
|
||||
While the isa strings in ISA specification are case
|
||||
insensitive, letters in the riscv,isa string must be all
|
||||
lowercase to simplify parsing.
|
||||
|
||||
timebase-frequency:
|
||||
type: integer
|
||||
minimum: 1
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ properties:
|
|||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- sifive,freedom-unleashed-a00
|
||||
- sifive,hifive-unleashed-a00
|
||||
- const: sifive,fu540-c000
|
||||
- const: sifive,fu540
|
||||
...
|
||||
|
|
|
|||
|
|
@ -73,7 +73,6 @@ patternProperties:
|
|||
Compatible of the SPI device.
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
minimum: 0
|
||||
maximum: 256
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ a) SMB3 (and SMB3.1.1) missing optional features:
|
|||
- T10 copy offload ie "ODX" (copy chunk, and "Duplicate Extents" ioctl
|
||||
currently the only two server side copy mechanisms supported)
|
||||
|
||||
b) improved sparse file support
|
||||
b) improved sparse file support (fiemap and SEEK_HOLE are implemented
|
||||
but additional features would be supportable by the protocol).
|
||||
|
||||
c) Directory entry caching relies on a 1 second timer, rather than
|
||||
using Directory Leases, currently only the root file handle is cached longer
|
||||
|
|
@ -21,9 +22,13 @@ using Directory Leases, currently only the root file handle is cached longer
|
|||
d) quota support (needs minor kernel change since quota calls
|
||||
to make it to network filesystems or deviceless filesystems)
|
||||
|
||||
e) Additional use cases where we use "compoounding" (e.g. open/query/close
|
||||
and open/setinfo/close) to reduce the number of roundtrips, and also
|
||||
open to reduce redundant opens (using deferred close and reference counts more).
|
||||
e) Additional use cases can be optimized to use "compounding"
|
||||
(e.g. open/query/close and open/setinfo/close) to reduce the number
|
||||
of roundtrips to the server and improve performance. Various cases
|
||||
(stat, statfs, create, unlink, mkdir) already have been improved by
|
||||
using compounding but more can be done. In addition we could significantly
|
||||
reduce redundant opens by using deferred close (with handle caching leases)
|
||||
and better using reference counters on file handles.
|
||||
|
||||
f) Finish inotify support so kde and gnome file list windows
|
||||
will autorefresh (partially complete by Asser). Needs minor kernel
|
||||
|
|
@ -43,18 +48,17 @@ mount or a per server basis to client UIDs or nobody if no mapping
|
|||
exists. Also better integration with winbind for resolving SID owners
|
||||
|
||||
k) Add tools to take advantage of more smb3 specific ioctls and features
|
||||
(passthrough ioctl/fsctl for sending various SMB3 fsctls to the server
|
||||
is in progress, and a passthrough query_info call is already implemented
|
||||
in cifs.ko to allow smb3 info levels queries to be sent from userspace)
|
||||
(passthrough ioctl/fsctl is now implemented in cifs.ko to allow sending
|
||||
various SMB3 fsctls and query info and set info calls directly from user space)
|
||||
Add tools to make setting various non-POSIX metadata attributes easier
|
||||
from tools (e.g. extending what was done in smb-info tool).
|
||||
|
||||
l) encrypted file support
|
||||
|
||||
m) improved stats gathering tools (perhaps integration with nfsometer?)
|
||||
to extend and make easier to use what is currently in /proc/fs/cifs/Stats
|
||||
|
||||
n) allow setting more NTFS/SMB3 file attributes remotely (currently limited to compressed
|
||||
file attribute via chflags) and improve user space tools for managing and
|
||||
viewing them.
|
||||
n) Add support for claims based ACLs ("DAC")
|
||||
|
||||
o) mount helper GUI (to simplify the various configuration options on mount)
|
||||
|
||||
|
|
@ -82,6 +86,8 @@ so far).
|
|||
w) Add support for additional strong encryption types, and additional spnego
|
||||
authentication mechanisms (see MS-SMB2)
|
||||
|
||||
x) Finish support for SMB3.1.1 compression
|
||||
|
||||
KNOWN BUGS
|
||||
====================================
|
||||
See http://bugzilla.samba.org - search on product "CifsVFS" for
|
||||
|
|
|
|||
|
|
@ -424,13 +424,24 @@ Statistics
|
|||
Following minimum set of TLS-related statistics should be reported
|
||||
by the driver:
|
||||
|
||||
* ``rx_tls_decrypted`` - number of successfully decrypted TLS segments
|
||||
* ``tx_tls_encrypted`` - number of in-order TLS segments passed to device
|
||||
for encryption
|
||||
* ``rx_tls_decrypted_packets`` - number of successfully decrypted RX packets
|
||||
which were part of a TLS stream.
|
||||
* ``rx_tls_decrypted_bytes`` - number of TLS payload bytes in RX packets
|
||||
which were successfully decrypted.
|
||||
* ``tx_tls_encrypted_packets`` - number of TX packets passed to the device
|
||||
for encryption of their TLS payload.
|
||||
* ``tx_tls_encrypted_bytes`` - number of TLS payload bytes in TX packets
|
||||
passed to the device for encryption.
|
||||
* ``tx_tls_ctx`` - number of TLS TX HW offload contexts added to device for
|
||||
encryption.
|
||||
* ``tx_tls_ooo`` - number of TX packets which were part of a TLS stream
|
||||
but did not arrive in the expected order
|
||||
* ``tx_tls_drop_no_sync_data`` - number of TX packets dropped because
|
||||
they arrived out of order and associated record could not be found
|
||||
but did not arrive in the expected order.
|
||||
* ``tx_tls_drop_no_sync_data`` - number of TX packets which were part of
|
||||
a TLS stream dropped, because they arrived out of order and associated
|
||||
record could not be found.
|
||||
* ``tx_tls_drop_bypass_req`` - number of TX packets which were part of a TLS
|
||||
stream dropped, because they contain both data that has been encrypted by
|
||||
software and data that expects hardware crypto offload.
|
||||
|
||||
Notable corner cases, exceptions and additional requirements
|
||||
============================================================
|
||||
|
|
|
|||
17
MAINTAINERS
17
MAINTAINERS
|
|
@ -6344,7 +6344,7 @@ FPGA MANAGER FRAMEWORK
|
|||
M: Moritz Fischer <mdf@kernel.org>
|
||||
L: linux-fpga@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/atull/linux-fpga.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mdf/linux-fpga.git
|
||||
Q: http://patchwork.kernel.org/project/linux-fpga/list/
|
||||
F: Documentation/fpga/
|
||||
F: Documentation/driver-api/fpga/
|
||||
|
|
@ -6377,7 +6377,7 @@ FRAMEBUFFER LAYER
|
|||
M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
T: git git://github.com/bzolnier/linux.git
|
||||
T: git git://anongit.freedesktop.org/drm/drm-misc
|
||||
Q: http://patchwork.kernel.org/project/linux-fbdev/list/
|
||||
S: Maintained
|
||||
F: Documentation/fb/
|
||||
|
|
@ -6827,13 +6827,6 @@ F: Documentation/filesystems/gfs2*.txt
|
|||
F: fs/gfs2/
|
||||
F: include/uapi/linux/gfs2_ondisk.h
|
||||
|
||||
GIGASET ISDN DRIVERS
|
||||
M: Paul Bolle <pebolle@tiscali.nl>
|
||||
L: gigaset307x-common@lists.sourceforge.net
|
||||
W: http://gigaset307x.sourceforge.net/
|
||||
S: Odd Fixes
|
||||
F: drivers/staging/isdn/gigaset/
|
||||
|
||||
GNSS SUBSYSTEM
|
||||
M: Johan Hovold <johan@kernel.org>
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/johan/gnss.git
|
||||
|
|
@ -8049,6 +8042,7 @@ S: Maintained
|
|||
F: drivers/video/fbdev/i810/
|
||||
|
||||
INTEL ASoC DRIVERS
|
||||
M: Cezary Rojewski <cezary.rojewski@intel.com>
|
||||
M: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
|
||||
M: Liam Girdwood <liam.r.girdwood@linux.intel.com>
|
||||
M: Jie Yang <yang.jie@linux.intel.com>
|
||||
|
|
@ -11149,6 +11143,7 @@ L: netdev@vger.kernel.org
|
|||
S: Maintained
|
||||
W: https://fedorahosted.org/dropwatch/
|
||||
F: net/core/drop_monitor.c
|
||||
F: include/uapi/linux/net_dropmon.h
|
||||
|
||||
NETWORKING DRIVERS
|
||||
M: "David S. Miller" <davem@davemloft.net>
|
||||
|
|
@ -11287,6 +11282,7 @@ M: Aviad Yehezkel <aviadye@mellanox.com>
|
|||
M: Dave Watson <davejwatson@fb.com>
|
||||
M: John Fastabend <john.fastabend@gmail.com>
|
||||
M: Daniel Borkmann <daniel@iogearbox.net>
|
||||
M: Jakub Kicinski <jakub.kicinski@netronome.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: net/tls/*
|
||||
|
|
@ -16089,7 +16085,7 @@ S: Maintained
|
|||
F: drivers/net/ethernet/ti/netcp*
|
||||
|
||||
TI PCM3060 ASoC CODEC DRIVER
|
||||
M: Kirill Marinushkin <kmarinushkin@birdec.tech>
|
||||
M: Kirill Marinushkin <kmarinushkin@birdec.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/sound/pcm3060.txt
|
||||
|
|
@ -17565,7 +17561,6 @@ M: Jakub Kicinski <jakub.kicinski@netronome.com>
|
|||
M: Jesper Dangaard Brouer <hawk@kernel.org>
|
||||
M: John Fastabend <john.fastabend@gmail.com>
|
||||
L: netdev@vger.kernel.org
|
||||
L: xdp-newbies@vger.kernel.org
|
||||
L: bpf@vger.kernel.org
|
||||
S: Supported
|
||||
F: net/core/xdp.c
|
||||
|
|
|
|||
24
Makefile
24
Makefile
|
|
@ -2,7 +2,7 @@
|
|||
VERSION = 5
|
||||
PATCHLEVEL = 3
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc3
|
||||
EXTRAVERSION = -rc4
|
||||
NAME = Bobtail Squid
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
@ -419,6 +419,7 @@ NM = $(CROSS_COMPILE)nm
|
|||
STRIP = $(CROSS_COMPILE)strip
|
||||
OBJCOPY = $(CROSS_COMPILE)objcopy
|
||||
OBJDUMP = $(CROSS_COMPILE)objdump
|
||||
OBJSIZE = $(CROSS_COMPILE)size
|
||||
PAHOLE = pahole
|
||||
LEX = flex
|
||||
YACC = bison
|
||||
|
|
@ -475,9 +476,9 @@ GCC_PLUGINS_CFLAGS :=
|
|||
CLANG_FLAGS :=
|
||||
|
||||
export ARCH SRCARCH CONFIG_SHELL HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE AS LD CC
|
||||
export CPP AR NM STRIP OBJCOPY OBJDUMP PAHOLE KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS
|
||||
export MAKE LEX YACC AWK INSTALLKERNEL PERL PYTHON PYTHON2 PYTHON3 UTS_MACHINE
|
||||
export HOSTCXX KBUILD_HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
|
||||
export CPP AR NM STRIP OBJCOPY OBJDUMP OBJSIZE PAHOLE LEX YACC AWK INSTALLKERNEL
|
||||
export PERL PYTHON PYTHON2 PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX
|
||||
export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS LDFLAGS_MODULE
|
||||
|
||||
export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS
|
||||
export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
|
||||
|
|
@ -849,7 +850,7 @@ NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
|
|||
KBUILD_CFLAGS += -Wdeclaration-after-statement
|
||||
|
||||
# Warn about unmarked fall-throughs in switch statement.
|
||||
KBUILD_CFLAGS += $(call cc-option,-Wimplicit-fallthrough=3,)
|
||||
KBUILD_CFLAGS += $(call cc-option,-Wimplicit-fallthrough,)
|
||||
|
||||
# Variable Length Arrays (VLAs) should not be used anywhere in the kernel
|
||||
KBUILD_CFLAGS += -Wvla
|
||||
|
|
@ -1006,6 +1007,8 @@ endif
|
|||
|
||||
PHONY += prepare0
|
||||
|
||||
export MODORDER := $(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD)/)modules.order
|
||||
|
||||
ifeq ($(KBUILD_EXTMOD),)
|
||||
core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/
|
||||
|
||||
|
|
@ -1775,13 +1778,22 @@ build-dir = $(patsubst %/,%,$(dir $(build-target)))
|
|||
$(Q)$(MAKE) $(build)=$(build-dir) $(build-target)
|
||||
%.symtypes: prepare FORCE
|
||||
$(Q)$(MAKE) $(build)=$(build-dir) $(build-target)
|
||||
ifeq ($(KBUILD_EXTMOD),)
|
||||
# For the single build of an in-tree module, use a temporary file to avoid
|
||||
# the situation of modules_install installing an invalid modules.order.
|
||||
%.ko: MODORDER := .modules.tmp
|
||||
endif
|
||||
%.ko: prepare FORCE
|
||||
$(Q)$(MAKE) $(build)=$(build-dir) $(build-target:.ko=.mod)
|
||||
$(Q)echo $(build-target) > $(MODORDER)
|
||||
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
|
||||
|
||||
# Modules
|
||||
PHONY += /
|
||||
/: ./
|
||||
|
||||
%/: prepare FORCE
|
||||
$(Q)$(MAKE) KBUILD_MODULES=1 $(build)=$(build-dir)
|
||||
$(Q)$(MAKE) KBUILD_MODULES=1 $(build)=$(build-dir) need-modorder=1
|
||||
|
||||
# FIXME Should go into a make.lib or something
|
||||
# ===========================================================================
|
||||
|
|
|
|||
|
|
@ -544,6 +544,7 @@ static int arch_build_bp_info(struct perf_event *bp,
|
|||
if ((hw->ctrl.type != ARM_BREAKPOINT_EXECUTE)
|
||||
&& max_watchpoint_len >= 8)
|
||||
break;
|
||||
/* Else, fall through */
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -608,10 +609,12 @@ int hw_breakpoint_arch_parse(struct perf_event *bp,
|
|||
/* Allow halfword watchpoints and breakpoints. */
|
||||
if (hw->ctrl.len == ARM_BREAKPOINT_LEN_2)
|
||||
break;
|
||||
/* Else, fall through */
|
||||
case 3:
|
||||
/* Allow single byte watchpoint. */
|
||||
if (hw->ctrl.len == ARM_BREAKPOINT_LEN_1)
|
||||
break;
|
||||
/* Else, fall through */
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
|
|
@ -861,6 +864,7 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,
|
|||
break;
|
||||
case ARM_ENTRY_ASYNC_WATCHPOINT:
|
||||
WARN(1, "Asynchronous watchpoint exception taken. Debugging results may be unreliable\n");
|
||||
/* Fall through */
|
||||
case ARM_ENTRY_SYNC_WATCHPOINT:
|
||||
watchpoint_handler(addr, fsr, regs);
|
||||
break;
|
||||
|
|
@ -909,6 +913,7 @@ static bool core_has_os_save_restore(void)
|
|||
ARM_DBG_READ(c1, c1, 4, oslsr);
|
||||
if (oslsr & ARM_OSLSR_OSLM0)
|
||||
return true;
|
||||
/* Else, fall through */
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -596,6 +596,7 @@ static int do_signal(struct pt_regs *regs, int syscall)
|
|||
switch (retval) {
|
||||
case -ERESTART_RESTARTBLOCK:
|
||||
restart -= 2;
|
||||
/* Fall through */
|
||||
case -ERESTARTNOHAND:
|
||||
case -ERESTARTSYS:
|
||||
case -ERESTARTNOINTR:
|
||||
|
|
|
|||
|
|
@ -651,13 +651,22 @@ int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
|||
}
|
||||
|
||||
static void reset_coproc_regs(struct kvm_vcpu *vcpu,
|
||||
const struct coproc_reg *table, size_t num)
|
||||
const struct coproc_reg *table, size_t num,
|
||||
unsigned long *bmap)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
if (table[i].reset)
|
||||
if (table[i].reset) {
|
||||
int reg = table[i].reg;
|
||||
|
||||
table[i].reset(vcpu, &table[i]);
|
||||
if (reg > 0 && reg < NR_CP15_REGS) {
|
||||
set_bit(reg, bmap);
|
||||
if (table[i].is_64bit)
|
||||
set_bit(reg + 1, bmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static struct coproc_params decode_32bit_hsr(struct kvm_vcpu *vcpu)
|
||||
|
|
@ -1432,17 +1441,15 @@ void kvm_reset_coprocs(struct kvm_vcpu *vcpu)
|
|||
{
|
||||
size_t num;
|
||||
const struct coproc_reg *table;
|
||||
|
||||
/* Catch someone adding a register without putting in reset entry. */
|
||||
memset(vcpu->arch.ctxt.cp15, 0x42, sizeof(vcpu->arch.ctxt.cp15));
|
||||
DECLARE_BITMAP(bmap, NR_CP15_REGS) = { 0, };
|
||||
|
||||
/* Generic chip reset first (so target could override). */
|
||||
reset_coproc_regs(vcpu, cp15_regs, ARRAY_SIZE(cp15_regs));
|
||||
reset_coproc_regs(vcpu, cp15_regs, ARRAY_SIZE(cp15_regs), bmap);
|
||||
|
||||
table = get_target_table(vcpu->arch.target, &num);
|
||||
reset_coproc_regs(vcpu, table, num);
|
||||
reset_coproc_regs(vcpu, table, num, bmap);
|
||||
|
||||
for (num = 1; num < NR_CP15_REGS; num++)
|
||||
WARN(vcpu_cp15(vcpu, num) == 0x42424242,
|
||||
WARN(!test_bit(num, bmap),
|
||||
"Didn't reset vcpu_cp15(vcpu, %zi)", num);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t)
|
|||
* FALLTHROUGH: Ensure we don't try to overwrite our newly
|
||||
* initialised state information on the first fault.
|
||||
*/
|
||||
/* Fall through */
|
||||
|
||||
case THREAD_NOTIFY_EXIT:
|
||||
crunch_task_release(thread);
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ static void __init tegra_cpu_reset_handler_enable(void)
|
|||
switch (err) {
|
||||
case -ENOSYS:
|
||||
tegra_cpu_reset_handler_set(reset_address);
|
||||
/* pass-through */
|
||||
/* fall through */
|
||||
case 0:
|
||||
is_enabled = true;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -695,7 +695,7 @@ thumb2arm(u16 tinstr)
|
|||
return subset[(L<<1) | ((tinstr & (1<<8)) >> 8)] |
|
||||
(tinstr & 255); /* register_list */
|
||||
}
|
||||
/* Else fall through for illegal instruction case */
|
||||
/* Else, fall through - for illegal instruction case */
|
||||
|
||||
default:
|
||||
return BAD_INSTR;
|
||||
|
|
@ -751,6 +751,8 @@ do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs,
|
|||
case 0xe8e0:
|
||||
case 0xe9e0:
|
||||
poffset->un = (tinst2 & 0xff) << 2;
|
||||
/* Fall through */
|
||||
|
||||
case 0xe940:
|
||||
case 0xe9c0:
|
||||
return do_alignment_ldrdstrd;
|
||||
|
|
|
|||
|
|
@ -388,17 +388,15 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
|
|||
/*
|
||||
* not supported by current hardware on OMAP1
|
||||
* w |= (0x03 << 7);
|
||||
* fall through
|
||||
*/
|
||||
/* fall through */
|
||||
case OMAP_DMA_DATA_BURST_16:
|
||||
if (dma_omap2plus()) {
|
||||
burst = 0x3;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* OMAP1 don't support burst 16
|
||||
* fall through
|
||||
*/
|
||||
/* OMAP1 don't support burst 16 */
|
||||
/* fall through */
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -474,10 +472,8 @@ void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
|
|||
burst = 0x3;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* OMAP1 don't support burst 16
|
||||
* fall through
|
||||
*/
|
||||
/* OMAP1 don't support burst 16 */
|
||||
/* fall through */
|
||||
default:
|
||||
printk(KERN_ERR "Invalid DMA burst mode\n");
|
||||
BUG();
|
||||
|
|
|
|||
|
|
@ -316,9 +316,10 @@
|
|||
|
||||
#define kvm_arm_exception_class \
|
||||
ECN(UNKNOWN), ECN(WFx), ECN(CP15_32), ECN(CP15_64), ECN(CP14_MR), \
|
||||
ECN(CP14_LS), ECN(FP_ASIMD), ECN(CP10_ID), ECN(CP14_64), ECN(SVC64), \
|
||||
ECN(HVC64), ECN(SMC64), ECN(SYS64), ECN(IMP_DEF), ECN(IABT_LOW), \
|
||||
ECN(IABT_CUR), ECN(PC_ALIGN), ECN(DABT_LOW), ECN(DABT_CUR), \
|
||||
ECN(CP14_LS), ECN(FP_ASIMD), ECN(CP10_ID), ECN(PAC), ECN(CP14_64), \
|
||||
ECN(SVC64), ECN(HVC64), ECN(SMC64), ECN(SYS64), ECN(SVE), \
|
||||
ECN(IMP_DEF), ECN(IABT_LOW), ECN(IABT_CUR), \
|
||||
ECN(PC_ALIGN), ECN(DABT_LOW), ECN(DABT_CUR), \
|
||||
ECN(SP_ALIGN), ECN(FP_EXC32), ECN(FP_EXC64), ECN(SERROR), \
|
||||
ECN(BREAKPT_LOW), ECN(BREAKPT_CUR), ECN(SOFTSTP_LOW), \
|
||||
ECN(SOFTSTP_CUR), ECN(WATCHPT_LOW), ECN(WATCHPT_CUR), \
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ static inline pmd_t pmd_mkcont(pmd_t pmd)
|
|||
|
||||
static inline pte_t pte_mkdevmap(pte_t pte)
|
||||
{
|
||||
return set_pte_bit(pte, __pgprot(PTE_DEVMAP));
|
||||
return set_pte_bit(pte, __pgprot(PTE_DEVMAP | PTE_SPECIAL));
|
||||
}
|
||||
|
||||
static inline void set_pte(pte_t *ptep, pte_t pte)
|
||||
|
|
@ -396,7 +396,10 @@ static inline int pmd_protnone(pmd_t pmd)
|
|||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
#define pmd_devmap(pmd) pte_devmap(pmd_pte(pmd))
|
||||
#endif
|
||||
#define pmd_mkdevmap(pmd) pte_pmd(pte_mkdevmap(pmd_pte(pmd)))
|
||||
static inline pmd_t pmd_mkdevmap(pmd_t pmd)
|
||||
{
|
||||
return pte_pmd(set_pte_bit(pmd_pte(pmd), __pgprot(PTE_DEVMAP)));
|
||||
}
|
||||
|
||||
#define __pmd_to_phys(pmd) __pte_to_phys(pmd_pte(pmd))
|
||||
#define __phys_to_pmd_val(phys) __phys_to_pte_val(phys)
|
||||
|
|
|
|||
|
|
@ -733,6 +733,7 @@ static const char *esr_class_str[] = {
|
|||
[ESR_ELx_EC_CP14_LS] = "CP14 LDC/STC",
|
||||
[ESR_ELx_EC_FP_ASIMD] = "ASIMD",
|
||||
[ESR_ELx_EC_CP10_ID] = "CP10 MRC/VMRS",
|
||||
[ESR_ELx_EC_PAC] = "PAC",
|
||||
[ESR_ELx_EC_CP14_64] = "CP14 MCRR/MRRC",
|
||||
[ESR_ELx_EC_ILL] = "PSTATE.IL",
|
||||
[ESR_ELx_EC_SVC32] = "SVC (AArch32)",
|
||||
|
|
|
|||
|
|
@ -18,40 +18,70 @@
|
|||
#define save_debug(ptr,reg,nr) \
|
||||
switch (nr) { \
|
||||
case 15: ptr[15] = read_debug(reg, 15); \
|
||||
/* Fall through */ \
|
||||
case 14: ptr[14] = read_debug(reg, 14); \
|
||||
/* Fall through */ \
|
||||
case 13: ptr[13] = read_debug(reg, 13); \
|
||||
/* Fall through */ \
|
||||
case 12: ptr[12] = read_debug(reg, 12); \
|
||||
/* Fall through */ \
|
||||
case 11: ptr[11] = read_debug(reg, 11); \
|
||||
/* Fall through */ \
|
||||
case 10: ptr[10] = read_debug(reg, 10); \
|
||||
/* Fall through */ \
|
||||
case 9: ptr[9] = read_debug(reg, 9); \
|
||||
/* Fall through */ \
|
||||
case 8: ptr[8] = read_debug(reg, 8); \
|
||||
/* Fall through */ \
|
||||
case 7: ptr[7] = read_debug(reg, 7); \
|
||||
/* Fall through */ \
|
||||
case 6: ptr[6] = read_debug(reg, 6); \
|
||||
/* Fall through */ \
|
||||
case 5: ptr[5] = read_debug(reg, 5); \
|
||||
/* Fall through */ \
|
||||
case 4: ptr[4] = read_debug(reg, 4); \
|
||||
/* Fall through */ \
|
||||
case 3: ptr[3] = read_debug(reg, 3); \
|
||||
/* Fall through */ \
|
||||
case 2: ptr[2] = read_debug(reg, 2); \
|
||||
/* Fall through */ \
|
||||
case 1: ptr[1] = read_debug(reg, 1); \
|
||||
/* Fall through */ \
|
||||
default: ptr[0] = read_debug(reg, 0); \
|
||||
}
|
||||
|
||||
#define restore_debug(ptr,reg,nr) \
|
||||
switch (nr) { \
|
||||
case 15: write_debug(ptr[15], reg, 15); \
|
||||
/* Fall through */ \
|
||||
case 14: write_debug(ptr[14], reg, 14); \
|
||||
/* Fall through */ \
|
||||
case 13: write_debug(ptr[13], reg, 13); \
|
||||
/* Fall through */ \
|
||||
case 12: write_debug(ptr[12], reg, 12); \
|
||||
/* Fall through */ \
|
||||
case 11: write_debug(ptr[11], reg, 11); \
|
||||
/* Fall through */ \
|
||||
case 10: write_debug(ptr[10], reg, 10); \
|
||||
/* Fall through */ \
|
||||
case 9: write_debug(ptr[9], reg, 9); \
|
||||
/* Fall through */ \
|
||||
case 8: write_debug(ptr[8], reg, 8); \
|
||||
/* Fall through */ \
|
||||
case 7: write_debug(ptr[7], reg, 7); \
|
||||
/* Fall through */ \
|
||||
case 6: write_debug(ptr[6], reg, 6); \
|
||||
/* Fall through */ \
|
||||
case 5: write_debug(ptr[5], reg, 5); \
|
||||
/* Fall through */ \
|
||||
case 4: write_debug(ptr[4], reg, 4); \
|
||||
/* Fall through */ \
|
||||
case 3: write_debug(ptr[3], reg, 3); \
|
||||
/* Fall through */ \
|
||||
case 2: write_debug(ptr[2], reg, 2); \
|
||||
/* Fall through */ \
|
||||
case 1: write_debug(ptr[1], reg, 1); \
|
||||
/* Fall through */ \
|
||||
default: write_debug(ptr[0], reg, 0); \
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -178,13 +178,18 @@ void vcpu_write_spsr32(struct kvm_vcpu *vcpu, unsigned long v)
|
|||
switch (spsr_idx) {
|
||||
case KVM_SPSR_SVC:
|
||||
write_sysreg_el1(v, SYS_SPSR);
|
||||
break;
|
||||
case KVM_SPSR_ABT:
|
||||
write_sysreg(v, spsr_abt);
|
||||
break;
|
||||
case KVM_SPSR_UND:
|
||||
write_sysreg(v, spsr_und);
|
||||
break;
|
||||
case KVM_SPSR_IRQ:
|
||||
write_sysreg(v, spsr_irq);
|
||||
break;
|
||||
case KVM_SPSR_FIQ:
|
||||
write_sysreg(v, spsr_fiq);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -632,7 +632,7 @@ static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
|
|||
*/
|
||||
val = ((pmcr & ~ARMV8_PMU_PMCR_MASK)
|
||||
| (ARMV8_PMU_PMCR_MASK & 0xdecafbad)) & (~ARMV8_PMU_PMCR_E);
|
||||
__vcpu_sys_reg(vcpu, PMCR_EL0) = val;
|
||||
__vcpu_sys_reg(vcpu, r->reg) = val;
|
||||
}
|
||||
|
||||
static bool check_pmu_access_disabled(struct kvm_vcpu *vcpu, u64 flags)
|
||||
|
|
@ -981,13 +981,13 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
|
|||
/* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */
|
||||
#define DBG_BCR_BVR_WCR_WVR_EL1(n) \
|
||||
{ SYS_DESC(SYS_DBGBVRn_EL1(n)), \
|
||||
trap_bvr, reset_bvr, n, 0, get_bvr, set_bvr }, \
|
||||
trap_bvr, reset_bvr, 0, 0, get_bvr, set_bvr }, \
|
||||
{ SYS_DESC(SYS_DBGBCRn_EL1(n)), \
|
||||
trap_bcr, reset_bcr, n, 0, get_bcr, set_bcr }, \
|
||||
trap_bcr, reset_bcr, 0, 0, get_bcr, set_bcr }, \
|
||||
{ SYS_DESC(SYS_DBGWVRn_EL1(n)), \
|
||||
trap_wvr, reset_wvr, n, 0, get_wvr, set_wvr }, \
|
||||
trap_wvr, reset_wvr, 0, 0, get_wvr, set_wvr }, \
|
||||
{ SYS_DESC(SYS_DBGWCRn_EL1(n)), \
|
||||
trap_wcr, reset_wcr, n, 0, get_wcr, set_wcr }
|
||||
trap_wcr, reset_wcr, 0, 0, get_wcr, set_wcr }
|
||||
|
||||
/* Macro to expand the PMEVCNTRn_EL0 register */
|
||||
#define PMU_PMEVCNTR_EL0(n) \
|
||||
|
|
@ -1540,7 +1540,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
|
|||
{ SYS_DESC(SYS_CSSELR_EL1), access_csselr, reset_unknown, CSSELR_EL1 },
|
||||
{ SYS_DESC(SYS_CTR_EL0), access_ctr },
|
||||
|
||||
{ SYS_DESC(SYS_PMCR_EL0), access_pmcr, reset_pmcr, },
|
||||
{ SYS_DESC(SYS_PMCR_EL0), access_pmcr, reset_pmcr, PMCR_EL0 },
|
||||
{ SYS_DESC(SYS_PMCNTENSET_EL0), access_pmcnten, reset_unknown, PMCNTENSET_EL0 },
|
||||
{ SYS_DESC(SYS_PMCNTENCLR_EL0), access_pmcnten, NULL, PMCNTENSET_EL0 },
|
||||
{ SYS_DESC(SYS_PMOVSCLR_EL0), access_pmovs, NULL, PMOVSSET_EL0 },
|
||||
|
|
@ -2254,13 +2254,19 @@ static int emulate_sys_reg(struct kvm_vcpu *vcpu,
|
|||
}
|
||||
|
||||
static void reset_sys_reg_descs(struct kvm_vcpu *vcpu,
|
||||
const struct sys_reg_desc *table, size_t num)
|
||||
const struct sys_reg_desc *table, size_t num,
|
||||
unsigned long *bmap)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
if (table[i].reset)
|
||||
if (table[i].reset) {
|
||||
int reg = table[i].reg;
|
||||
|
||||
table[i].reset(vcpu, &table[i]);
|
||||
if (reg > 0 && reg < NR_SYS_REGS)
|
||||
set_bit(reg, bmap);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2774,18 +2780,16 @@ void kvm_reset_sys_regs(struct kvm_vcpu *vcpu)
|
|||
{
|
||||
size_t num;
|
||||
const struct sys_reg_desc *table;
|
||||
|
||||
/* Catch someone adding a register without putting in reset entry. */
|
||||
memset(&vcpu->arch.ctxt.sys_regs, 0x42, sizeof(vcpu->arch.ctxt.sys_regs));
|
||||
DECLARE_BITMAP(bmap, NR_SYS_REGS) = { 0, };
|
||||
|
||||
/* Generic chip reset first (so target could override). */
|
||||
reset_sys_reg_descs(vcpu, sys_reg_descs, ARRAY_SIZE(sys_reg_descs));
|
||||
reset_sys_reg_descs(vcpu, sys_reg_descs, ARRAY_SIZE(sys_reg_descs), bmap);
|
||||
|
||||
table = get_target_table(vcpu->arch.target, true, &num);
|
||||
reset_sys_reg_descs(vcpu, table, num);
|
||||
reset_sys_reg_descs(vcpu, table, num, bmap);
|
||||
|
||||
for (num = 1; num < NR_SYS_REGS; num++) {
|
||||
if (WARN(__vcpu_sys_reg(vcpu, num) == 0x4242424242424242,
|
||||
if (WARN(!test_bit(num, bmap),
|
||||
"Didn't reset __vcpu_sys_reg(%zi)\n", num))
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -398,6 +398,7 @@ static int dwc3_octeon_clocks_start(struct device *dev, u64 base)
|
|||
default:
|
||||
dev_err(dev, "Invalid ref_clk %u, using 100000000 instead\n",
|
||||
clock_rate);
|
||||
/* fall through */
|
||||
case 100000000:
|
||||
mpll_mul = 0x19;
|
||||
if (ref_clk_sel < 2)
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ static int __populate_cache_leaves(unsigned int cpu)
|
|||
if (c->tcache.waysize)
|
||||
populate_cache(tcache, this_leaf, 3, CACHE_TYPE_UNIFIED);
|
||||
|
||||
this_cpu_ci->cpu_map_populated = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ void __init setup_pit_timer(void)
|
|||
|
||||
static int __init init_pit_clocksource(void)
|
||||
{
|
||||
if (num_possible_cpus() > 1) /* PIT does not scale! */
|
||||
if (num_possible_cpus() > 1 || /* PIT does not scale! */
|
||||
!clockevent_state_periodic(&i8253_clockevent))
|
||||
return 0;
|
||||
|
||||
return clocksource_i8253_init();
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@ static int kvm_compute_return_epc(struct kvm_vcpu *vcpu, unsigned long instpc,
|
|||
/* These are unconditional and in j_format. */
|
||||
case jal_op:
|
||||
arch->gprs[31] = instpc + 8;
|
||||
/* fall through */
|
||||
case j_op:
|
||||
epc += 4;
|
||||
epc >>= 28;
|
||||
|
|
|
|||
|
|
@ -150,16 +150,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool kvm_arch_has_vcpu_debugfs(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void kvm_mips_free_vcpus(struct kvm *kvm)
|
||||
{
|
||||
unsigned int i;
|
||||
|
|
|
|||
|
|
@ -172,12 +172,15 @@ static void mipsxx_cpu_setup(void *args)
|
|||
case 4:
|
||||
w_c0_perfctrl3(0);
|
||||
w_c0_perfcntr3(reg.counter[3]);
|
||||
/* fall through */
|
||||
case 3:
|
||||
w_c0_perfctrl2(0);
|
||||
w_c0_perfcntr2(reg.counter[2]);
|
||||
/* fall through */
|
||||
case 2:
|
||||
w_c0_perfctrl1(0);
|
||||
w_c0_perfcntr1(reg.counter[1]);
|
||||
/* fall through */
|
||||
case 1:
|
||||
w_c0_perfctrl0(0);
|
||||
w_c0_perfcntr0(reg.counter[0]);
|
||||
|
|
@ -195,10 +198,13 @@ static void mipsxx_cpu_start(void *args)
|
|||
switch (counters) {
|
||||
case 4:
|
||||
w_c0_perfctrl3(WHAT | reg.control[3]);
|
||||
/* fall through */
|
||||
case 3:
|
||||
w_c0_perfctrl2(WHAT | reg.control[2]);
|
||||
/* fall through */
|
||||
case 2:
|
||||
w_c0_perfctrl1(WHAT | reg.control[1]);
|
||||
/* fall through */
|
||||
case 1:
|
||||
w_c0_perfctrl0(WHAT | reg.control[0]);
|
||||
}
|
||||
|
|
@ -215,10 +221,13 @@ static void mipsxx_cpu_stop(void *args)
|
|||
switch (counters) {
|
||||
case 4:
|
||||
w_c0_perfctrl3(0);
|
||||
/* fall through */
|
||||
case 3:
|
||||
w_c0_perfctrl2(0);
|
||||
/* fall through */
|
||||
case 2:
|
||||
w_c0_perfctrl1(0);
|
||||
/* fall through */
|
||||
case 1:
|
||||
w_c0_perfctrl0(0);
|
||||
}
|
||||
|
|
@ -236,6 +245,7 @@ static int mipsxx_perfcount_handler(void)
|
|||
|
||||
switch (counters) {
|
||||
#define HANDLE_COUNTER(n) \
|
||||
/* fall through */ \
|
||||
case n + 1: \
|
||||
control = r_c0_perfctrl ## n(); \
|
||||
counter = r_c0_perfcntr ## n(); \
|
||||
|
|
@ -297,12 +307,15 @@ static void reset_counters(void *arg)
|
|||
case 4:
|
||||
w_c0_perfctrl3(0);
|
||||
w_c0_perfcntr3(0);
|
||||
/* fall through */
|
||||
case 3:
|
||||
w_c0_perfctrl2(0);
|
||||
w_c0_perfcntr2(0);
|
||||
/* fall through */
|
||||
case 2:
|
||||
w_c0_perfctrl1(0);
|
||||
w_c0_perfcntr1(0);
|
||||
/* fall through */
|
||||
case 1:
|
||||
w_c0_perfctrl0(0);
|
||||
w_c0_perfcntr0(0);
|
||||
|
|
|
|||
|
|
@ -474,6 +474,7 @@ static int bcm63xx_pcie_can_access(struct pci_bus *bus, int devfn)
|
|||
if (PCI_SLOT(devfn) == 0)
|
||||
return bcm_pcie_readl(PCIE_DLSTATUS_REG)
|
||||
& DLSTATUS_PHYLINKUP;
|
||||
/* else, fall through */
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,4 +18,4 @@ obj-y := frnd.o driver.o decode_exc.o fpudispatch.o denormal.o \
|
|||
# other very old or stripped-down PA-RISC CPUs -- not currently supported
|
||||
|
||||
obj-$(CONFIG_MATH_EMULATION) += unimplemented-math-emulation.o
|
||||
CFLAGS_REMOVE_fpudispatch.o = -Wimplicit-fallthrough=3
|
||||
CFLAGS_REMOVE_fpudispatch.o = -Wimplicit-fallthrough
|
||||
|
|
|
|||
|
|
@ -107,22 +107,22 @@ extern void _set_L3CR(unsigned long);
|
|||
|
||||
static inline void dcbz(void *addr)
|
||||
{
|
||||
__asm__ __volatile__ ("dcbz %y0" : : "Z"(*(u8 *)addr) : "memory");
|
||||
__asm__ __volatile__ ("dcbz 0, %0" : : "r"(addr) : "memory");
|
||||
}
|
||||
|
||||
static inline void dcbi(void *addr)
|
||||
{
|
||||
__asm__ __volatile__ ("dcbi %y0" : : "Z"(*(u8 *)addr) : "memory");
|
||||
__asm__ __volatile__ ("dcbi 0, %0" : : "r"(addr) : "memory");
|
||||
}
|
||||
|
||||
static inline void dcbf(void *addr)
|
||||
{
|
||||
__asm__ __volatile__ ("dcbf %y0" : : "Z"(*(u8 *)addr) : "memory");
|
||||
__asm__ __volatile__ ("dcbf 0, %0" : : "r"(addr) : "memory");
|
||||
}
|
||||
|
||||
static inline void dcbst(void *addr)
|
||||
{
|
||||
__asm__ __volatile__ ("dcbst %y0" : : "Z"(*(u8 *)addr) : "memory");
|
||||
__asm__ __volatile__ ("dcbst 0, %0" : : "r"(addr) : "memory");
|
||||
}
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
#endif /* __KERNEL__ */
|
||||
|
|
|
|||
|
|
@ -50,6 +50,11 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
|
|||
return !!(v->arch.pending_exceptions) || kvm_request_pending(v);
|
||||
}
|
||||
|
||||
bool kvm_arch_dy_runnable(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return kvm_arch_vcpu_runnable(vcpu);
|
||||
}
|
||||
|
||||
bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return false;
|
||||
|
|
@ -452,16 +457,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
bool kvm_arch_has_vcpu_debugfs(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void kvm_arch_destroy_vm(struct kvm *kvm)
|
||||
{
|
||||
unsigned int i;
|
||||
|
|
|
|||
|
|
@ -5,5 +5,3 @@ lib-y += memset.o
|
|||
lib-y += uaccess.o
|
||||
|
||||
lib-$(CONFIG_64BIT) += tishift.o
|
||||
|
||||
lib-$(CONFIG_32BIT) += udivdi3.o
|
||||
|
|
|
|||
|
|
@ -81,9 +81,13 @@ EXPORT_SYMBOL(__delay);
|
|||
void udelay(unsigned long usecs)
|
||||
{
|
||||
u64 ucycles = (u64)usecs * lpj_fine * UDELAY_MULT;
|
||||
u64 n;
|
||||
|
||||
if (unlikely(usecs > MAX_UDELAY_US)) {
|
||||
__delay((u64)usecs * riscv_timebase / 1000000ULL);
|
||||
n = (u64)usecs * riscv_timebase;
|
||||
do_div(n, 1000000);
|
||||
|
||||
__delay(n);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,32 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2016-2017 Free Software Foundation, Inc.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
|
||||
ENTRY(__udivdi3)
|
||||
mv a2, a1
|
||||
mv a1, a0
|
||||
li a0, -1
|
||||
beqz a2, .L5
|
||||
li a3, 1
|
||||
bgeu a2, a1, .L2
|
||||
.L1:
|
||||
blez a2, .L2
|
||||
slli a2, a2, 1
|
||||
slli a3, a3, 1
|
||||
bgtu a1, a2, .L1
|
||||
.L2:
|
||||
li a0, 0
|
||||
.L3:
|
||||
bltu a1, a2, .L4
|
||||
sub a1, a1, a2
|
||||
or a0, a0, a3
|
||||
.L4:
|
||||
srli a3, a3, 1
|
||||
srli a2, a2, 1
|
||||
bnez a3, .L3
|
||||
.L5:
|
||||
ret
|
||||
ENDPROC(__udivdi3)
|
||||
|
|
@ -48,9 +48,7 @@ void store_ipl_parmblock(void)
|
|||
{
|
||||
int rc;
|
||||
|
||||
uv_set_shared(__pa(&ipl_block));
|
||||
rc = __diag308(DIAG308_STORE, &ipl_block);
|
||||
uv_remove_shared(__pa(&ipl_block));
|
||||
if (rc == DIAG308_RC_OK &&
|
||||
ipl_block.hdr.version <= IPL_MAX_SUPPORTED_VERSION)
|
||||
ipl_block_valid = 1;
|
||||
|
|
|
|||
|
|
@ -114,12 +114,8 @@ int get_stack_info(unsigned long sp, struct task_struct *task,
|
|||
* If it comes up a second time then there's something wrong going on:
|
||||
* just break out and report an unknown stack type.
|
||||
*/
|
||||
if (*visit_mask & (1UL << info->type)) {
|
||||
printk_deferred_once(KERN_WARNING
|
||||
"WARNING: stack recursion on stack type %d\n",
|
||||
info->type);
|
||||
if (*visit_mask & (1UL << info->type))
|
||||
goto unknown;
|
||||
}
|
||||
*visit_mask |= 1UL << info->type;
|
||||
return 0;
|
||||
unknown:
|
||||
|
|
|
|||
|
|
@ -60,12 +60,5 @@ ENTRY(startup_continue)
|
|||
|
||||
.align 16
|
||||
.LPG1:
|
||||
.Lpcmsk:.quad 0x0000000180000000
|
||||
.L4malign:.quad 0xffffffffffc00000
|
||||
.Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8
|
||||
.Lnop: .long 0x07000700
|
||||
.Lparmaddr:
|
||||
.quad PARMAREA
|
||||
.align 64
|
||||
.Ldw: .quad 0x0002000180000000,0x0000000000000000
|
||||
.Laregs:.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
#include <asm/os_info.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/boot_data.h>
|
||||
#include <asm/uv.h>
|
||||
#include "entry.h"
|
||||
|
||||
#define IPL_PARM_BLOCK_VERSION 0
|
||||
|
|
@ -892,21 +891,15 @@ static void __reipl_run(void *unused)
|
|||
{
|
||||
switch (reipl_type) {
|
||||
case IPL_TYPE_CCW:
|
||||
uv_set_shared(__pa(reipl_block_ccw));
|
||||
diag308(DIAG308_SET, reipl_block_ccw);
|
||||
uv_remove_shared(__pa(reipl_block_ccw));
|
||||
diag308(DIAG308_LOAD_CLEAR, NULL);
|
||||
break;
|
||||
case IPL_TYPE_FCP:
|
||||
uv_set_shared(__pa(reipl_block_fcp));
|
||||
diag308(DIAG308_SET, reipl_block_fcp);
|
||||
uv_remove_shared(__pa(reipl_block_fcp));
|
||||
diag308(DIAG308_LOAD_CLEAR, NULL);
|
||||
break;
|
||||
case IPL_TYPE_NSS:
|
||||
uv_set_shared(__pa(reipl_block_nss));
|
||||
diag308(DIAG308_SET, reipl_block_nss);
|
||||
uv_remove_shared(__pa(reipl_block_nss));
|
||||
diag308(DIAG308_LOAD_CLEAR, NULL);
|
||||
break;
|
||||
case IPL_TYPE_UNKNOWN:
|
||||
|
|
@ -1176,9 +1169,7 @@ static struct kset *dump_kset;
|
|||
|
||||
static void diag308_dump(void *dump_block)
|
||||
{
|
||||
uv_set_shared(__pa(dump_block));
|
||||
diag308(DIAG308_SET, dump_block);
|
||||
uv_remove_shared(__pa(dump_block));
|
||||
while (1) {
|
||||
if (diag308(DIAG308_LOAD_NORMAL_DUMP, NULL) != 0x302)
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1114,8 +1114,7 @@ void __init setup_arch(char **cmdline_p)
|
|||
|
||||
ROOT_DEV = Root_RAM0;
|
||||
|
||||
/* Is init_mm really needed? */
|
||||
init_mm.start_code = PAGE_OFFSET;
|
||||
init_mm.start_code = (unsigned long) _text;
|
||||
init_mm.end_code = (unsigned long) _etext;
|
||||
init_mm.end_data = (unsigned long) _edata;
|
||||
init_mm.brk = (unsigned long) _end;
|
||||
|
|
|
|||
|
|
@ -216,11 +216,6 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
|
|||
|
||||
if (!vdso_enabled)
|
||||
return 0;
|
||||
/*
|
||||
* Only map the vdso for dynamically linked elf binaries.
|
||||
*/
|
||||
if (!uses_interp)
|
||||
return 0;
|
||||
|
||||
vdso_pages = vdso64_pages;
|
||||
#ifdef CONFIG_COMPAT_VDSO
|
||||
|
|
|
|||
|
|
@ -32,10 +32,9 @@ PHDRS {
|
|||
SECTIONS
|
||||
{
|
||||
. = 0x100000;
|
||||
_stext = .; /* Start of text section */
|
||||
.text : {
|
||||
/* Text and read-only data */
|
||||
_text = .;
|
||||
_stext = .; /* Start of text section */
|
||||
_text = .; /* Text and read-only data */
|
||||
HEAD_TEXT
|
||||
TEXT_TEXT
|
||||
SCHED_TEXT
|
||||
|
|
@ -47,11 +46,10 @@ SECTIONS
|
|||
*(.text.*_indirect_*)
|
||||
*(.fixup)
|
||||
*(.gnu.warning)
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
_etext = .; /* End of text section */
|
||||
} :text = 0x0700
|
||||
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
_etext = .; /* End of text section */
|
||||
|
||||
NOTES :text :note
|
||||
|
||||
.dummy : { *(.dummy) } :data
|
||||
|
|
|
|||
|
|
@ -2516,16 +2516,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
|
|||
return rc;
|
||||
}
|
||||
|
||||
bool kvm_arch_has_vcpu_debugfs(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
VCPU_EVENT(vcpu, 3, "%s", "free cpu");
|
||||
|
|
|
|||
|
|
@ -161,9 +161,9 @@ static void walk_pmd_level(struct seq_file *m, struct pg_state *st,
|
|||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < PTRS_PER_PMD && addr < max_addr; i++) {
|
||||
pmd = pmd_offset(pud, addr);
|
||||
for (i = 0; i < PTRS_PER_PMD && addr < max_addr; i++, pmd++) {
|
||||
st->current_address = addr;
|
||||
pmd = pmd_offset(pud, addr);
|
||||
if (!pmd_none(*pmd)) {
|
||||
if (pmd_large(*pmd)) {
|
||||
prot = pmd_val(*pmd) &
|
||||
|
|
@ -192,9 +192,9 @@ static void walk_pud_level(struct seq_file *m, struct pg_state *st,
|
|||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < PTRS_PER_PUD && addr < max_addr; i++) {
|
||||
pud = pud_offset(p4d, addr);
|
||||
for (i = 0; i < PTRS_PER_PUD && addr < max_addr; i++, pud++) {
|
||||
st->current_address = addr;
|
||||
pud = pud_offset(p4d, addr);
|
||||
if (!pud_none(*pud))
|
||||
if (pud_large(*pud)) {
|
||||
prot = pud_val(*pud) &
|
||||
|
|
@ -222,9 +222,9 @@ static void walk_p4d_level(struct seq_file *m, struct pg_state *st,
|
|||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < PTRS_PER_P4D && addr < max_addr; i++) {
|
||||
p4d = p4d_offset(pgd, addr);
|
||||
for (i = 0; i < PTRS_PER_P4D && addr < max_addr; i++, p4d++) {
|
||||
st->current_address = addr;
|
||||
p4d = p4d_offset(pgd, addr);
|
||||
if (!p4d_none(*p4d))
|
||||
walk_pud_level(m, st, p4d, addr);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -11,8 +11,7 @@ chkbss: $(addprefix $(obj)/, $(chkbss-files))
|
|||
|
||||
quiet_cmd_chkbss = CHKBSS $<
|
||||
cmd_chkbss = \
|
||||
if $(OBJDUMP) -h $< | grep -q "\.bss" && \
|
||||
! $(OBJDUMP) -j .bss -w -h $< | awk 'END { if ($$3) exit 1 }'; then \
|
||||
if ! $(OBJSIZE) --common $< | $(AWK) 'END { if ($$3) exit 1 }'; then \
|
||||
echo "error: $< .bss section is not empty" >&2; exit 1; \
|
||||
fi; \
|
||||
touch $@;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,14 @@ int memcmp(const void *s1, const void *s2, size_t len)
|
|||
return diff;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clang may lower `memcmp == 0` to `bcmp == 0`.
|
||||
*/
|
||||
int bcmp(const void *s1, const void *s2, size_t len)
|
||||
{
|
||||
return memcmp(s1, s2, len);
|
||||
}
|
||||
|
||||
int strcmp(const char *str1, const char *str2)
|
||||
{
|
||||
const unsigned char *s1 = (const unsigned char *)str1;
|
||||
|
|
|
|||
|
|
@ -314,6 +314,23 @@ For 32-bit we have the following conventions - kernel is built with
|
|||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Mitigate Spectre v1 for conditional swapgs code paths.
|
||||
*
|
||||
* FENCE_SWAPGS_USER_ENTRY is used in the user entry swapgs code path, to
|
||||
* prevent a speculative swapgs when coming from kernel space.
|
||||
*
|
||||
* FENCE_SWAPGS_KERNEL_ENTRY is used in the kernel entry non-swapgs code path,
|
||||
* to prevent the swapgs from getting speculatively skipped when coming from
|
||||
* user space.
|
||||
*/
|
||||
.macro FENCE_SWAPGS_USER_ENTRY
|
||||
ALTERNATIVE "", "lfence", X86_FEATURE_FENCE_SWAPGS_USER
|
||||
.endm
|
||||
.macro FENCE_SWAPGS_KERNEL_ENTRY
|
||||
ALTERNATIVE "", "lfence", X86_FEATURE_FENCE_SWAPGS_KERNEL
|
||||
.endm
|
||||
|
||||
.macro STACKLEAK_ERASE_NOCLOBBER
|
||||
#ifdef CONFIG_GCC_PLUGIN_STACKLEAK
|
||||
PUSH_AND_CLEAR_REGS
|
||||
|
|
|
|||
|
|
@ -519,7 +519,7 @@ ENTRY(interrupt_entry)
|
|||
testb $3, CS-ORIG_RAX+8(%rsp)
|
||||
jz 1f
|
||||
SWAPGS
|
||||
|
||||
FENCE_SWAPGS_USER_ENTRY
|
||||
/*
|
||||
* Switch to the thread stack. The IRET frame and orig_ax are
|
||||
* on the stack, as well as the return address. RDI..R12 are
|
||||
|
|
@ -549,8 +549,10 @@ ENTRY(interrupt_entry)
|
|||
UNWIND_HINT_FUNC
|
||||
|
||||
movq (%rdi), %rdi
|
||||
jmp 2f
|
||||
1:
|
||||
|
||||
FENCE_SWAPGS_KERNEL_ENTRY
|
||||
2:
|
||||
PUSH_AND_CLEAR_REGS save_ret=1
|
||||
ENCODE_FRAME_POINTER 8
|
||||
|
||||
|
|
@ -1238,6 +1240,13 @@ ENTRY(paranoid_entry)
|
|||
*/
|
||||
SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg=%rax save_reg=%r14
|
||||
|
||||
/*
|
||||
* The above SAVE_AND_SWITCH_TO_KERNEL_CR3 macro doesn't do an
|
||||
* unconditional CR3 write, even in the PTI case. So do an lfence
|
||||
* to prevent GS speculation, regardless of whether PTI is enabled.
|
||||
*/
|
||||
FENCE_SWAPGS_KERNEL_ENTRY
|
||||
|
||||
ret
|
||||
END(paranoid_entry)
|
||||
|
||||
|
|
@ -1288,6 +1297,7 @@ ENTRY(error_entry)
|
|||
* from user mode due to an IRET fault.
|
||||
*/
|
||||
SWAPGS
|
||||
FENCE_SWAPGS_USER_ENTRY
|
||||
/* We have user CR3. Change to kernel CR3. */
|
||||
SWITCH_TO_KERNEL_CR3 scratch_reg=%rax
|
||||
|
||||
|
|
@ -1301,6 +1311,8 @@ ENTRY(error_entry)
|
|||
pushq %r12
|
||||
ret
|
||||
|
||||
.Lerror_entry_done_lfence:
|
||||
FENCE_SWAPGS_KERNEL_ENTRY
|
||||
.Lerror_entry_done:
|
||||
ret
|
||||
|
||||
|
|
@ -1318,7 +1330,7 @@ ENTRY(error_entry)
|
|||
cmpq %rax, RIP+8(%rsp)
|
||||
je .Lbstep_iret
|
||||
cmpq $.Lgs_change, RIP+8(%rsp)
|
||||
jne .Lerror_entry_done
|
||||
jne .Lerror_entry_done_lfence
|
||||
|
||||
/*
|
||||
* hack: .Lgs_change can fail with user gsbase. If this happens, fix up
|
||||
|
|
@ -1326,6 +1338,7 @@ ENTRY(error_entry)
|
|||
* .Lgs_change's error handler with kernel gsbase.
|
||||
*/
|
||||
SWAPGS
|
||||
FENCE_SWAPGS_USER_ENTRY
|
||||
SWITCH_TO_KERNEL_CR3 scratch_reg=%rax
|
||||
jmp .Lerror_entry_done
|
||||
|
||||
|
|
@ -1340,6 +1353,7 @@ ENTRY(error_entry)
|
|||
* gsbase and CR3. Switch to kernel gsbase and CR3:
|
||||
*/
|
||||
SWAPGS
|
||||
FENCE_SWAPGS_USER_ENTRY
|
||||
SWITCH_TO_KERNEL_CR3 scratch_reg=%rax
|
||||
|
||||
/*
|
||||
|
|
@ -1431,6 +1445,7 @@ ENTRY(nmi)
|
|||
|
||||
swapgs
|
||||
cld
|
||||
FENCE_SWAPGS_USER_ENTRY
|
||||
SWITCH_TO_KERNEL_CR3 scratch_reg=%rdx
|
||||
movq %rsp, %rdx
|
||||
movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
|
||||
|
|
|
|||
|
|
@ -281,6 +281,8 @@
|
|||
#define X86_FEATURE_CQM_OCCUP_LLC (11*32+ 1) /* LLC occupancy monitoring */
|
||||
#define X86_FEATURE_CQM_MBM_TOTAL (11*32+ 2) /* LLC Total MBM monitoring */
|
||||
#define X86_FEATURE_CQM_MBM_LOCAL (11*32+ 3) /* LLC Local MBM monitoring */
|
||||
#define X86_FEATURE_FENCE_SWAPGS_USER (11*32+ 4) /* "" LFENCE in user entry SWAPGS path */
|
||||
#define X86_FEATURE_FENCE_SWAPGS_KERNEL (11*32+ 5) /* "" LFENCE in kernel entry SWAPGS path */
|
||||
|
||||
/* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
|
||||
#define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */
|
||||
|
|
@ -394,5 +396,6 @@
|
|||
#define X86_BUG_L1TF X86_BUG(18) /* CPU is affected by L1 Terminal Fault */
|
||||
#define X86_BUG_MDS X86_BUG(19) /* CPU is affected by Microarchitectural data sampling */
|
||||
#define X86_BUG_MSBDS_ONLY X86_BUG(20) /* CPU is only affected by the MSDBS variant of BUG_MDS */
|
||||
#define X86_BUG_SWAPGS X86_BUG(21) /* CPU is affected by speculation through SWAPGS */
|
||||
|
||||
#endif /* _ASM_X86_CPUFEATURES_H */
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
#include <asm/kvm_vcpu_regs.h>
|
||||
#include <asm/hyperv-tlfs.h>
|
||||
|
||||
#define __KVM_HAVE_ARCH_VCPU_DEBUGFS
|
||||
|
||||
#define KVM_MAX_VCPUS 288
|
||||
#define KVM_SOFT_MAX_VCPUS 240
|
||||
#define KVM_MAX_VCPU_ID 1023
|
||||
|
|
@ -1175,6 +1177,7 @@ struct kvm_x86_ops {
|
|||
int (*update_pi_irte)(struct kvm *kvm, unsigned int host_irq,
|
||||
uint32_t guest_irq, bool set);
|
||||
void (*apicv_post_state_restore)(struct kvm_vcpu *vcpu);
|
||||
bool (*dy_apicv_has_pending_interrupt)(struct kvm_vcpu *vcpu);
|
||||
|
||||
int (*set_hv_timer)(struct kvm_vcpu *vcpu, u64 guest_deadline_tsc,
|
||||
bool *expired);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#include "cpu.h"
|
||||
|
||||
static void __init spectre_v1_select_mitigation(void);
|
||||
static void __init spectre_v2_select_mitigation(void);
|
||||
static void __init ssb_select_mitigation(void);
|
||||
static void __init l1tf_select_mitigation(void);
|
||||
|
|
@ -98,17 +99,11 @@ void __init check_bugs(void)
|
|||
if (boot_cpu_has(X86_FEATURE_STIBP))
|
||||
x86_spec_ctrl_mask |= SPEC_CTRL_STIBP;
|
||||
|
||||
/* Select the proper spectre mitigation before patching alternatives */
|
||||
/* Select the proper CPU mitigations before patching alternatives: */
|
||||
spectre_v1_select_mitigation();
|
||||
spectre_v2_select_mitigation();
|
||||
|
||||
/*
|
||||
* Select proper mitigation for any exposure to the Speculative Store
|
||||
* Bypass vulnerability.
|
||||
*/
|
||||
ssb_select_mitigation();
|
||||
|
||||
l1tf_select_mitigation();
|
||||
|
||||
mds_select_mitigation();
|
||||
|
||||
arch_smt_update();
|
||||
|
|
@ -273,6 +268,98 @@ static int __init mds_cmdline(char *str)
|
|||
}
|
||||
early_param("mds", mds_cmdline);
|
||||
|
||||
#undef pr_fmt
|
||||
#define pr_fmt(fmt) "Spectre V1 : " fmt
|
||||
|
||||
enum spectre_v1_mitigation {
|
||||
SPECTRE_V1_MITIGATION_NONE,
|
||||
SPECTRE_V1_MITIGATION_AUTO,
|
||||
};
|
||||
|
||||
static enum spectre_v1_mitigation spectre_v1_mitigation __ro_after_init =
|
||||
SPECTRE_V1_MITIGATION_AUTO;
|
||||
|
||||
static const char * const spectre_v1_strings[] = {
|
||||
[SPECTRE_V1_MITIGATION_NONE] = "Vulnerable: __user pointer sanitization and usercopy barriers only; no swapgs barriers",
|
||||
[SPECTRE_V1_MITIGATION_AUTO] = "Mitigation: usercopy/swapgs barriers and __user pointer sanitization",
|
||||
};
|
||||
|
||||
/*
|
||||
* Does SMAP provide full mitigation against speculative kernel access to
|
||||
* userspace?
|
||||
*/
|
||||
static bool smap_works_speculatively(void)
|
||||
{
|
||||
if (!boot_cpu_has(X86_FEATURE_SMAP))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* On CPUs which are vulnerable to Meltdown, SMAP does not
|
||||
* prevent speculative access to user data in the L1 cache.
|
||||
* Consider SMAP to be non-functional as a mitigation on these
|
||||
* CPUs.
|
||||
*/
|
||||
if (boot_cpu_has(X86_BUG_CPU_MELTDOWN))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __init spectre_v1_select_mitigation(void)
|
||||
{
|
||||
if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V1) || cpu_mitigations_off()) {
|
||||
spectre_v1_mitigation = SPECTRE_V1_MITIGATION_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (spectre_v1_mitigation == SPECTRE_V1_MITIGATION_AUTO) {
|
||||
/*
|
||||
* With Spectre v1, a user can speculatively control either
|
||||
* path of a conditional swapgs with a user-controlled GS
|
||||
* value. The mitigation is to add lfences to both code paths.
|
||||
*
|
||||
* If FSGSBASE is enabled, the user can put a kernel address in
|
||||
* GS, in which case SMAP provides no protection.
|
||||
*
|
||||
* [ NOTE: Don't check for X86_FEATURE_FSGSBASE until the
|
||||
* FSGSBASE enablement patches have been merged. ]
|
||||
*
|
||||
* If FSGSBASE is disabled, the user can only put a user space
|
||||
* address in GS. That makes an attack harder, but still
|
||||
* possible if there's no SMAP protection.
|
||||
*/
|
||||
if (!smap_works_speculatively()) {
|
||||
/*
|
||||
* Mitigation can be provided from SWAPGS itself or
|
||||
* PTI as the CR3 write in the Meltdown mitigation
|
||||
* is serializing.
|
||||
*
|
||||
* If neither is there, mitigate with an LFENCE to
|
||||
* stop speculation through swapgs.
|
||||
*/
|
||||
if (boot_cpu_has_bug(X86_BUG_SWAPGS) &&
|
||||
!boot_cpu_has(X86_FEATURE_PTI))
|
||||
setup_force_cpu_cap(X86_FEATURE_FENCE_SWAPGS_USER);
|
||||
|
||||
/*
|
||||
* Enable lfences in the kernel entry (non-swapgs)
|
||||
* paths, to prevent user entry from speculatively
|
||||
* skipping swapgs.
|
||||
*/
|
||||
setup_force_cpu_cap(X86_FEATURE_FENCE_SWAPGS_KERNEL);
|
||||
}
|
||||
}
|
||||
|
||||
pr_info("%s\n", spectre_v1_strings[spectre_v1_mitigation]);
|
||||
}
|
||||
|
||||
static int __init nospectre_v1_cmdline(char *str)
|
||||
{
|
||||
spectre_v1_mitigation = SPECTRE_V1_MITIGATION_NONE;
|
||||
return 0;
|
||||
}
|
||||
early_param("nospectre_v1", nospectre_v1_cmdline);
|
||||
|
||||
#undef pr_fmt
|
||||
#define pr_fmt(fmt) "Spectre V2 : " fmt
|
||||
|
||||
|
|
@ -1290,7 +1377,7 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
|
|||
break;
|
||||
|
||||
case X86_BUG_SPECTRE_V1:
|
||||
return sprintf(buf, "Mitigation: __user pointer sanitization\n");
|
||||
return sprintf(buf, "%s\n", spectre_v1_strings[spectre_v1_mitigation]);
|
||||
|
||||
case X86_BUG_SPECTRE_V2:
|
||||
return sprintf(buf, "%s%s%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled],
|
||||
|
|
|
|||
|
|
@ -1022,6 +1022,7 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
|
|||
#define NO_L1TF BIT(3)
|
||||
#define NO_MDS BIT(4)
|
||||
#define MSBDS_ONLY BIT(5)
|
||||
#define NO_SWAPGS BIT(6)
|
||||
|
||||
#define VULNWL(_vendor, _family, _model, _whitelist) \
|
||||
{ X86_VENDOR_##_vendor, _family, _model, X86_FEATURE_ANY, _whitelist }
|
||||
|
|
@ -1048,30 +1049,38 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
|
|||
VULNWL_INTEL(ATOM_BONNELL, NO_SPECULATION),
|
||||
VULNWL_INTEL(ATOM_BONNELL_MID, NO_SPECULATION),
|
||||
|
||||
VULNWL_INTEL(ATOM_SILVERMONT, NO_SSB | NO_L1TF | MSBDS_ONLY),
|
||||
VULNWL_INTEL(ATOM_SILVERMONT_X, NO_SSB | NO_L1TF | MSBDS_ONLY),
|
||||
VULNWL_INTEL(ATOM_SILVERMONT_MID, NO_SSB | NO_L1TF | MSBDS_ONLY),
|
||||
VULNWL_INTEL(ATOM_AIRMONT, NO_SSB | NO_L1TF | MSBDS_ONLY),
|
||||
VULNWL_INTEL(XEON_PHI_KNL, NO_SSB | NO_L1TF | MSBDS_ONLY),
|
||||
VULNWL_INTEL(XEON_PHI_KNM, NO_SSB | NO_L1TF | MSBDS_ONLY),
|
||||
VULNWL_INTEL(ATOM_SILVERMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
|
||||
VULNWL_INTEL(ATOM_SILVERMONT_X, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
|
||||
VULNWL_INTEL(ATOM_SILVERMONT_MID, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
|
||||
VULNWL_INTEL(ATOM_AIRMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
|
||||
VULNWL_INTEL(XEON_PHI_KNL, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
|
||||
VULNWL_INTEL(XEON_PHI_KNM, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
|
||||
|
||||
VULNWL_INTEL(CORE_YONAH, NO_SSB),
|
||||
|
||||
VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY),
|
||||
VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
|
||||
|
||||
VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF),
|
||||
VULNWL_INTEL(ATOM_GOLDMONT_X, NO_MDS | NO_L1TF),
|
||||
VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF),
|
||||
VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS),
|
||||
VULNWL_INTEL(ATOM_GOLDMONT_X, NO_MDS | NO_L1TF | NO_SWAPGS),
|
||||
VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS),
|
||||
|
||||
/*
|
||||
* Technically, swapgs isn't serializing on AMD (despite it previously
|
||||
* being documented as such in the APM). But according to AMD, %gs is
|
||||
* updated non-speculatively, and the issuing of %gs-relative memory
|
||||
* operands will be blocked until the %gs update completes, which is
|
||||
* good enough for our purposes.
|
||||
*/
|
||||
|
||||
/* AMD Family 0xf - 0x12 */
|
||||
VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
|
||||
VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
|
||||
VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
|
||||
VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
|
||||
VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS),
|
||||
VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS),
|
||||
VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS),
|
||||
VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS),
|
||||
|
||||
/* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */
|
||||
VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS),
|
||||
VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS),
|
||||
VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS),
|
||||
VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS),
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
@ -1108,6 +1117,9 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
|
|||
setup_force_cpu_bug(X86_BUG_MSBDS_ONLY);
|
||||
}
|
||||
|
||||
if (!cpu_matches(NO_SWAPGS))
|
||||
setup_force_cpu_bug(X86_BUG_SWAPGS);
|
||||
|
||||
if (cpu_matches(NO_MELTDOWN))
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ cyrix_get_free_region(unsigned long base, unsigned long size, int replace_reg)
|
|||
case 7:
|
||||
if (size < 0x40)
|
||||
break;
|
||||
/* Else, fall through */
|
||||
case 6:
|
||||
case 5:
|
||||
case 4:
|
||||
|
|
|
|||
|
|
@ -308,9 +308,6 @@ static notrace void kvm_guest_apic_eoi_write(u32 reg, u32 val)
|
|||
|
||||
static void kvm_guest_cpu_init(void)
|
||||
{
|
||||
if (!kvm_para_available())
|
||||
return;
|
||||
|
||||
if (kvm_para_has_feature(KVM_FEATURE_ASYNC_PF) && kvmapf) {
|
||||
u64 pa = slow_virt_to_phys(this_cpu_ptr(&apf_reason));
|
||||
|
||||
|
|
@ -625,9 +622,6 @@ static void __init kvm_guest_init(void)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (!kvm_para_available())
|
||||
return;
|
||||
|
||||
paravirt_ops_setup();
|
||||
register_reboot_notifier(&kvm_pv_reboot_nb);
|
||||
for (i = 0; i < KVM_TASK_SLEEP_HASHSIZE; i++)
|
||||
|
|
@ -848,8 +842,6 @@ asm(
|
|||
*/
|
||||
void __init kvm_spinlock_init(void)
|
||||
{
|
||||
if (!kvm_para_available())
|
||||
return;
|
||||
/* Does host kernel support KVM_FEATURE_PV_UNHALT? */
|
||||
if (!kvm_para_has_feature(KVM_FEATURE_PV_UNHALT))
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -201,6 +201,7 @@ static int set_segment_reg(struct task_struct *task,
|
|||
case offsetof(struct user_regs_struct, ss):
|
||||
if (unlikely(value == 0))
|
||||
return -EIO;
|
||||
/* Else, fall through */
|
||||
|
||||
default:
|
||||
*pt_regs_access(task_pt_regs(task), offset) = value;
|
||||
|
|
|
|||
|
|
@ -8,11 +8,6 @@
|
|||
#include <linux/debugfs.h>
|
||||
#include "lapic.h"
|
||||
|
||||
bool kvm_arch_has_vcpu_debugfs(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static int vcpu_get_timer_advance_ns(void *data, u64 *val)
|
||||
{
|
||||
struct kvm_vcpu *vcpu = (struct kvm_vcpu *) data;
|
||||
|
|
@ -48,37 +43,22 @@ static int vcpu_get_tsc_scaling_frac_bits(void *data, u64 *val)
|
|||
|
||||
DEFINE_SIMPLE_ATTRIBUTE(vcpu_tsc_scaling_frac_fops, vcpu_get_tsc_scaling_frac_bits, NULL, "%llu\n");
|
||||
|
||||
int kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu)
|
||||
void kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct dentry *ret;
|
||||
debugfs_create_file("tsc-offset", 0444, vcpu->debugfs_dentry, vcpu,
|
||||
&vcpu_tsc_offset_fops);
|
||||
|
||||
ret = debugfs_create_file("tsc-offset", 0444,
|
||||
vcpu->debugfs_dentry,
|
||||
vcpu, &vcpu_tsc_offset_fops);
|
||||
if (!ret)
|
||||
return -ENOMEM;
|
||||
|
||||
if (lapic_in_kernel(vcpu)) {
|
||||
ret = debugfs_create_file("lapic_timer_advance_ns", 0444,
|
||||
vcpu->debugfs_dentry,
|
||||
vcpu, &vcpu_timer_advance_ns_fops);
|
||||
if (!ret)
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (lapic_in_kernel(vcpu))
|
||||
debugfs_create_file("lapic_timer_advance_ns", 0444,
|
||||
vcpu->debugfs_dentry, vcpu,
|
||||
&vcpu_timer_advance_ns_fops);
|
||||
|
||||
if (kvm_has_tsc_control) {
|
||||
ret = debugfs_create_file("tsc-scaling-ratio", 0444,
|
||||
vcpu->debugfs_dentry,
|
||||
vcpu, &vcpu_tsc_scaling_fops);
|
||||
if (!ret)
|
||||
return -ENOMEM;
|
||||
ret = debugfs_create_file("tsc-scaling-ratio-frac-bits", 0444,
|
||||
vcpu->debugfs_dentry,
|
||||
vcpu, &vcpu_tsc_scaling_frac_fops);
|
||||
if (!ret)
|
||||
return -ENOMEM;
|
||||
|
||||
debugfs_create_file("tsc-scaling-ratio", 0444,
|
||||
vcpu->debugfs_dentry, vcpu,
|
||||
&vcpu_tsc_scaling_fops);
|
||||
debugfs_create_file("tsc-scaling-ratio-frac-bits", 0444,
|
||||
vcpu->debugfs_dentry, vcpu,
|
||||
&vcpu_tsc_scaling_frac_fops);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1548,7 +1548,6 @@ static void kvm_apic_inject_pending_timer_irqs(struct kvm_lapic *apic)
|
|||
static void apic_timer_expired(struct kvm_lapic *apic)
|
||||
{
|
||||
struct kvm_vcpu *vcpu = apic->vcpu;
|
||||
struct swait_queue_head *q = &vcpu->wq;
|
||||
struct kvm_timer *ktimer = &apic->lapic_timer;
|
||||
|
||||
if (atomic_read(&apic->lapic_timer.pending))
|
||||
|
|
@ -1566,13 +1565,6 @@ static void apic_timer_expired(struct kvm_lapic *apic)
|
|||
|
||||
atomic_inc(&apic->lapic_timer.pending);
|
||||
kvm_set_pending_timer(vcpu);
|
||||
|
||||
/*
|
||||
* For x86, the atomic_inc() is serialized, thus
|
||||
* using swait_active() is safe.
|
||||
*/
|
||||
if (swait_active(q))
|
||||
swake_up_one(q);
|
||||
}
|
||||
|
||||
static void start_sw_tscdeadline(struct kvm_lapic *apic)
|
||||
|
|
|
|||
|
|
@ -5190,6 +5190,11 @@ static void svm_deliver_avic_intr(struct kvm_vcpu *vcpu, int vec)
|
|||
kvm_vcpu_wake_up(vcpu);
|
||||
}
|
||||
|
||||
static bool svm_dy_apicv_has_pending_interrupt(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static void svm_ir_list_del(struct vcpu_svm *svm, struct amd_iommu_pi_data *pi)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
|
@ -7314,6 +7319,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
|
|||
|
||||
.pmu_ops = &amd_pmu_ops,
|
||||
.deliver_posted_interrupt = svm_deliver_avic_intr,
|
||||
.dy_apicv_has_pending_interrupt = svm_dy_apicv_has_pending_interrupt,
|
||||
.update_pi_irte = svm_update_pi_irte,
|
||||
.setup_mce = svm_setup_mce,
|
||||
|
||||
|
|
|
|||
|
|
@ -6117,6 +6117,11 @@ static int vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu)
|
|||
return max_irr;
|
||||
}
|
||||
|
||||
static bool vmx_dy_apicv_has_pending_interrupt(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return pi_test_on(vcpu_to_pi_desc(vcpu));
|
||||
}
|
||||
|
||||
static void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
|
||||
{
|
||||
if (!kvm_vcpu_apicv_active(vcpu))
|
||||
|
|
@ -7726,6 +7731,7 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = {
|
|||
.guest_apic_has_interrupt = vmx_guest_apic_has_interrupt,
|
||||
.sync_pir_to_irr = vmx_sync_pir_to_irr,
|
||||
.deliver_posted_interrupt = vmx_deliver_posted_interrupt,
|
||||
.dy_apicv_has_pending_interrupt = vmx_dy_apicv_has_pending_interrupt,
|
||||
|
||||
.set_tss_addr = vmx_set_tss_addr,
|
||||
.set_identity_map_addr = vmx_set_identity_map_addr,
|
||||
|
|
|
|||
|
|
@ -9698,6 +9698,22 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
|
|||
return kvm_vcpu_running(vcpu) || kvm_vcpu_has_events(vcpu);
|
||||
}
|
||||
|
||||
bool kvm_arch_dy_runnable(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (READ_ONCE(vcpu->arch.pv.pv_unhalted))
|
||||
return true;
|
||||
|
||||
if (kvm_test_request(KVM_REQ_NMI, vcpu) ||
|
||||
kvm_test_request(KVM_REQ_SMI, vcpu) ||
|
||||
kvm_test_request(KVM_REQ_EVENT, vcpu))
|
||||
return true;
|
||||
|
||||
if (vcpu->arch.apicv_active && kvm_x86_ops->dy_apicv_has_pending_interrupt(vcpu))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return vcpu->arch.preempted_in_kernel;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
#include <linux/types.h>
|
||||
#include <linux/export.h>
|
||||
#include <asm/cpu.h>
|
||||
|
||||
unsigned int x86_family(unsigned int sig)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ purgatory-y := purgatory.o stack.o setup-x86_$(BITS).o sha256.o entry64.o string
|
|||
targets += $(purgatory-y)
|
||||
PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y))
|
||||
|
||||
$(obj)/string.o: $(srctree)/arch/x86/boot/compressed/string.c FORCE
|
||||
$(call if_changed_rule,cc_o_c)
|
||||
|
||||
$(obj)/sha256.o: $(srctree)/lib/sha256.c FORCE
|
||||
$(call if_changed_rule,cc_o_c)
|
||||
|
||||
|
|
@ -17,11 +20,34 @@ KCOV_INSTRUMENT := n
|
|||
|
||||
# Default KBUILD_CFLAGS can have -pg option set when FTRACE is enabled. That
|
||||
# in turn leaves some undefined symbols like __fentry__ in purgatory and not
|
||||
# sure how to relocate those. Like kexec-tools, use custom flags.
|
||||
# sure how to relocate those.
|
||||
ifdef CONFIG_FUNCTION_TRACER
|
||||
CFLAGS_REMOVE_sha256.o += $(CC_FLAGS_FTRACE)
|
||||
CFLAGS_REMOVE_purgatory.o += $(CC_FLAGS_FTRACE)
|
||||
CFLAGS_REMOVE_string.o += $(CC_FLAGS_FTRACE)
|
||||
CFLAGS_REMOVE_kexec-purgatory.o += $(CC_FLAGS_FTRACE)
|
||||
endif
|
||||
|
||||
KBUILD_CFLAGS := -fno-strict-aliasing -Wall -Wstrict-prototypes -fno-zero-initialized-in-bss -fno-builtin -ffreestanding -c -Os -mcmodel=large
|
||||
KBUILD_CFLAGS += -m$(BITS)
|
||||
KBUILD_CFLAGS += $(call cc-option,-fno-PIE)
|
||||
ifdef CONFIG_STACKPROTECTOR
|
||||
CFLAGS_REMOVE_sha256.o += -fstack-protector
|
||||
CFLAGS_REMOVE_purgatory.o += -fstack-protector
|
||||
CFLAGS_REMOVE_string.o += -fstack-protector
|
||||
CFLAGS_REMOVE_kexec-purgatory.o += -fstack-protector
|
||||
endif
|
||||
|
||||
ifdef CONFIG_STACKPROTECTOR_STRONG
|
||||
CFLAGS_REMOVE_sha256.o += -fstack-protector-strong
|
||||
CFLAGS_REMOVE_purgatory.o += -fstack-protector-strong
|
||||
CFLAGS_REMOVE_string.o += -fstack-protector-strong
|
||||
CFLAGS_REMOVE_kexec-purgatory.o += -fstack-protector-strong
|
||||
endif
|
||||
|
||||
ifdef CONFIG_RETPOLINE
|
||||
CFLAGS_REMOVE_sha256.o += $(RETPOLINE_CFLAGS)
|
||||
CFLAGS_REMOVE_purgatory.o += $(RETPOLINE_CFLAGS)
|
||||
CFLAGS_REMOVE_string.o += $(RETPOLINE_CFLAGS)
|
||||
CFLAGS_REMOVE_kexec-purgatory.o += $(RETPOLINE_CFLAGS)
|
||||
endif
|
||||
|
||||
$(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE
|
||||
$(call if_changed,ld)
|
||||
|
|
|
|||
|
|
@ -68,3 +68,9 @@ void purgatory(void)
|
|||
}
|
||||
copy_backup_region();
|
||||
}
|
||||
|
||||
/*
|
||||
* Defined in order to reuse memcpy() and memset() from
|
||||
* arch/x86/boot/compressed/string.c
|
||||
*/
|
||||
void warn(const char *msg) {}
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Simple string functions.
|
||||
*
|
||||
* Copyright (C) 2014 Red Hat Inc.
|
||||
*
|
||||
* Author:
|
||||
* Vivek Goyal <vgoyal@redhat.com>
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "../boot/string.c"
|
||||
|
||||
void *memcpy(void *dst, const void *src, size_t len)
|
||||
{
|
||||
return __builtin_memcpy(dst, src, len);
|
||||
}
|
||||
|
||||
void *memset(void *dst, int c, size_t len)
|
||||
{
|
||||
return __builtin_memset(dst, c, len);
|
||||
}
|
||||
|
|
@ -1924,12 +1924,13 @@ static void bfq_add_request(struct request *rq)
|
|||
* confirmed no later than during the next
|
||||
* I/O-plugging interval for bfqq.
|
||||
*/
|
||||
if (!bfq_bfqq_has_short_ttime(bfqq) &&
|
||||
if (bfqd->last_completed_rq_bfqq &&
|
||||
!bfq_bfqq_has_short_ttime(bfqq) &&
|
||||
ktime_get_ns() - bfqd->last_completion <
|
||||
200 * NSEC_PER_USEC) {
|
||||
if (bfqd->last_completed_rq_bfqq != bfqq &&
|
||||
bfqd->last_completed_rq_bfqq !=
|
||||
bfqq->waker_bfqq) {
|
||||
bfqd->last_completed_rq_bfqq !=
|
||||
bfqq->waker_bfqq) {
|
||||
/*
|
||||
* First synchronization detected with
|
||||
* a candidate waker queue, or with a
|
||||
|
|
@ -2250,9 +2251,14 @@ static void bfq_request_merged(struct request_queue *q, struct request *req,
|
|||
blk_rq_pos(container_of(rb_prev(&req->rb_node),
|
||||
struct request, rb_node))) {
|
||||
struct bfq_queue *bfqq = bfq_init_rq(req);
|
||||
struct bfq_data *bfqd = bfqq->bfqd;
|
||||
struct bfq_data *bfqd;
|
||||
struct request *prev, *next_rq;
|
||||
|
||||
if (!bfqq)
|
||||
return;
|
||||
|
||||
bfqd = bfqq->bfqd;
|
||||
|
||||
/* Reposition request in its sort_list */
|
||||
elv_rb_del(&bfqq->sort_list, req);
|
||||
elv_rb_add(&bfqq->sort_list, req);
|
||||
|
|
@ -2299,6 +2305,9 @@ static void bfq_requests_merged(struct request_queue *q, struct request *rq,
|
|||
struct bfq_queue *bfqq = bfq_init_rq(rq),
|
||||
*next_bfqq = bfq_init_rq(next);
|
||||
|
||||
if (!bfqq)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If next and rq belong to the same bfq_queue and next is older
|
||||
* than rq, then reposition rq in the fifo (by substituting next
|
||||
|
|
@ -4764,6 +4773,8 @@ static struct request *bfq_dispatch_request(struct blk_mq_hw_ctx *hctx)
|
|||
*/
|
||||
void bfq_put_queue(struct bfq_queue *bfqq)
|
||||
{
|
||||
struct bfq_queue *item;
|
||||
struct hlist_node *n;
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
struct bfq_group *bfqg = bfqq_group(bfqq);
|
||||
#endif
|
||||
|
|
@ -4808,6 +4819,36 @@ void bfq_put_queue(struct bfq_queue *bfqq)
|
|||
bfqq->bfqd->burst_size--;
|
||||
}
|
||||
|
||||
/*
|
||||
* bfqq does not exist any longer, so it cannot be woken by
|
||||
* any other queue, and cannot wake any other queue. Then bfqq
|
||||
* must be removed from the woken list of its possible waker
|
||||
* queue, and all queues in the woken list of bfqq must stop
|
||||
* having a waker queue. Strictly speaking, these updates
|
||||
* should be performed when bfqq remains with no I/O source
|
||||
* attached to it, which happens before bfqq gets freed. In
|
||||
* particular, this happens when the last process associated
|
||||
* with bfqq exits or gets associated with a different
|
||||
* queue. However, both events lead to bfqq being freed soon,
|
||||
* and dangling references would come out only after bfqq gets
|
||||
* freed. So these updates are done here, as a simple and safe
|
||||
* way to handle all cases.
|
||||
*/
|
||||
/* remove bfqq from woken list */
|
||||
if (!hlist_unhashed(&bfqq->woken_list_node))
|
||||
hlist_del_init(&bfqq->woken_list_node);
|
||||
|
||||
/* reset waker for all queues in woken list */
|
||||
hlist_for_each_entry_safe(item, n, &bfqq->woken_list,
|
||||
woken_list_node) {
|
||||
item->waker_bfqq = NULL;
|
||||
bfq_clear_bfqq_has_waker(item);
|
||||
hlist_del_init(&item->woken_list_node);
|
||||
}
|
||||
|
||||
if (bfqq->bfqd && bfqq->bfqd->last_completed_rq_bfqq == bfqq)
|
||||
bfqq->bfqd->last_completed_rq_bfqq = NULL;
|
||||
|
||||
kmem_cache_free(bfq_pool, bfqq);
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
bfqg_and_blkg_put(bfqg);
|
||||
|
|
@ -4835,9 +4876,6 @@ static void bfq_put_cooperator(struct bfq_queue *bfqq)
|
|||
|
||||
static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq)
|
||||
{
|
||||
struct bfq_queue *item;
|
||||
struct hlist_node *n;
|
||||
|
||||
if (bfqq == bfqd->in_service_queue) {
|
||||
__bfq_bfqq_expire(bfqd, bfqq, BFQQE_BUDGET_TIMEOUT);
|
||||
bfq_schedule_dispatch(bfqd);
|
||||
|
|
@ -4847,18 +4885,6 @@ static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq)
|
|||
|
||||
bfq_put_cooperator(bfqq);
|
||||
|
||||
/* remove bfqq from woken list */
|
||||
if (!hlist_unhashed(&bfqq->woken_list_node))
|
||||
hlist_del_init(&bfqq->woken_list_node);
|
||||
|
||||
/* reset waker for all queues in woken list */
|
||||
hlist_for_each_entry_safe(item, n, &bfqq->woken_list,
|
||||
woken_list_node) {
|
||||
item->waker_bfqq = NULL;
|
||||
bfq_clear_bfqq_has_waker(item);
|
||||
hlist_del_init(&item->woken_list_node);
|
||||
}
|
||||
|
||||
bfq_put_queue(bfqq); /* release process reference */
|
||||
}
|
||||
|
||||
|
|
@ -5436,12 +5462,12 @@ static void bfq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
|
|||
|
||||
spin_lock_irq(&bfqd->lock);
|
||||
bfqq = bfq_init_rq(rq);
|
||||
if (at_head || blk_rq_is_passthrough(rq)) {
|
||||
if (!bfqq || at_head || blk_rq_is_passthrough(rq)) {
|
||||
if (at_head)
|
||||
list_add(&rq->queuelist, &bfqd->dispatch);
|
||||
else
|
||||
list_add_tail(&rq->queuelist, &bfqd->dispatch);
|
||||
} else { /* bfqq is assumed to be non null here */
|
||||
} else {
|
||||
idle_timer_disabled = __bfq_insert_request(bfqd, rq);
|
||||
/*
|
||||
* Update bfqq, because, if a queue merge has occurred
|
||||
|
|
|
|||
|
|
@ -1786,6 +1786,21 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static bool ata_check_nblocks(struct scsi_cmnd *scmd, u32 n_blocks)
|
||||
{
|
||||
struct request *rq = scmd->request;
|
||||
u32 req_blocks;
|
||||
|
||||
if (!blk_rq_is_passthrough(rq))
|
||||
return true;
|
||||
|
||||
req_blocks = blk_rq_bytes(rq) / scmd->device->sector_size;
|
||||
if (n_blocks > req_blocks)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_scsi_rw_xlat - Translate SCSI r/w command into an ATA one
|
||||
* @qc: Storage for translated ATA taskfile
|
||||
|
|
@ -1830,6 +1845,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
|
|||
scsi_10_lba_len(cdb, &block, &n_block);
|
||||
if (cdb[1] & (1 << 3))
|
||||
tf_flags |= ATA_TFLAG_FUA;
|
||||
if (!ata_check_nblocks(scmd, n_block))
|
||||
goto invalid_fld;
|
||||
break;
|
||||
case READ_6:
|
||||
case WRITE_6:
|
||||
|
|
@ -1844,6 +1861,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
|
|||
*/
|
||||
if (!n_block)
|
||||
n_block = 256;
|
||||
if (!ata_check_nblocks(scmd, n_block))
|
||||
goto invalid_fld;
|
||||
break;
|
||||
case READ_16:
|
||||
case WRITE_16:
|
||||
|
|
@ -1854,6 +1873,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
|
|||
scsi_16_lba_len(cdb, &block, &n_block);
|
||||
if (cdb[1] & (1 << 3))
|
||||
tf_flags |= ATA_TFLAG_FUA;
|
||||
if (!ata_check_nblocks(scmd, n_block))
|
||||
goto invalid_fld;
|
||||
break;
|
||||
default:
|
||||
DPRINTK("no-byte command\n");
|
||||
|
|
|
|||
|
|
@ -658,6 +658,10 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
|
|||
unsigned int offset;
|
||||
unsigned char *buf;
|
||||
|
||||
if (!qc->cursg) {
|
||||
qc->curbytes = qc->nbytes;
|
||||
return;
|
||||
}
|
||||
if (qc->curbytes == qc->nbytes - qc->sect_size)
|
||||
ap->hsm_task_state = HSM_ST_LAST;
|
||||
|
||||
|
|
@ -683,6 +687,8 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
|
|||
|
||||
if (qc->cursg_ofs == qc->cursg->length) {
|
||||
qc->cursg = sg_next(qc->cursg);
|
||||
if (!qc->cursg)
|
||||
ap->hsm_task_state = HSM_ST_LAST;
|
||||
qc->cursg_ofs = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -158,7 +158,6 @@ static int rb532_pata_driver_probe(struct platform_device *pdev)
|
|||
static int rb532_pata_driver_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct ata_host *ah = platform_get_drvdata(pdev);
|
||||
struct rb532_cf_info *info = ah->private_data;
|
||||
|
||||
ata_host_detach(ah);
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@
|
|||
#include <asm/byteorder.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/nospec.h>
|
||||
#include "iphase.h"
|
||||
#include "suni.h"
|
||||
#define swap_byte_order(x) (((x & 0xff) << 8) | ((x & 0xff00) >> 8))
|
||||
|
|
@ -2760,8 +2761,11 @@ static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
|
|||
}
|
||||
if (copy_from_user(&ia_cmds, arg, sizeof ia_cmds)) return -EFAULT;
|
||||
board = ia_cmds.status;
|
||||
if ((board < 0) || (board > iadev_count))
|
||||
board = 0;
|
||||
|
||||
if ((board < 0) || (board > iadev_count))
|
||||
board = 0;
|
||||
board = array_index_nospec(board, iadev_count + 1);
|
||||
|
||||
iadev = ia_dev[board];
|
||||
switch (ia_cmds.cmd) {
|
||||
case MEMDUMP:
|
||||
|
|
|
|||
|
|
@ -1823,12 +1823,63 @@ static inline struct kobject *get_glue_dir(struct device *dev)
|
|||
*/
|
||||
static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir)
|
||||
{
|
||||
unsigned int ref;
|
||||
|
||||
/* see if we live in a "glue" directory */
|
||||
if (!live_in_glue_dir(glue_dir, dev))
|
||||
return;
|
||||
|
||||
mutex_lock(&gdp_mutex);
|
||||
if (!kobject_has_children(glue_dir))
|
||||
/**
|
||||
* There is a race condition between removing glue directory
|
||||
* and adding a new device under the glue directory.
|
||||
*
|
||||
* CPU1: CPU2:
|
||||
*
|
||||
* device_add()
|
||||
* get_device_parent()
|
||||
* class_dir_create_and_add()
|
||||
* kobject_add_internal()
|
||||
* create_dir() // create glue_dir
|
||||
*
|
||||
* device_add()
|
||||
* get_device_parent()
|
||||
* kobject_get() // get glue_dir
|
||||
*
|
||||
* device_del()
|
||||
* cleanup_glue_dir()
|
||||
* kobject_del(glue_dir)
|
||||
*
|
||||
* kobject_add()
|
||||
* kobject_add_internal()
|
||||
* create_dir() // in glue_dir
|
||||
* sysfs_create_dir_ns()
|
||||
* kernfs_create_dir_ns(sd)
|
||||
*
|
||||
* sysfs_remove_dir() // glue_dir->sd=NULL
|
||||
* sysfs_put() // free glue_dir->sd
|
||||
*
|
||||
* // sd is freed
|
||||
* kernfs_new_node(sd)
|
||||
* kernfs_get(glue_dir)
|
||||
* kernfs_add_one()
|
||||
* kernfs_put()
|
||||
*
|
||||
* Before CPU1 remove last child device under glue dir, if CPU2 add
|
||||
* a new device under glue dir, the glue_dir kobject reference count
|
||||
* will be increase to 2 in kobject_get(k). And CPU2 has been called
|
||||
* kernfs_create_dir_ns(). Meanwhile, CPU1 call sysfs_remove_dir()
|
||||
* and sysfs_put(). This result in glue_dir->sd is freed.
|
||||
*
|
||||
* Then the CPU2 will see a stale "empty" but still potentially used
|
||||
* glue dir around in kernfs_new_node().
|
||||
*
|
||||
* In order to avoid this happening, we also should make sure that
|
||||
* kernfs_node for glue_dir is released in CPU1 only when refcount
|
||||
* for glue_dir kobj is 1.
|
||||
*/
|
||||
ref = kref_read(&glue_dir->kref);
|
||||
if (!kobject_has_children(glue_dir) && !--ref)
|
||||
kobject_del(glue_dir);
|
||||
kobject_put(glue_dir);
|
||||
mutex_unlock(&gdp_mutex);
|
||||
|
|
|
|||
|
|
@ -157,8 +157,13 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
|
|||
* the device will only expose one IRQ, and this fallback
|
||||
* allows a common code path across either kind of resource.
|
||||
*/
|
||||
if (num == 0 && has_acpi_companion(&dev->dev))
|
||||
return acpi_dev_gpio_irq_get(ACPI_COMPANION(&dev->dev), num);
|
||||
if (num == 0 && has_acpi_companion(&dev->dev)) {
|
||||
int ret = acpi_dev_gpio_irq_get(ACPI_COMPANION(&dev->dev), num);
|
||||
|
||||
/* Our callers expect -ENXIO for missing IRQs. */
|
||||
if (ret >= 0 || ret == -EPROBE_DEFER)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return -ENXIO;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -323,10 +323,14 @@ flush(const char __user *str, size_t cnt, int exiting)
|
|||
}
|
||||
|
||||
flush_scheduled_work();
|
||||
/* pass one: without sleeping, do aoedev_downdev */
|
||||
/* pass one: do aoedev_downdev, which might sleep */
|
||||
restart1:
|
||||
spin_lock_irqsave(&devlist_lock, flags);
|
||||
for (d = devlist; d; d = d->next) {
|
||||
spin_lock(&d->lock);
|
||||
if (d->flags & DEVFL_TKILL)
|
||||
goto cont;
|
||||
|
||||
if (exiting) {
|
||||
/* unconditionally take each device down */
|
||||
} else if (specified) {
|
||||
|
|
@ -338,8 +342,11 @@ flush(const char __user *str, size_t cnt, int exiting)
|
|||
|| d->ref)
|
||||
goto cont;
|
||||
|
||||
spin_unlock(&d->lock);
|
||||
spin_unlock_irqrestore(&devlist_lock, flags);
|
||||
aoedev_downdev(d);
|
||||
d->flags |= DEVFL_TKILL;
|
||||
goto restart1;
|
||||
cont:
|
||||
spin_unlock(&d->lock);
|
||||
}
|
||||
|
|
@ -348,7 +355,7 @@ flush(const char __user *str, size_t cnt, int exiting)
|
|||
/* pass two: call freedev, which might sleep,
|
||||
* for aoedevs marked with DEVFL_TKILL
|
||||
*/
|
||||
restart:
|
||||
restart2:
|
||||
spin_lock_irqsave(&devlist_lock, flags);
|
||||
for (d = devlist; d; d = d->next) {
|
||||
spin_lock(&d->lock);
|
||||
|
|
@ -357,7 +364,7 @@ flush(const char __user *str, size_t cnt, int exiting)
|
|||
spin_unlock(&d->lock);
|
||||
spin_unlock_irqrestore(&devlist_lock, flags);
|
||||
freedev(d);
|
||||
goto restart;
|
||||
goto restart2;
|
||||
}
|
||||
spin_unlock(&d->lock);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -885,7 +885,7 @@ static void loop_unprepare_queue(struct loop_device *lo)
|
|||
|
||||
static int loop_kthread_worker_fn(void *worker_ptr)
|
||||
{
|
||||
current->flags |= PF_LESS_THROTTLE;
|
||||
current->flags |= PF_LESS_THROTTLE | PF_MEMALLOC_NOIO;
|
||||
return kthread_worker_fn(worker_ptr);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ static u64 riscv_sched_clock(void)
|
|||
return get_cycles64();
|
||||
}
|
||||
|
||||
static DEFINE_PER_CPU(struct clocksource, riscv_clocksource) = {
|
||||
static struct clocksource riscv_clocksource = {
|
||||
.name = "riscv_clocksource",
|
||||
.rating = 300,
|
||||
.mask = CLOCKSOURCE_MASK(64),
|
||||
|
|
@ -92,7 +92,6 @@ void riscv_timer_interrupt(void)
|
|||
static int __init riscv_timer_init_dt(struct device_node *n)
|
||||
{
|
||||
int cpuid, hartid, error;
|
||||
struct clocksource *cs;
|
||||
|
||||
hartid = riscv_of_processor_hartid(n);
|
||||
if (hartid < 0) {
|
||||
|
|
@ -112,8 +111,7 @@ static int __init riscv_timer_init_dt(struct device_node *n)
|
|||
|
||||
pr_info("%s: Registering clocksource cpuid [%d] hartid [%d]\n",
|
||||
__func__, cpuid, hartid);
|
||||
cs = per_cpu_ptr(&riscv_clocksource, cpuid);
|
||||
error = clocksource_register_hz(cs, riscv_timebase);
|
||||
error = clocksource_register_hz(&riscv_clocksource, riscv_timebase);
|
||||
if (error) {
|
||||
pr_err("RISCV timer register failed [%d] for cpu = [%d]\n",
|
||||
error, cpuid);
|
||||
|
|
|
|||
|
|
@ -58,6 +58,19 @@ static int ccp_aes_gcm_setkey(struct crypto_aead *tfm, const u8 *key,
|
|||
static int ccp_aes_gcm_setauthsize(struct crypto_aead *tfm,
|
||||
unsigned int authsize)
|
||||
{
|
||||
switch (authsize) {
|
||||
case 16:
|
||||
case 15:
|
||||
case 14:
|
||||
case 13:
|
||||
case 12:
|
||||
case 8:
|
||||
case 4:
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -104,6 +117,7 @@ static int ccp_aes_gcm_crypt(struct aead_request *req, bool encrypt)
|
|||
memset(&rctx->cmd, 0, sizeof(rctx->cmd));
|
||||
INIT_LIST_HEAD(&rctx->cmd.entry);
|
||||
rctx->cmd.engine = CCP_ENGINE_AES;
|
||||
rctx->cmd.u.aes.authsize = crypto_aead_authsize(tfm);
|
||||
rctx->cmd.u.aes.type = ctx->u.aes.type;
|
||||
rctx->cmd.u.aes.mode = ctx->u.aes.mode;
|
||||
rctx->cmd.u.aes.action = encrypt;
|
||||
|
|
|
|||
|
|
@ -622,6 +622,7 @@ static int ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q,
|
|||
|
||||
unsigned long long *final;
|
||||
unsigned int dm_offset;
|
||||
unsigned int authsize;
|
||||
unsigned int jobid;
|
||||
unsigned int ilen;
|
||||
bool in_place = true; /* Default value */
|
||||
|
|
@ -643,6 +644,21 @@ static int ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q,
|
|||
if (!aes->key) /* Gotta have a key SGL */
|
||||
return -EINVAL;
|
||||
|
||||
/* Zero defaults to 16 bytes, the maximum size */
|
||||
authsize = aes->authsize ? aes->authsize : AES_BLOCK_SIZE;
|
||||
switch (authsize) {
|
||||
case 16:
|
||||
case 15:
|
||||
case 14:
|
||||
case 13:
|
||||
case 12:
|
||||
case 8:
|
||||
case 4:
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* First, decompose the source buffer into AAD & PT,
|
||||
* and the destination buffer into AAD, CT & tag, or
|
||||
* the input into CT & tag.
|
||||
|
|
@ -657,7 +673,7 @@ static int ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q,
|
|||
p_tag = scatterwalk_ffwd(sg_tag, p_outp, ilen);
|
||||
} else {
|
||||
/* Input length for decryption includes tag */
|
||||
ilen = aes->src_len - AES_BLOCK_SIZE;
|
||||
ilen = aes->src_len - authsize;
|
||||
p_tag = scatterwalk_ffwd(sg_tag, p_inp, ilen);
|
||||
}
|
||||
|
||||
|
|
@ -766,8 +782,7 @@ static int ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q,
|
|||
while (src.sg_wa.bytes_left) {
|
||||
ccp_prepare_data(&src, &dst, &op, AES_BLOCK_SIZE, true);
|
||||
if (!src.sg_wa.bytes_left) {
|
||||
unsigned int nbytes = aes->src_len
|
||||
% AES_BLOCK_SIZE;
|
||||
unsigned int nbytes = ilen % AES_BLOCK_SIZE;
|
||||
|
||||
if (nbytes) {
|
||||
op.eom = 1;
|
||||
|
|
@ -839,19 +854,19 @@ static int ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q,
|
|||
|
||||
if (aes->action == CCP_AES_ACTION_ENCRYPT) {
|
||||
/* Put the ciphered tag after the ciphertext. */
|
||||
ccp_get_dm_area(&final_wa, 0, p_tag, 0, AES_BLOCK_SIZE);
|
||||
ccp_get_dm_area(&final_wa, 0, p_tag, 0, authsize);
|
||||
} else {
|
||||
/* Does this ciphered tag match the input? */
|
||||
ret = ccp_init_dm_workarea(&tag, cmd_q, AES_BLOCK_SIZE,
|
||||
ret = ccp_init_dm_workarea(&tag, cmd_q, authsize,
|
||||
DMA_BIDIRECTIONAL);
|
||||
if (ret)
|
||||
goto e_tag;
|
||||
ret = ccp_set_dm_area(&tag, 0, p_tag, 0, AES_BLOCK_SIZE);
|
||||
ret = ccp_set_dm_area(&tag, 0, p_tag, 0, authsize);
|
||||
if (ret)
|
||||
goto e_tag;
|
||||
|
||||
ret = crypto_memneq(tag.address, final_wa.address,
|
||||
AES_BLOCK_SIZE) ? -EBADMSG : 0;
|
||||
authsize) ? -EBADMSG : 0;
|
||||
ccp_dm_free(&tag);
|
||||
}
|
||||
|
||||
|
|
@ -859,11 +874,11 @@ static int ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q,
|
|||
ccp_dm_free(&final_wa);
|
||||
|
||||
e_dst:
|
||||
if (aes->src_len && !in_place)
|
||||
if (ilen > 0 && !in_place)
|
||||
ccp_free_data(&dst, cmd_q);
|
||||
|
||||
e_src:
|
||||
if (aes->src_len)
|
||||
if (ilen > 0)
|
||||
ccp_free_data(&src, cmd_q);
|
||||
|
||||
e_aad:
|
||||
|
|
|
|||
|
|
@ -314,14 +314,17 @@ void cryp_save_device_context(struct cryp_device_data *device_data,
|
|||
case CRYP_KEY_SIZE_256:
|
||||
ctx->key_4_l = readl_relaxed(&src_reg->key_4_l);
|
||||
ctx->key_4_r = readl_relaxed(&src_reg->key_4_r);
|
||||
/* Fall through */
|
||||
|
||||
case CRYP_KEY_SIZE_192:
|
||||
ctx->key_3_l = readl_relaxed(&src_reg->key_3_l);
|
||||
ctx->key_3_r = readl_relaxed(&src_reg->key_3_r);
|
||||
/* Fall through */
|
||||
|
||||
case CRYP_KEY_SIZE_128:
|
||||
ctx->key_2_l = readl_relaxed(&src_reg->key_2_l);
|
||||
ctx->key_2_r = readl_relaxed(&src_reg->key_2_r);
|
||||
/* Fall through */
|
||||
|
||||
default:
|
||||
ctx->key_1_l = readl_relaxed(&src_reg->key_1_l);
|
||||
|
|
@ -361,14 +364,17 @@ void cryp_restore_device_context(struct cryp_device_data *device_data,
|
|||
case CRYP_KEY_SIZE_256:
|
||||
writel_relaxed(ctx->key_4_l, ®->key_4_l);
|
||||
writel_relaxed(ctx->key_4_r, ®->key_4_r);
|
||||
/* Fall through */
|
||||
|
||||
case CRYP_KEY_SIZE_192:
|
||||
writel_relaxed(ctx->key_3_l, ®->key_3_l);
|
||||
writel_relaxed(ctx->key_3_r, ®->key_3_r);
|
||||
/* Fall through */
|
||||
|
||||
case CRYP_KEY_SIZE_128:
|
||||
writel_relaxed(ctx->key_2_l, ®->key_2_l);
|
||||
writel_relaxed(ctx->key_2_r, ®->key_2_r);
|
||||
/* Fall through */
|
||||
|
||||
default:
|
||||
writel_relaxed(ctx->key_1_l, ®->key_1_l);
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ struct amdgpu_gds {
|
|||
uint32_t gws_size;
|
||||
uint32_t oa_size;
|
||||
uint32_t gds_compute_max_wave_id;
|
||||
uint32_t vgt_gs_max_wave_id;
|
||||
};
|
||||
|
||||
struct amdgpu_gds_reg_offset {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#define AMDGPU_VCN_FIRMWARE_OFFSET 256
|
||||
#define AMDGPU_VCN_MAX_ENC_RINGS 3
|
||||
|
||||
#define VCN_DEC_KMD_CMD 0x80000000
|
||||
#define VCN_DEC_CMD_FENCE 0x00000000
|
||||
#define VCN_DEC_CMD_TRAP 0x00000001
|
||||
#define VCN_DEC_CMD_WRITE_REG 0x00000004
|
||||
|
|
|
|||
|
|
@ -4206,15 +4206,6 @@ static void gfx_v10_0_ring_emit_ib_gfx(struct amdgpu_ring *ring,
|
|||
unsigned vmid = AMDGPU_JOB_GET_VMID(job);
|
||||
u32 header, control = 0;
|
||||
|
||||
/* Prevent a hw deadlock due to a wave ID mismatch between ME and GDS.
|
||||
* This resets the wave ID counters. (needed by transform feedback)
|
||||
* TODO: This might only be needed on a VMID switch when we change
|
||||
* the GDS OA mapping, not sure.
|
||||
*/
|
||||
amdgpu_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
|
||||
amdgpu_ring_write(ring, mmVGT_GS_MAX_WAVE_ID);
|
||||
amdgpu_ring_write(ring, ring->adev->gds.vgt_gs_max_wave_id);
|
||||
|
||||
if (ib->flags & AMDGPU_IB_FLAG_CE)
|
||||
header = PACKET3(PACKET3_INDIRECT_BUFFER_CNST, 2);
|
||||
else
|
||||
|
|
@ -4961,7 +4952,7 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_gfx = {
|
|||
5 + /* HDP_INVL */
|
||||
8 + 8 + /* FENCE x2 */
|
||||
2, /* SWITCH_BUFFER */
|
||||
.emit_ib_size = 7, /* gfx_v10_0_ring_emit_ib_gfx */
|
||||
.emit_ib_size = 4, /* gfx_v10_0_ring_emit_ib_gfx */
|
||||
.emit_ib = gfx_v10_0_ring_emit_ib_gfx,
|
||||
.emit_fence = gfx_v10_0_ring_emit_fence,
|
||||
.emit_pipeline_sync = gfx_v10_0_ring_emit_pipeline_sync,
|
||||
|
|
@ -5112,7 +5103,6 @@ static void gfx_v10_0_set_gds_init(struct amdgpu_device *adev)
|
|||
default:
|
||||
adev->gds.gds_size = 0x10000;
|
||||
adev->gds.gds_compute_max_wave_id = 0x4ff;
|
||||
adev->gds.vgt_gs_max_wave_id = 0x3ff;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1321,6 +1321,39 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int gfx_v8_0_csb_vram_pin(struct amdgpu_device *adev)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
|
||||
if (unlikely(r != 0))
|
||||
return r;
|
||||
|
||||
r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj,
|
||||
AMDGPU_GEM_DOMAIN_VRAM);
|
||||
if (!r)
|
||||
adev->gfx.rlc.clear_state_gpu_addr =
|
||||
amdgpu_bo_gpu_offset(adev->gfx.rlc.clear_state_obj);
|
||||
|
||||
amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void gfx_v8_0_csb_vram_unpin(struct amdgpu_device *adev)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!adev->gfx.rlc.clear_state_obj)
|
||||
return;
|
||||
|
||||
r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true);
|
||||
if (likely(r == 0)) {
|
||||
amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
|
||||
amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_v8_0_mec_fini(struct amdgpu_device *adev)
|
||||
{
|
||||
amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL);
|
||||
|
|
@ -4785,6 +4818,10 @@ static int gfx_v8_0_hw_init(void *handle)
|
|||
gfx_v8_0_init_golden_registers(adev);
|
||||
gfx_v8_0_constants_init(adev);
|
||||
|
||||
r = gfx_v8_0_csb_vram_pin(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = adev->gfx.rlc.funcs->resume(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
|
@ -4901,6 +4938,9 @@ static int gfx_v8_0_hw_fini(void *handle)
|
|||
else
|
||||
pr_err("rlc is busy, skip halt rlc\n");
|
||||
amdgpu_gfx_rlc_exit_safe_mode(adev);
|
||||
|
||||
gfx_v8_0_csb_vram_unpin(adev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1485,7 +1485,7 @@ static void vcn_v2_0_dec_ring_insert_start(struct amdgpu_ring *ring)
|
|||
amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET, 0));
|
||||
amdgpu_ring_write(ring, 0);
|
||||
amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET, 0));
|
||||
amdgpu_ring_write(ring, VCN_DEC_CMD_PACKET_START << 1);
|
||||
amdgpu_ring_write(ring, VCN_DEC_KMD_CMD | (VCN_DEC_CMD_PACKET_START << 1));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1498,7 +1498,7 @@ static void vcn_v2_0_dec_ring_insert_start(struct amdgpu_ring *ring)
|
|||
static void vcn_v2_0_dec_ring_insert_end(struct amdgpu_ring *ring)
|
||||
{
|
||||
amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET, 0));
|
||||
amdgpu_ring_write(ring, VCN_DEC_CMD_PACKET_END << 1);
|
||||
amdgpu_ring_write(ring, VCN_DEC_KMD_CMD | (VCN_DEC_CMD_PACKET_END << 1));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1543,7 +1543,7 @@ static void vcn_v2_0_dec_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64
|
|||
amdgpu_ring_write(ring, upper_32_bits(addr) & 0xff);
|
||||
|
||||
amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET, 0));
|
||||
amdgpu_ring_write(ring, VCN_DEC_CMD_FENCE << 1);
|
||||
amdgpu_ring_write(ring, VCN_DEC_KMD_CMD | (VCN_DEC_CMD_FENCE << 1));
|
||||
|
||||
amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET, 0));
|
||||
amdgpu_ring_write(ring, 0);
|
||||
|
|
@ -1553,7 +1553,7 @@ static void vcn_v2_0_dec_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64
|
|||
|
||||
amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET, 0));
|
||||
|
||||
amdgpu_ring_write(ring, VCN_DEC_CMD_TRAP << 1);
|
||||
amdgpu_ring_write(ring, VCN_DEC_KMD_CMD | (VCN_DEC_CMD_TRAP << 1));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1597,7 +1597,7 @@ static void vcn_v2_0_dec_ring_emit_reg_wait(struct amdgpu_ring *ring,
|
|||
|
||||
amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET, 0));
|
||||
|
||||
amdgpu_ring_write(ring, VCN_DEC_CMD_REG_READ_COND_WAIT << 1);
|
||||
amdgpu_ring_write(ring, VCN_DEC_KMD_CMD | (VCN_DEC_CMD_REG_READ_COND_WAIT << 1));
|
||||
}
|
||||
|
||||
static void vcn_v2_0_dec_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
||||
|
|
@ -1626,7 +1626,7 @@ static void vcn_v2_0_dec_ring_emit_wreg(struct amdgpu_ring *ring,
|
|||
|
||||
amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET, 0));
|
||||
|
||||
amdgpu_ring_write(ring, VCN_DEC_CMD_WRITE_REG << 1);
|
||||
amdgpu_ring_write(ring, VCN_DEC_KMD_CMD | (VCN_DEC_CMD_WRITE_REG << 1));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2079,6 +2079,36 @@ static int vcn_v2_0_process_interrupt(struct amdgpu_device *adev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int vcn_v2_0_dec_ring_test_ring(struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
uint32_t tmp = 0;
|
||||
unsigned i;
|
||||
int r;
|
||||
|
||||
WREG32(adev->vcn.external.scratch9, 0xCAFEDEAD);
|
||||
r = amdgpu_ring_alloc(ring, 4);
|
||||
if (r)
|
||||
return r;
|
||||
amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET, 0));
|
||||
amdgpu_ring_write(ring, VCN_DEC_KMD_CMD | (VCN_DEC_CMD_PACKET_START << 1));
|
||||
amdgpu_ring_write(ring, PACKET0(adev->vcn.internal.scratch9, 0));
|
||||
amdgpu_ring_write(ring, 0xDEADBEEF);
|
||||
amdgpu_ring_commit(ring);
|
||||
for (i = 0; i < adev->usec_timeout; i++) {
|
||||
tmp = RREG32(adev->vcn.external.scratch9);
|
||||
if (tmp == 0xDEADBEEF)
|
||||
break;
|
||||
DRM_UDELAY(1);
|
||||
}
|
||||
|
||||
if (i >= adev->usec_timeout)
|
||||
r = -ETIMEDOUT;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static int vcn_v2_0_set_powergating_state(void *handle,
|
||||
enum amd_powergating_state state)
|
||||
{
|
||||
|
|
@ -2142,7 +2172,7 @@ static const struct amdgpu_ring_funcs vcn_v2_0_dec_ring_vm_funcs = {
|
|||
.emit_ib = vcn_v2_0_dec_ring_emit_ib,
|
||||
.emit_fence = vcn_v2_0_dec_ring_emit_fence,
|
||||
.emit_vm_flush = vcn_v2_0_dec_ring_emit_vm_flush,
|
||||
.test_ring = amdgpu_vcn_dec_ring_test_ring,
|
||||
.test_ring = vcn_v2_0_dec_ring_test_ring,
|
||||
.test_ib = amdgpu_vcn_dec_ring_test_ib,
|
||||
.insert_nop = vcn_v2_0_dec_ring_insert_nop,
|
||||
.insert_start = vcn_v2_0_dec_ring_insert_start,
|
||||
|
|
|
|||
|
|
@ -1567,32 +1567,6 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int kfd_ioctl_alloc_queue_gws(struct file *filep,
|
||||
struct kfd_process *p, void *data)
|
||||
{
|
||||
int retval;
|
||||
struct kfd_ioctl_alloc_queue_gws_args *args = data;
|
||||
struct kfd_dev *dev;
|
||||
|
||||
if (!hws_gws_support)
|
||||
return -ENODEV;
|
||||
|
||||
dev = kfd_device_by_id(args->gpu_id);
|
||||
if (!dev) {
|
||||
pr_debug("Could not find gpu id 0x%x\n", args->gpu_id);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (dev->dqm->sched_policy == KFD_SCHED_POLICY_NO_HWS)
|
||||
return -ENODEV;
|
||||
|
||||
mutex_lock(&p->mutex);
|
||||
retval = pqm_set_gws(&p->pqm, args->queue_id, args->num_gws ? dev->gws : NULL);
|
||||
mutex_unlock(&p->mutex);
|
||||
|
||||
args->first_gws = 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int kfd_ioctl_get_dmabuf_info(struct file *filep,
|
||||
struct kfd_process *p, void *data)
|
||||
{
|
||||
|
|
@ -1795,8 +1769,6 @@ static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
|
|||
AMDKFD_IOCTL_DEF(AMDKFD_IOC_IMPORT_DMABUF,
|
||||
kfd_ioctl_import_dmabuf, 0),
|
||||
|
||||
AMDKFD_IOCTL_DEF(AMDKFD_IOC_ALLOC_QUEUE_GWS,
|
||||
kfd_ioctl_alloc_queue_gws, 0),
|
||||
};
|
||||
|
||||
#define AMDKFD_CORE_IOCTL_COUNT ARRAY_SIZE(amdkfd_ioctls)
|
||||
|
|
|
|||
|
|
@ -315,6 +315,8 @@ int smu_get_power_num_states(struct smu_context *smu,
|
|||
int smu_common_read_sensor(struct smu_context *smu, enum amd_pp_sensors sensor,
|
||||
void *data, uint32_t *size)
|
||||
{
|
||||
struct smu_power_context *smu_power = &smu->smu_power;
|
||||
struct smu_power_gate *power_gate = &smu_power->power_gate;
|
||||
int ret = 0;
|
||||
|
||||
switch (sensor) {
|
||||
|
|
@ -339,7 +341,7 @@ int smu_common_read_sensor(struct smu_context *smu, enum amd_pp_sensors sensor,
|
|||
*size = 4;
|
||||
break;
|
||||
case AMDGPU_PP_SENSOR_VCN_POWER_STATE:
|
||||
*(uint32_t *)data = smu_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT) ? 1 : 0;
|
||||
*(uint32_t *)data = power_gate->vcn_gated ? 0 : 1;
|
||||
*size = 4;
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -451,6 +451,7 @@ struct smu_dpm_context {
|
|||
struct smu_power_gate {
|
||||
bool uvd_gated;
|
||||
bool vce_gated;
|
||||
bool vcn_gated;
|
||||
};
|
||||
|
||||
struct smu_power_context {
|
||||
|
|
|
|||
|
|
@ -502,6 +502,8 @@ static int navi10_store_powerplay_table(struct smu_context *smu)
|
|||
|
||||
static int navi10_tables_init(struct smu_context *smu, struct smu_table *tables)
|
||||
{
|
||||
struct smu_table_context *smu_table = &smu->smu_table;
|
||||
|
||||
SMU_TABLE_INIT(tables, SMU_TABLE_PPTABLE, sizeof(PPTable_t),
|
||||
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
|
||||
SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t),
|
||||
|
|
@ -516,9 +518,35 @@ static int navi10_tables_init(struct smu_context *smu, struct smu_table *tables)
|
|||
sizeof(DpmActivityMonitorCoeffInt_t), PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM);
|
||||
|
||||
smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL);
|
||||
if (!smu_table->metrics_table)
|
||||
return -ENOMEM;
|
||||
smu_table->metrics_time = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int navi10_get_metrics_table(struct smu_context *smu,
|
||||
SmuMetrics_t *metrics_table)
|
||||
{
|
||||
struct smu_table_context *smu_table= &smu->smu_table;
|
||||
int ret = 0;
|
||||
|
||||
if (!smu_table->metrics_time || time_after(jiffies, smu_table->metrics_time + HZ / 1000)) {
|
||||
ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0,
|
||||
(void *)smu_table->metrics_table, false);
|
||||
if (ret) {
|
||||
pr_info("Failed to export SMU metrics table!\n");
|
||||
return ret;
|
||||
}
|
||||
smu_table->metrics_time = jiffies;
|
||||
}
|
||||
|
||||
memcpy(metrics_table, smu_table->metrics_table, sizeof(SmuMetrics_t));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int navi10_allocate_dpm_context(struct smu_context *smu)
|
||||
{
|
||||
struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
|
||||
|
|
@ -577,20 +605,27 @@ static int navi10_set_default_dpm_table(struct smu_context *smu)
|
|||
|
||||
static int navi10_dpm_set_uvd_enable(struct smu_context *smu, bool enable)
|
||||
{
|
||||
struct smu_power_context *smu_power = &smu->smu_power;
|
||||
struct smu_power_gate *power_gate = &smu_power->power_gate;
|
||||
int ret = 0;
|
||||
|
||||
if (enable) {
|
||||
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* vcn dpm on is a prerequisite for vcn power gate messages */
|
||||
if (smu_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
|
||||
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
power_gate->vcn_gated = false;
|
||||
} else {
|
||||
ret = smu_send_smc_msg(smu, SMU_MSG_PowerDownVcn);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (smu_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
|
||||
ret = smu_send_smc_msg(smu, SMU_MSG_PowerDownVcn);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
power_gate->vcn_gated = true;
|
||||
}
|
||||
|
||||
ret = smu_feature_set_enabled(smu, SMU_FEATURE_VCN_PG_BIT, enable);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -598,15 +633,10 @@ static int navi10_get_current_clk_freq_by_table(struct smu_context *smu,
|
|||
enum smu_clk_type clk_type,
|
||||
uint32_t *value)
|
||||
{
|
||||
static SmuMetrics_t metrics;
|
||||
int ret = 0, clk_id = 0;
|
||||
SmuMetrics_t metrics;
|
||||
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
|
||||
memset(&metrics, 0, sizeof(metrics));
|
||||
|
||||
ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, (void *)&metrics, false);
|
||||
ret = navi10_get_metrics_table(smu, &metrics);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -894,8 +924,9 @@ static int navi10_get_gpu_power(struct smu_context *smu, uint32_t *value)
|
|||
if (!value)
|
||||
return -EINVAL;
|
||||
|
||||
ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, (void *)&metrics,
|
||||
false);
|
||||
ret = navi10_get_metrics_table(smu, &metrics);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -914,10 +945,7 @@ static int navi10_get_current_activity_percent(struct smu_context *smu,
|
|||
if (!value)
|
||||
return -EINVAL;
|
||||
|
||||
msleep(1);
|
||||
|
||||
ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0,
|
||||
(void *)&metrics, false);
|
||||
ret = navi10_get_metrics_table(smu, &metrics);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -956,10 +984,9 @@ static int navi10_get_fan_speed_rpm(struct smu_context *smu,
|
|||
if (!speed)
|
||||
return -EINVAL;
|
||||
|
||||
memset(&metrics, 0, sizeof(metrics));
|
||||
|
||||
ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0,
|
||||
(void *)&metrics, false);
|
||||
ret = navi10_get_metrics_table(smu, &metrics);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -1307,7 +1334,7 @@ static int navi10_thermal_get_temperature(struct smu_context *smu,
|
|||
if (!value)
|
||||
return -EINVAL;
|
||||
|
||||
ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, (void *)&metrics, false);
|
||||
ret = navi10_get_metrics_table(smu, &metrics);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -1391,7 +1391,7 @@ smu_v11_0_smc_fan_control(struct smu_context *smu, bool start)
|
|||
{
|
||||
int ret = 0;
|
||||
|
||||
if (smu_feature_is_supported(smu, SMU_FEATURE_FAN_CONTROL_BIT))
|
||||
if (!smu_feature_is_supported(smu, SMU_FEATURE_FAN_CONTROL_BIT))
|
||||
return 0;
|
||||
|
||||
ret = smu_feature_set_enabled(smu, SMU_FEATURE_FAN_CONTROL_BIT, start);
|
||||
|
|
|
|||
|
|
@ -1770,7 +1770,9 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
|
|||
}
|
||||
|
||||
if (named_mode) {
|
||||
strncpy(mode->name, name, mode_end);
|
||||
if (mode_end + 1 > DRM_DISPLAY_MODE_LEN)
|
||||
return false;
|
||||
strscpy(mode->name, name, mode_end + 1);
|
||||
} else {
|
||||
ret = drm_mode_parse_cmdline_res_mode(name, mode_end,
|
||||
parse_extras,
|
||||
|
|
|
|||
|
|
@ -536,7 +536,8 @@ int intel_hdcp_auth_downstream(struct intel_connector *connector)
|
|||
|
||||
if (drm_hdcp_check_ksvs_revoked(dev, ksv_fifo, num_downstream)) {
|
||||
DRM_ERROR("Revoked Ksv(s) in ksv_fifo\n");
|
||||
return -EPERM;
|
||||
ret = -EPERM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -396,8 +396,8 @@ static void glk_dsi_program_esc_clock(struct drm_device *dev,
|
|||
else
|
||||
txesc2_div = 10;
|
||||
|
||||
I915_WRITE(MIPIO_TXESC_CLK_DIV1, txesc1_div & GLK_TX_ESC_CLK_DIV1_MASK);
|
||||
I915_WRITE(MIPIO_TXESC_CLK_DIV2, txesc2_div & GLK_TX_ESC_CLK_DIV2_MASK);
|
||||
I915_WRITE(MIPIO_TXESC_CLK_DIV1, (1 << (txesc1_div - 1)) & GLK_TX_ESC_CLK_DIV1_MASK);
|
||||
I915_WRITE(MIPIO_TXESC_CLK_DIV2, (1 << (txesc2_div - 1)) & GLK_TX_ESC_CLK_DIV2_MASK);
|
||||
}
|
||||
|
||||
/* Program BXT Mipi clocks and dividers */
|
||||
|
|
|
|||
|
|
@ -1628,6 +1628,7 @@ static int check_relocations(const struct drm_i915_gem_exec_object2 *entry)
|
|||
|
||||
static int eb_copy_relocations(const struct i915_execbuffer *eb)
|
||||
{
|
||||
struct drm_i915_gem_relocation_entry *relocs;
|
||||
const unsigned int count = eb->buffer_count;
|
||||
unsigned int i;
|
||||
int err;
|
||||
|
|
@ -1635,7 +1636,6 @@ static int eb_copy_relocations(const struct i915_execbuffer *eb)
|
|||
for (i = 0; i < count; i++) {
|
||||
const unsigned int nreloc = eb->exec[i].relocation_count;
|
||||
struct drm_i915_gem_relocation_entry __user *urelocs;
|
||||
struct drm_i915_gem_relocation_entry *relocs;
|
||||
unsigned long size;
|
||||
unsigned long copied;
|
||||
|
||||
|
|
@ -1663,14 +1663,8 @@ static int eb_copy_relocations(const struct i915_execbuffer *eb)
|
|||
|
||||
if (__copy_from_user((char *)relocs + copied,
|
||||
(char __user *)urelocs + copied,
|
||||
len)) {
|
||||
end_user:
|
||||
user_access_end();
|
||||
end:
|
||||
kvfree(relocs);
|
||||
err = -EFAULT;
|
||||
goto err;
|
||||
}
|
||||
len))
|
||||
goto end;
|
||||
|
||||
copied += len;
|
||||
} while (copied < size);
|
||||
|
|
@ -1699,10 +1693,14 @@ static int eb_copy_relocations(const struct i915_execbuffer *eb)
|
|||
|
||||
return 0;
|
||||
|
||||
end_user:
|
||||
user_access_end();
|
||||
end:
|
||||
kvfree(relocs);
|
||||
err = -EFAULT;
|
||||
err:
|
||||
while (i--) {
|
||||
struct drm_i915_gem_relocation_entry *relocs =
|
||||
u64_to_ptr(typeof(*relocs), eb->exec[i].relocs_ptr);
|
||||
relocs = u64_to_ptr(typeof(*relocs), eb->exec[i].relocs_ptr);
|
||||
if (eb->exec[i].relocation_count)
|
||||
kvfree(relocs);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -432,7 +432,7 @@ static int rockchip_dp_resume(struct device *dev)
|
|||
|
||||
static const struct dev_pm_ops rockchip_dp_pm_ops = {
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
.suspend = rockchip_dp_suspend,
|
||||
.suspend_late = rockchip_dp_suspend,
|
||||
.resume_early = rockchip_dp_resume,
|
||||
#endif
|
||||
};
|
||||
|
|
|
|||
|
|
@ -126,8 +126,12 @@ int tegra_output_probe(struct tegra_output *output)
|
|||
"nvidia,hpd-gpio", 0,
|
||||
GPIOD_IN,
|
||||
"HDMI hotplug detect");
|
||||
if (IS_ERR(output->hpd_gpio))
|
||||
return PTR_ERR(output->hpd_gpio);
|
||||
if (IS_ERR(output->hpd_gpio)) {
|
||||
if (PTR_ERR(output->hpd_gpio) != -ENOENT)
|
||||
return PTR_ERR(output->hpd_gpio);
|
||||
|
||||
output->hpd_gpio = NULL;
|
||||
}
|
||||
|
||||
if (output->hpd_gpio) {
|
||||
err = gpiod_to_irq(output->hpd_gpio);
|
||||
|
|
|
|||
|
|
@ -389,8 +389,10 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
|
|||
break;
|
||||
}
|
||||
|
||||
if (retries == RETRIES)
|
||||
if (retries == RETRIES) {
|
||||
kfree(reply);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*msg_len = reply_len;
|
||||
*msg = reply;
|
||||
|
|
|
|||
|
|
@ -23,12 +23,36 @@
|
|||
#define A4_2WHEEL_MOUSE_HACK_7 0x01
|
||||
#define A4_2WHEEL_MOUSE_HACK_B8 0x02
|
||||
|
||||
#define A4_WHEEL_ORIENTATION (HID_UP_GENDESK | 0x000000b8)
|
||||
|
||||
struct a4tech_sc {
|
||||
unsigned long quirks;
|
||||
unsigned int hw_wheel;
|
||||
__s32 delayed_value;
|
||||
};
|
||||
|
||||
static int a4_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||
struct hid_field *field, struct hid_usage *usage,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
struct a4tech_sc *a4 = hid_get_drvdata(hdev);
|
||||
|
||||
if (a4->quirks & A4_2WHEEL_MOUSE_HACK_B8 &&
|
||||
usage->hid == A4_WHEEL_ORIENTATION) {
|
||||
/*
|
||||
* We do not want to have this usage mapped to anything as it's
|
||||
* nonstandard and doesn't really behave like an HID report.
|
||||
* It's only selecting the orientation (vertical/horizontal) of
|
||||
* the previous mouse wheel report. The input_events will be
|
||||
* generated once both reports are recorded in a4_event().
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int a4_input_mapped(struct hid_device *hdev, struct hid_input *hi,
|
||||
struct hid_field *field, struct hid_usage *usage,
|
||||
unsigned long **bit, int *max)
|
||||
|
|
@ -52,8 +76,7 @@ static int a4_event(struct hid_device *hdev, struct hid_field *field,
|
|||
struct a4tech_sc *a4 = hid_get_drvdata(hdev);
|
||||
struct input_dev *input;
|
||||
|
||||
if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
|
||||
!usage->type)
|
||||
if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput)
|
||||
return 0;
|
||||
|
||||
input = field->hidinput->input;
|
||||
|
|
@ -64,7 +87,7 @@ static int a4_event(struct hid_device *hdev, struct hid_field *field,
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (usage->hid == 0x000100b8) {
|
||||
if (usage->hid == A4_WHEEL_ORIENTATION) {
|
||||
input_event(input, EV_REL, value ? REL_HWHEEL :
|
||||
REL_WHEEL, a4->delayed_value);
|
||||
input_event(input, EV_REL, value ? REL_HWHEEL_HI_RES :
|
||||
|
|
@ -131,6 +154,7 @@ MODULE_DEVICE_TABLE(hid, a4_devices);
|
|||
static struct hid_driver a4_driver = {
|
||||
.name = "a4tech",
|
||||
.id_table = a4_devices,
|
||||
.input_mapping = a4_input_mapping,
|
||||
.input_mapped = a4_input_mapped,
|
||||
.event = a4_event,
|
||||
.probe = a4_probe,
|
||||
|
|
|
|||
|
|
@ -123,9 +123,14 @@ static int holtek_kbd_input_event(struct input_dev *dev, unsigned int type,
|
|||
|
||||
/* Locate the boot interface, to receive the LED change events */
|
||||
struct usb_interface *boot_interface = usb_ifnum_to_if(usb_dev, 0);
|
||||
struct hid_device *boot_hid;
|
||||
struct hid_input *boot_hid_input;
|
||||
|
||||
struct hid_device *boot_hid = usb_get_intfdata(boot_interface);
|
||||
struct hid_input *boot_hid_input = list_first_entry(&boot_hid->inputs,
|
||||
if (unlikely(boot_interface == NULL))
|
||||
return -ENODEV;
|
||||
|
||||
boot_hid = usb_get_intfdata(boot_interface);
|
||||
boot_hid_input = list_first_entry(&boot_hid->inputs,
|
||||
struct hid_input, list);
|
||||
|
||||
return boot_hid_input->input->event(boot_hid_input->input, type, code,
|
||||
|
|
|
|||
|
|
@ -568,6 +568,7 @@
|
|||
#define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A 0x0b4a
|
||||
#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE 0x134a
|
||||
#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A 0x094a
|
||||
#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641 0x0641
|
||||
|
||||
#define USB_VENDOR_ID_HUION 0x256c
|
||||
#define USB_DEVICE_ID_HUION_TABLET 0x006e
|
||||
|
|
@ -768,7 +769,8 @@
|
|||
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER 0xc52f
|
||||
#define USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2 0xc532
|
||||
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2 0xc534
|
||||
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_GAMING 0xc539
|
||||
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED 0xc539
|
||||
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY 0xc53a
|
||||
#define USB_DEVICE_ID_SPACETRAVELLER 0xc623
|
||||
#define USB_DEVICE_ID_SPACENAVIGATOR 0xc626
|
||||
#define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704
|
||||
|
|
@ -989,6 +991,7 @@
|
|||
#define USB_DEVICE_ID_SAITEK_RAT7 0x0cd7
|
||||
#define USB_DEVICE_ID_SAITEK_RAT9 0x0cfa
|
||||
#define USB_DEVICE_ID_SAITEK_MMO7 0x0cd0
|
||||
#define USB_DEVICE_ID_SAITEK_X52 0x075c
|
||||
|
||||
#define USB_VENDOR_ID_SAMSUNG 0x0419
|
||||
#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001
|
||||
|
|
|
|||
|
|
@ -1125,7 +1125,7 @@ static int logi_dj_recv_query_hidpp_devices(struct dj_receiver_dev *djrcv_dev)
|
|||
HID_REQ_SET_REPORT);
|
||||
|
||||
kfree(hidpp_report);
|
||||
return retval;
|
||||
return (retval < 0) ? retval : 0;
|
||||
}
|
||||
|
||||
static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
|
||||
|
|
@ -1832,13 +1832,17 @@ static const struct hid_device_id logi_dj_receivers[] = {
|
|||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
|
||||
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2),
|
||||
.driver_data = recvr_type_hidpp},
|
||||
{ /* Logitech gaming receiver (0xc539) */
|
||||
{ /* Logitech lightspeed receiver (0xc539) */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
|
||||
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_GAMING),
|
||||
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED),
|
||||
.driver_data = recvr_type_gaming_hidpp},
|
||||
{ /* Logitech 27 MHz HID++ 1.0 receiver (0xc513) */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),
|
||||
.driver_data = recvr_type_27mhz},
|
||||
{ /* Logitech powerplay receiver (0xc53a) */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
|
||||
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY),
|
||||
.driver_data = recvr_type_gaming_hidpp},
|
||||
{ /* Logitech 27 MHz HID++ 1.0 receiver (0xc517) */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
|
||||
USB_DEVICE_ID_S510_RECEIVER_2),
|
||||
|
|
|
|||
|
|
@ -3749,15 +3749,45 @@ static const struct hid_device_id hidpp_devices[] = {
|
|||
|
||||
{ L27MHZ_DEVICE(HID_ANY_ID) },
|
||||
|
||||
{ /* Logitech G403 Gaming Mouse over USB */
|
||||
{ /* Logitech G203/Prodigy Gaming Mouse */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC084) },
|
||||
{ /* Logitech G302 Gaming Mouse */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC07F) },
|
||||
{ /* Logitech G303 Gaming Mouse */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC080) },
|
||||
{ /* Logitech G400 Gaming Mouse */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC07E) },
|
||||
{ /* Logitech G403 Wireless Gaming Mouse over USB */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC082) },
|
||||
{ /* Logitech G403 Gaming Mouse */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC083) },
|
||||
{ /* Logitech G403 Hero Gaming Mouse over USB */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC08F) },
|
||||
{ /* Logitech G502 Proteus Core Gaming Mouse */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC07D) },
|
||||
{ /* Logitech G502 Proteus Spectrum Gaming Mouse over USB */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC332) },
|
||||
{ /* Logitech G502 Hero Gaming Mouse over USB */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC08B) },
|
||||
{ /* Logitech G700 Gaming Mouse over USB */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC06B) },
|
||||
{ /* Logitech G700s Gaming Mouse over USB */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC07C) },
|
||||
{ /* Logitech G703 Gaming Mouse over USB */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC087) },
|
||||
{ /* Logitech G703 Hero Gaming Mouse over USB */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC090) },
|
||||
{ /* Logitech G900 Gaming Mouse over USB */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC081) },
|
||||
{ /* Logitech G903 Gaming Mouse over USB */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC086) },
|
||||
{ /* Logitech G903 Hero Gaming Mouse over USB */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC091) },
|
||||
{ /* Logitech G920 Wheel over USB */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL),
|
||||
.driver_data = HIDPP_QUIRK_CLASS_G920 | HIDPP_QUIRK_FORCE_OUTPUT_REPORTS},
|
||||
{ /* Logitech G Pro Gaming Mouse over USB */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC088) },
|
||||
|
||||
{ /* MX5000 keyboard over Bluetooth */
|
||||
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb305),
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user