Merge remote-tracking branch 'torvalds/master' into perf-tools-next
To pick up changes for other tools/ libraries used by perf and for header synchronization with the kernel sources originals. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>pull/1285/head
commit
4d4eb38795
|
|
@ -7,5 +7,5 @@ check-private-items = true
|
|||
disallowed-macros = [
|
||||
# The `clippy::dbg_macro` lint only works with `std::dbg!`, thus we simulate
|
||||
# it here, see: https://github.com/rust-lang/rust-clippy/issues/11303.
|
||||
{ path = "kernel::dbg", reason = "the `dbg!` macro is intended as a debugging tool" },
|
||||
{ path = "kernel::dbg", reason = "the `dbg!` macro is intended as a debugging tool", allow-invalid = true },
|
||||
]
|
||||
|
|
|
|||
5
.mailmap
5
.mailmap
|
|
@ -102,6 +102,7 @@ Ard Biesheuvel <ardb@kernel.org> <ard.biesheuvel@linaro.org>
|
|||
Arnaud Patard <arnaud.patard@rtp-net.org>
|
||||
Arnd Bergmann <arnd@arndb.de>
|
||||
Arun Kumar Neelakantam <quic_aneela@quicinc.com> <aneela@codeaurora.org>
|
||||
Asahi Lina <lina+kernel@asahilina.net> <lina@asahilina.net>
|
||||
Ashok Raj Nagarajan <quic_arnagara@quicinc.com> <arnagara@codeaurora.org>
|
||||
Ashwin Chaugule <quic_ashwinc@quicinc.com> <ashwinc@codeaurora.org>
|
||||
Asutosh Das <quic_asutoshd@quicinc.com> <asutoshd@codeaurora.org>
|
||||
|
|
@ -447,6 +448,8 @@ Luca Ceresoli <luca.ceresoli@bootlin.com> <luca@lucaceresoli.net>
|
|||
Luca Weiss <luca@lucaweiss.eu> <luca@z3ntu.xyz>
|
||||
Lukasz Luba <lukasz.luba@arm.com> <l.luba@partner.samsung.com>
|
||||
Luo Jie <quic_luoj@quicinc.com> <luoj@codeaurora.org>
|
||||
Lance Yang <lance.yang@linux.dev> <ioworker0@gmail.com>
|
||||
Lance Yang <lance.yang@linux.dev> <mingzhe.yang@ly.com>
|
||||
Maciej W. Rozycki <macro@mips.com> <macro@imgtec.com>
|
||||
Maciej W. Rozycki <macro@orcam.me.uk> <macro@linux-mips.org>
|
||||
Maharaja Kennadyrajan <quic_mkenna@quicinc.com> <mkenna@codeaurora.org>
|
||||
|
|
@ -483,6 +486,7 @@ Matthias Fuchs <socketcan@esd.eu> <matthias.fuchs@esd.eu>
|
|||
Matthieu Baerts <matttbe@kernel.org> <matthieu.baerts@tessares.net>
|
||||
Matthieu CASTET <castet.matthieu@free.fr>
|
||||
Matti Vaittinen <mazziesaccount@gmail.com> <matti.vaittinen@fi.rohmeurope.com>
|
||||
Mattijs Korpershoek <mkorpershoek@kernel.org> <mkorpershoek@baylibre.com>
|
||||
Matt Ranostay <matt@ranostay.sg> <matt.ranostay@konsulko.com>
|
||||
Matt Ranostay <matt@ranostay.sg> <matt@ranostay.consulting>
|
||||
Matt Ranostay <matt@ranostay.sg> Matthew Ranostay <mranostay@embeddedalley.com>
|
||||
|
|
@ -749,6 +753,7 @@ Tvrtko Ursulin <tursulin@ursulin.net> <tvrtko@ursulin.net>
|
|||
Tycho Andersen <tycho@tycho.pizza> <tycho@tycho.ws>
|
||||
Tzung-Bi Shih <tzungbi@kernel.org> <tzungbi@google.com>
|
||||
Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de>
|
||||
Uwe Kleine-König <u.kleine-koenig@baylibre.com> <ukleinek@baylibre.com>
|
||||
Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
|
||||
Uwe Kleine-König <ukleinek@strlen.de>
|
||||
Uwe Kleine-König <ukl@pengutronix.de>
|
||||
|
|
|
|||
|
|
@ -511,6 +511,7 @@ Description: information about CPUs heterogeneity.
|
|||
|
||||
What: /sys/devices/system/cpu/vulnerabilities
|
||||
/sys/devices/system/cpu/vulnerabilities/gather_data_sampling
|
||||
/sys/devices/system/cpu/vulnerabilities/indirect_target_selection
|
||||
/sys/devices/system/cpu/vulnerabilities/itlb_multihit
|
||||
/sys/devices/system/cpu/vulnerabilities/l1tf
|
||||
/sys/devices/system/cpu/vulnerabilities/mds
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
What: /sys/bus/hid/drivers/hid-appletb-kbd/<dev>/mode
|
||||
Date: September, 2023
|
||||
KernelVersion: 6.5
|
||||
Date: March, 2025
|
||||
KernelVersion: 6.15
|
||||
Contact: linux-input@vger.kernel.org
|
||||
Description:
|
||||
The set of keys displayed on the Touch Bar.
|
||||
|
|
|
|||
|
|
@ -23,3 +23,4 @@ are configurable at compile, boot or run time.
|
|||
gather_data_sampling
|
||||
reg-file-data-sampling
|
||||
rsb
|
||||
indirect-target-selection
|
||||
|
|
|
|||
|
|
@ -0,0 +1,168 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
Indirect Target Selection (ITS)
|
||||
===============================
|
||||
|
||||
ITS is a vulnerability in some Intel CPUs that support Enhanced IBRS and were
|
||||
released before Alder Lake. ITS may allow an attacker to control the prediction
|
||||
of indirect branches and RETs located in the lower half of a cacheline.
|
||||
|
||||
ITS is assigned CVE-2024-28956 with a CVSS score of 4.7 (Medium).
|
||||
|
||||
Scope of Impact
|
||||
---------------
|
||||
- **eIBRS Guest/Host Isolation**: Indirect branches in KVM/kernel may still be
|
||||
predicted with unintended target corresponding to a branch in the guest.
|
||||
|
||||
- **Intra-Mode BTI**: In-kernel training such as through cBPF or other native
|
||||
gadgets.
|
||||
|
||||
- **Indirect Branch Prediction Barrier (IBPB)**: After an IBPB, indirect
|
||||
branches may still be predicted with targets corresponding to direct branches
|
||||
executed prior to the IBPB. This is fixed by the IPU 2025.1 microcode, which
|
||||
should be available via distro updates. Alternatively microcode can be
|
||||
obtained from Intel's github repository [#f1]_.
|
||||
|
||||
Affected CPUs
|
||||
-------------
|
||||
Below is the list of ITS affected CPUs [#f2]_ [#f3]_:
|
||||
|
||||
======================== ============ ==================== ===============
|
||||
Common name Family_Model eIBRS Intra-mode BTI
|
||||
Guest/Host Isolation
|
||||
======================== ============ ==================== ===============
|
||||
SKYLAKE_X (step >= 6) 06_55H Affected Affected
|
||||
ICELAKE_X 06_6AH Not affected Affected
|
||||
ICELAKE_D 06_6CH Not affected Affected
|
||||
ICELAKE_L 06_7EH Not affected Affected
|
||||
TIGERLAKE_L 06_8CH Not affected Affected
|
||||
TIGERLAKE 06_8DH Not affected Affected
|
||||
KABYLAKE_L (step >= 12) 06_8EH Affected Affected
|
||||
KABYLAKE (step >= 13) 06_9EH Affected Affected
|
||||
COMETLAKE 06_A5H Affected Affected
|
||||
COMETLAKE_L 06_A6H Affected Affected
|
||||
ROCKETLAKE 06_A7H Not affected Affected
|
||||
======================== ============ ==================== ===============
|
||||
|
||||
- All affected CPUs enumerate Enhanced IBRS feature.
|
||||
- IBPB isolation is affected on all ITS affected CPUs, and need a microcode
|
||||
update for mitigation.
|
||||
- None of the affected CPUs enumerate BHI_CTRL which was introduced in Golden
|
||||
Cove (Alder Lake and Sapphire Rapids). This can help guests to determine the
|
||||
host's affected status.
|
||||
- Intel Atom CPUs are not affected by ITS.
|
||||
|
||||
Mitigation
|
||||
----------
|
||||
As only the indirect branches and RETs that have their last byte of instruction
|
||||
in the lower half of the cacheline are vulnerable to ITS, the basic idea behind
|
||||
the mitigation is to not allow indirect branches in the lower half.
|
||||
|
||||
This is achieved by relying on existing retpoline support in the kernel, and in
|
||||
compilers. ITS-vulnerable retpoline sites are runtime patched to point to newly
|
||||
added ITS-safe thunks. These safe thunks consists of indirect branch in the
|
||||
second half of the cacheline. Not all retpoline sites are patched to thunks, if
|
||||
a retpoline site is evaluated to be ITS-safe, it is replaced with an inline
|
||||
indirect branch.
|
||||
|
||||
Dynamic thunks
|
||||
~~~~~~~~~~~~~~
|
||||
From a dynamically allocated pool of safe-thunks, each vulnerable site is
|
||||
replaced with a new thunk, such that they get a unique address. This could
|
||||
improve the branch prediction accuracy. Also, it is a defense-in-depth measure
|
||||
against aliasing.
|
||||
|
||||
Note, for simplicity, indirect branches in eBPF programs are always replaced
|
||||
with a jump to a static thunk in __x86_indirect_its_thunk_array. If required,
|
||||
in future this can be changed to use dynamic thunks.
|
||||
|
||||
All vulnerable RETs are replaced with a static thunk, they do not use dynamic
|
||||
thunks. This is because RETs get their prediction from RSB mostly that does not
|
||||
depend on source address. RETs that underflow RSB may benefit from dynamic
|
||||
thunks. But, RETs significantly outnumber indirect branches, and any benefit
|
||||
from a unique source address could be outweighed by the increased icache
|
||||
footprint and iTLB pressure.
|
||||
|
||||
Retpoline
|
||||
~~~~~~~~~
|
||||
Retpoline sequence also mitigates ITS-unsafe indirect branches. For this
|
||||
reason, when retpoline is enabled, ITS mitigation only relocates the RETs to
|
||||
safe thunks. Unless user requested the RSB-stuffing mitigation.
|
||||
|
||||
RSB Stuffing
|
||||
~~~~~~~~~~~~
|
||||
RSB-stuffing via Call Depth Tracking is a mitigation for Retbleed RSB-underflow
|
||||
attacks. And it also mitigates RETs that are vulnerable to ITS.
|
||||
|
||||
Mitigation in guests
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
All guests deploy ITS mitigation by default, irrespective of eIBRS enumeration
|
||||
and Family/Model of the guest. This is because eIBRS feature could be hidden
|
||||
from a guest. One exception to this is when a guest enumerates BHI_DIS_S, which
|
||||
indicates that the guest is running on an unaffected host.
|
||||
|
||||
To prevent guests from unnecessarily deploying the mitigation on unaffected
|
||||
platforms, Intel has defined ITS_NO bit(62) in MSR IA32_ARCH_CAPABILITIES. When
|
||||
a guest sees this bit set, it should not enumerate the ITS bug. Note, this bit
|
||||
is not set by any hardware, but is **intended for VMMs to synthesize** it for
|
||||
guests as per the host's affected status.
|
||||
|
||||
Mitigation options
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
The ITS mitigation can be controlled using the "indirect_target_selection"
|
||||
kernel parameter. The available options are:
|
||||
|
||||
======== ===================================================================
|
||||
on (default) Deploy the "Aligned branch/return thunks" mitigation.
|
||||
If spectre_v2 mitigation enables retpoline, aligned-thunks are only
|
||||
deployed for the affected RET instructions. Retpoline mitigates
|
||||
indirect branches.
|
||||
|
||||
off Disable ITS mitigation.
|
||||
|
||||
vmexit Equivalent to "=on" if the CPU is affected by guest/host isolation
|
||||
part of ITS. Otherwise, mitigation is not deployed. This option is
|
||||
useful when host userspace is not in the threat model, and only
|
||||
attacks from guest to host are considered.
|
||||
|
||||
stuff Deploy RSB-fill mitigation when retpoline is also deployed.
|
||||
Otherwise, deploy the default mitigation. When retpoline mitigation
|
||||
is enabled, RSB-stuffing via Call-Depth-Tracking also mitigates
|
||||
ITS.
|
||||
|
||||
force Force the ITS bug and deploy the default mitigation.
|
||||
======== ===================================================================
|
||||
|
||||
Sysfs reporting
|
||||
---------------
|
||||
|
||||
The sysfs file showing ITS mitigation status is:
|
||||
|
||||
/sys/devices/system/cpu/vulnerabilities/indirect_target_selection
|
||||
|
||||
Note, microcode mitigation status is not reported in this file.
|
||||
|
||||
The possible values in this file are:
|
||||
|
||||
.. list-table::
|
||||
|
||||
* - Not affected
|
||||
- The processor is not vulnerable.
|
||||
* - Vulnerable
|
||||
- System is vulnerable and no mitigation has been applied.
|
||||
* - Vulnerable, KVM: Not affected
|
||||
- System is vulnerable to intra-mode BTI, but not affected by eIBRS
|
||||
guest/host isolation.
|
||||
* - Mitigation: Aligned branch/return thunks
|
||||
- The mitigation is enabled, affected indirect branches and RETs are
|
||||
relocated to safe thunks.
|
||||
* - Mitigation: Retpolines, Stuffing RSB
|
||||
- The mitigation is enabled using retpoline and RSB stuffing.
|
||||
|
||||
References
|
||||
----------
|
||||
.. [#f1] Microcode repository - https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files
|
||||
|
||||
.. [#f2] Affected Processors list - https://www.intel.com/content/www/us/en/developer/topic-technology/software-security-guidance/processors-affected-consolidated-product-cpu-model.html
|
||||
|
||||
.. [#f3] Affected Processors list (machine readable) - https://github.com/intel/Intel-affected-processor-list
|
||||
|
|
@ -2202,6 +2202,23 @@
|
|||
different crypto accelerators. This option can be used
|
||||
to achieve best performance for particular HW.
|
||||
|
||||
indirect_target_selection= [X86,Intel] Mitigation control for Indirect
|
||||
Target Selection(ITS) bug in Intel CPUs. Updated
|
||||
microcode is also required for a fix in IBPB.
|
||||
|
||||
on: Enable mitigation (default).
|
||||
off: Disable mitigation.
|
||||
force: Force the ITS bug and deploy default
|
||||
mitigation.
|
||||
vmexit: Only deploy mitigation if CPU is affected by
|
||||
guest/host isolation part of ITS.
|
||||
stuff: Deploy RSB-fill mitigation when retpoline is
|
||||
also deployed. Otherwise, deploy the default
|
||||
mitigation.
|
||||
|
||||
For details see:
|
||||
Documentation/admin-guide/hw-vuln/indirect-target-selection.rst
|
||||
|
||||
init= [KNL]
|
||||
Format: <full_path>
|
||||
Run specified binary instead of /sbin/init as init
|
||||
|
|
@ -3693,6 +3710,7 @@
|
|||
expose users to several CPU vulnerabilities.
|
||||
Equivalent to: if nokaslr then kpti=0 [ARM64]
|
||||
gather_data_sampling=off [X86]
|
||||
indirect_target_selection=off [X86]
|
||||
kvm.nx_huge_pages=off [X86]
|
||||
l1tf=off [X86]
|
||||
mds=off [X86]
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
|||
title: Mediatek's Keypad Controller
|
||||
|
||||
maintainers:
|
||||
- Mattijs Korpershoek <mkorpershoek@baylibre.com>
|
||||
- Mattijs Korpershoek <mkorpershoek@kernel.org>
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/input/matrix-keymap.yaml#
|
||||
|
|
|
|||
|
|
@ -74,19 +74,17 @@ properties:
|
|||
- rev-rmii
|
||||
- moca
|
||||
|
||||
# RX and TX delays are added by the MAC when required
|
||||
# RX and TX delays are provided by the PCB. See below
|
||||
- rgmii
|
||||
|
||||
# RGMII with internal RX and TX delays provided by the PHY,
|
||||
# the MAC should not add the RX or TX delays in this case
|
||||
# RX and TX delays are not provided by the PCB. This is the most
|
||||
# frequent case. See below
|
||||
- rgmii-id
|
||||
|
||||
# RGMII with internal RX delay provided by the PHY, the MAC
|
||||
# should not add an RX delay in this case
|
||||
# TX delay is provided by the PCB. See below
|
||||
- rgmii-rxid
|
||||
|
||||
# RGMII with internal TX delay provided by the PHY, the MAC
|
||||
# should not add an TX delay in this case
|
||||
# RX delay is provided by the PCB. See below
|
||||
- rgmii-txid
|
||||
- rtbi
|
||||
- smii
|
||||
|
|
@ -286,4 +284,89 @@ allOf:
|
|||
|
||||
additionalProperties: true
|
||||
|
||||
# Informative
|
||||
# ===========
|
||||
#
|
||||
# 'phy-modes' & 'phy-connection-type' properties 'rgmii', 'rgmii-id',
|
||||
# 'rgmii-rxid', and 'rgmii-txid' are frequently used wrongly by
|
||||
# developers. This informative section clarifies their usage.
|
||||
#
|
||||
# The RGMII specification requires a 2ns delay between the data and
|
||||
# clock signals on the RGMII bus. How this delay is implemented is not
|
||||
# specified.
|
||||
#
|
||||
# One option is to make the clock traces on the PCB longer than the
|
||||
# data traces. A sufficiently difference in length can provide the 2ns
|
||||
# delay. If both the RX and TX delays are implemented in this manner,
|
||||
# 'rgmii' should be used, so indicating the PCB adds the delays.
|
||||
#
|
||||
# If the PCB does not add these delays via extra long traces,
|
||||
# 'rgmii-id' should be used. Here, 'id' refers to 'internal delay',
|
||||
# where either the MAC or PHY adds the delay.
|
||||
#
|
||||
# If only one of the two delays are implemented via extra long clock
|
||||
# lines, either 'rgmii-rxid' or 'rgmii-txid' should be used,
|
||||
# indicating the MAC or PHY should implement one of the delays
|
||||
# internally, while the PCB implements the other delay.
|
||||
#
|
||||
# Device Tree describes hardware, and in this case, it describes the
|
||||
# PCB between the MAC and the PHY, if the PCB implements delays or
|
||||
# not.
|
||||
#
|
||||
# In practice, very few PCBs make use of extra long clock lines. Hence
|
||||
# any RGMII phy mode other than 'rgmii-id' is probably wrong, and is
|
||||
# unlikely to be accepted during review without details provided in
|
||||
# the commit description and comments in the .dts file.
|
||||
#
|
||||
# When the PCB does not implement the delays, the MAC or PHY must. As
|
||||
# such, this is software configuration, and so not described in Device
|
||||
# Tree.
|
||||
#
|
||||
# The following describes how Linux implements the configuration of
|
||||
# the MAC and PHY to add these delays when the PCB does not. As stated
|
||||
# above, developers often get this wrong, and the aim of this section
|
||||
# is reduce the frequency of these errors by Linux developers. Other
|
||||
# users of the Device Tree may implement it differently, and still be
|
||||
# consistent with both the normative and informative description
|
||||
# above.
|
||||
#
|
||||
# By default in Linux, when using phylib/phylink, the MAC is expected
|
||||
# to read the 'phy-mode' from Device Tree, not implement any delays,
|
||||
# and pass the value to the PHY. The PHY will then implement delays as
|
||||
# specified by the 'phy-mode'. The PHY should always be reconfigured
|
||||
# to implement the needed delays, replacing any setting performed by
|
||||
# strapping or the bootloader, etc.
|
||||
#
|
||||
# Experience to date is that all PHYs which implement RGMII also
|
||||
# implement the ability to add or not add the needed delays. Hence
|
||||
# this default is expected to work in all cases. Ignoring this default
|
||||
# is likely to be questioned by Reviews, and require a strong argument
|
||||
# to be accepted.
|
||||
#
|
||||
# There are a small number of cases where the MAC has hard coded
|
||||
# delays which cannot be disabled. The 'phy-mode' only describes the
|
||||
# PCB. The inability to disable the delays in the MAC does not change
|
||||
# the meaning of 'phy-mode'. It does however mean that a 'phy-mode' of
|
||||
# 'rgmii' is now invalid, it cannot be supported, since both the PCB
|
||||
# and the MAC and PHY adding delays cannot result in a functional
|
||||
# link. Thus the MAC should report a fatal error for any modes which
|
||||
# cannot be supported. When the MAC implements the delay, it must
|
||||
# ensure that the PHY does not also implement the same delay. So it
|
||||
# must modify the phy-mode it passes to the PHY, removing the delay it
|
||||
# has added. Failure to remove the delay will result in a
|
||||
# non-functioning link.
|
||||
#
|
||||
# Sometimes there is a need to fine tune the delays. Often the MAC or
|
||||
# PHY can perform this fine tuning. In the MAC node, the Device Tree
|
||||
# properties 'rx-internal-delay-ps' and 'tx-internal-delay-ps' should
|
||||
# be used to indicate fine tuning performed by the MAC. The values
|
||||
# expected here are small. A value of 2000ps, i.e 2ns, and a phy-mode
|
||||
# of 'rgmii' will not be accepted by Reviewers.
|
||||
#
|
||||
# If the PHY is to perform fine tuning, the properties
|
||||
# 'rx-internal-delay-ps' and 'tx-internal-delay-ps' in the PHY node
|
||||
# should be used. When the PHY is implementing delays, e.g. 'rgmii-id'
|
||||
# these properties should have a value near to 2000ps. If the PCB is
|
||||
# implementing delays, e.g. 'rgmii', a small value can be used to fine
|
||||
# tune the delay added by the PCB.
|
||||
...
|
||||
|
|
|
|||
|
|
@ -46,6 +46,21 @@ The kernel embeds the building user and host names in
|
|||
`KBUILD_BUILD_USER and KBUILD_BUILD_HOST`_ variables. If you are
|
||||
building from a git commit, you could use its committer address.
|
||||
|
||||
Absolute filenames
|
||||
------------------
|
||||
|
||||
When the kernel is built out-of-tree, debug information may include
|
||||
absolute filenames for the source files. This must be overridden by
|
||||
including the ``-fdebug-prefix-map`` option in the `KCFLAGS`_ variable.
|
||||
|
||||
Depending on the compiler used, the ``__FILE__`` macro may also expand
|
||||
to an absolute filename in an out-of-tree build. Kbuild automatically
|
||||
uses the ``-fmacro-prefix-map`` option to prevent this, if it is
|
||||
supported.
|
||||
|
||||
The Reproducible Builds web site has more information about these
|
||||
`prefix-map options`_.
|
||||
|
||||
Generated files in source packages
|
||||
----------------------------------
|
||||
|
||||
|
|
@ -116,5 +131,7 @@ See ``scripts/setlocalversion`` for details.
|
|||
|
||||
.. _KBUILD_BUILD_TIMESTAMP: kbuild.html#kbuild-build-timestamp
|
||||
.. _KBUILD_BUILD_USER and KBUILD_BUILD_HOST: kbuild.html#kbuild-build-user-kbuild-build-host
|
||||
.. _KCFLAGS: kbuild.html#kcflags
|
||||
.. _prefix-map options: https://reproducible-builds.org/docs/build-path/
|
||||
.. _Reproducible Builds project: https://reproducible-builds.org/
|
||||
.. _SOURCE_DATE_EPOCH: https://reproducible-builds.org/docs/source-date-epoch/
|
||||
|
|
|
|||
|
|
@ -2017,7 +2017,8 @@ attribute-sets:
|
|||
attributes:
|
||||
-
|
||||
name: act
|
||||
type: nest
|
||||
type: indexed-array
|
||||
sub-type: nest
|
||||
nested-attributes: tc-act-attrs
|
||||
-
|
||||
name: police
|
||||
|
|
@ -2250,7 +2251,8 @@ attribute-sets:
|
|||
attributes:
|
||||
-
|
||||
name: act
|
||||
type: nest
|
||||
type: indexed-array
|
||||
sub-type: nest
|
||||
nested-attributes: tc-act-attrs
|
||||
-
|
||||
name: police
|
||||
|
|
@ -2745,7 +2747,7 @@ attribute-sets:
|
|||
type: u16
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: key-l2-tpv3-sid
|
||||
name: key-l2tpv3-sid
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
|
|
@ -3504,7 +3506,7 @@ attribute-sets:
|
|||
name: rate64
|
||||
type: u64
|
||||
-
|
||||
name: prate4
|
||||
name: prate64
|
||||
type: u64
|
||||
-
|
||||
name: burst
|
||||
|
|
|
|||
|
|
@ -811,11 +811,9 @@ Documentation/devicetree/bindings/ptp/timestamper.txt for more details.
|
|||
3.2.4 Other caveats for MAC drivers
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Stacked PHCs, especially DSA (but not only) - since that doesn't require any
|
||||
modification to MAC drivers, so it is more difficult to ensure correctness of
|
||||
all possible code paths - is that they uncover bugs which were impossible to
|
||||
trigger before the existence of stacked PTP clocks. One example has to do with
|
||||
this line of code, already presented earlier::
|
||||
The use of stacked PHCs may uncover MAC driver bugs which were impossible to
|
||||
trigger without them. One example has to do with this line of code, already
|
||||
presented earlier::
|
||||
|
||||
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
|
||||
|
||||
|
|
|
|||
96
MAINTAINERS
96
MAINTAINERS
|
|
@ -8727,6 +8727,7 @@ M: Chao Yu <chao@kernel.org>
|
|||
R: Yue Hu <zbestahu@gmail.com>
|
||||
R: Jeffle Xu <jefflexu@linux.alibaba.com>
|
||||
R: Sandeep Dhavale <dhavale@google.com>
|
||||
R: Hongbo Li <lihongbo22@huawei.com>
|
||||
L: linux-erofs@lists.ozlabs.org
|
||||
S: Maintained
|
||||
W: https://erofs.docs.kernel.org
|
||||
|
|
@ -10146,6 +10147,13 @@ F: drivers/gpio/gpio-regmap.c
|
|||
F: include/linux/gpio/regmap.h
|
||||
K: (devm_)?gpio_regmap_(un)?register
|
||||
|
||||
GPIO SLOPPY LOGIC ANALYZER
|
||||
M: Wolfram Sang <wsa+renesas@sang-engineering.com>
|
||||
S: Supported
|
||||
F: Documentation/dev-tools/gpio-sloppy-logic-analyzer.rst
|
||||
F: drivers/gpio/gpio-sloppy-logic-analyzer.c
|
||||
F: tools/gpio/gpio-sloppy-logic-analyzer.sh
|
||||
|
||||
GPIO SUBSYSTEM
|
||||
M: Linus Walleij <linus.walleij@linaro.org>
|
||||
M: Bartosz Golaszewski <brgl@bgdev.pl>
|
||||
|
|
@ -11237,7 +11245,6 @@ S: Maintained
|
|||
F: drivers/i2c/busses/i2c-cht-wc.c
|
||||
|
||||
I2C/SMBUS ISMT DRIVER
|
||||
M: Seth Heasley <seth.heasley@intel.com>
|
||||
M: Neil Horman <nhorman@tuxdriver.com>
|
||||
L: linux-i2c@vger.kernel.org
|
||||
F: Documentation/i2c/busses/i2c-ismt.rst
|
||||
|
|
@ -15073,7 +15080,7 @@ F: Documentation/devicetree/bindings/media/mediatek-jpeg-*.yaml
|
|||
F: drivers/media/platform/mediatek/jpeg/
|
||||
|
||||
MEDIATEK KEYPAD DRIVER
|
||||
M: Mattijs Korpershoek <mkorpershoek@baylibre.com>
|
||||
M: Mattijs Korpershoek <mkorpershoek@kernel.org>
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml
|
||||
F: drivers/input/keyboard/mt6779-keypad.c
|
||||
|
|
@ -15496,24 +15503,45 @@ F: Documentation/mm/
|
|||
F: include/linux/gfp.h
|
||||
F: include/linux/gfp_types.h
|
||||
F: include/linux/memfd.h
|
||||
F: include/linux/memory.h
|
||||
F: include/linux/memory_hotplug.h
|
||||
F: include/linux/memory-tiers.h
|
||||
F: include/linux/mempolicy.h
|
||||
F: include/linux/mempool.h
|
||||
F: include/linux/memremap.h
|
||||
F: include/linux/mm.h
|
||||
F: include/linux/mm_*.h
|
||||
F: include/linux/mmzone.h
|
||||
F: include/linux/mmu_notifier.h
|
||||
F: include/linux/pagewalk.h
|
||||
F: include/linux/rmap.h
|
||||
F: include/trace/events/ksm.h
|
||||
F: mm/
|
||||
F: tools/mm/
|
||||
F: tools/testing/selftests/mm/
|
||||
N: include/linux/page[-_]*
|
||||
|
||||
MEMORY MANAGEMENT - CORE
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: David Hildenbrand <david@redhat.com>
|
||||
R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
R: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
R: Vlastimil Babka <vbabka@suse.cz>
|
||||
R: Mike Rapoport <rppt@kernel.org>
|
||||
R: Suren Baghdasaryan <surenb@google.com>
|
||||
R: Michal Hocko <mhocko@suse.com>
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
W: http://www.linux-mm.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
|
||||
F: include/linux/memory.h
|
||||
F: include/linux/mm.h
|
||||
F: include/linux/mm_*.h
|
||||
F: include/linux/mmdebug.h
|
||||
F: include/linux/pagewalk.h
|
||||
F: mm/Kconfig
|
||||
F: mm/debug.c
|
||||
F: mm/init-mm.c
|
||||
F: mm/memory.c
|
||||
F: mm/pagewalk.c
|
||||
F: mm/util.c
|
||||
|
||||
MEMORY MANAGEMENT - EXECMEM
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: Mike Rapoport <rppt@kernel.org>
|
||||
|
|
@ -15522,6 +15550,18 @@ S: Maintained
|
|||
F: include/linux/execmem.h
|
||||
F: mm/execmem.c
|
||||
|
||||
MEMORY MANAGEMENT - GUP (GET USER PAGES)
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: David Hildenbrand <david@redhat.com>
|
||||
R: Jason Gunthorpe <jgg@nvidia.com>
|
||||
R: John Hubbard <jhubbard@nvidia.com>
|
||||
R: Peter Xu <peterx@redhat.com>
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
W: http://www.linux-mm.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
|
||||
F: mm/gup.c
|
||||
|
||||
MEMORY MANAGEMENT - NUMA MEMBLOCKS AND NUMA EMULATION
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: Mike Rapoport <rppt@kernel.org>
|
||||
|
|
@ -15547,6 +15587,19 @@ F: mm/page_alloc.c
|
|||
F: include/linux/gfp.h
|
||||
F: include/linux/compaction.h
|
||||
|
||||
MEMORY MANAGEMENT - RMAP (REVERSE MAPPING)
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: David Hildenbrand <david@redhat.com>
|
||||
M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
R: Rik van Riel <riel@surriel.com>
|
||||
R: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
R: Vlastimil Babka <vbabka@suse.cz>
|
||||
R: Harry Yoo <harry.yoo@oracle.com>
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
F: include/linux/rmap.h
|
||||
F: mm/rmap.c
|
||||
|
||||
MEMORY MANAGEMENT - SECRETMEM
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: Mike Rapoport <rppt@kernel.org>
|
||||
|
|
@ -15555,6 +15608,30 @@ S: Maintained
|
|||
F: include/linux/secretmem.h
|
||||
F: mm/secretmem.c
|
||||
|
||||
MEMORY MANAGEMENT - THP (TRANSPARENT HUGE PAGE)
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: David Hildenbrand <david@redhat.com>
|
||||
R: Zi Yan <ziy@nvidia.com>
|
||||
R: Baolin Wang <baolin.wang@linux.alibaba.com>
|
||||
R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
R: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
R: Nico Pache <npache@redhat.com>
|
||||
R: Ryan Roberts <ryan.roberts@arm.com>
|
||||
R: Dev Jain <dev.jain@arm.com>
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
W: http://www.linux-mm.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
|
||||
F: Documentation/admin-guide/mm/transhuge.rst
|
||||
F: include/linux/huge_mm.h
|
||||
F: include/linux/khugepaged.h
|
||||
F: include/trace/events/huge_memory.h
|
||||
F: mm/huge_memory.c
|
||||
F: mm/khugepaged.c
|
||||
F: tools/testing/selftests/mm/khugepaged.c
|
||||
F: tools/testing/selftests/mm/split_huge_page_test.c
|
||||
F: tools/testing/selftests/mm/transhuge-stress.c
|
||||
|
||||
MEMORY MANAGEMENT - USERFAULTFD
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
R: Peter Xu <peterx@redhat.com>
|
||||
|
|
@ -18375,7 +18452,7 @@ F: include/uapi/linux/ppdev.h
|
|||
PARAVIRT_OPS INTERFACE
|
||||
M: Juergen Gross <jgross@suse.com>
|
||||
R: Ajay Kaher <ajay.kaher@broadcom.com>
|
||||
R: Alexey Makhalov <alexey.amakhalov@broadcom.com>
|
||||
R: Alexey Makhalov <alexey.makhalov@broadcom.com>
|
||||
R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
|
||||
L: virtualization@lists.linux.dev
|
||||
L: x86@kernel.org
|
||||
|
|
@ -22859,7 +22936,6 @@ F: drivers/accessibility/speakup/
|
|||
|
||||
SPEAR PLATFORM/CLOCK/PINCTRL SUPPORT
|
||||
M: Viresh Kumar <vireshk@kernel.org>
|
||||
M: Shiraz Hashim <shiraz.linux.kernel@gmail.com>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
L: soc@lists.linux.dev
|
||||
S: Maintained
|
||||
|
|
@ -25861,7 +25937,7 @@ F: drivers/misc/vmw_balloon.c
|
|||
|
||||
VMWARE HYPERVISOR INTERFACE
|
||||
M: Ajay Kaher <ajay.kaher@broadcom.com>
|
||||
M: Alexey Makhalov <alexey.amakhalov@broadcom.com>
|
||||
M: Alexey Makhalov <alexey.makhalov@broadcom.com>
|
||||
R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
|
||||
L: virtualization@lists.linux.dev
|
||||
L: x86@kernel.org
|
||||
|
|
@ -25889,7 +25965,7 @@ F: drivers/scsi/vmw_pvscsi.h
|
|||
VMWARE VIRTUAL PTP CLOCK DRIVER
|
||||
M: Nick Shi <nick.shi@broadcom.com>
|
||||
R: Ajay Kaher <ajay.kaher@broadcom.com>
|
||||
R: Alexey Makhalov <alexey.amakhalov@broadcom.com>
|
||||
R: Alexey Makhalov <alexey.makhalov@broadcom.com>
|
||||
R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
|
|
|
|||
5
Makefile
5
Makefile
|
|
@ -2,7 +2,7 @@
|
|||
VERSION = 6
|
||||
PATCHLEVEL = 15
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc5
|
||||
EXTRAVERSION = -rc7
|
||||
NAME = Baby Opossum Posse
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
@ -1068,8 +1068,7 @@ KBUILD_CFLAGS += -fno-builtin-wcslen
|
|||
|
||||
# change __FILE__ to the relative path to the source directory
|
||||
ifdef building_out_of_srctree
|
||||
KBUILD_CPPFLAGS += $(call cc-option,-ffile-prefix-map=$(srcroot)/=)
|
||||
KBUILD_RUSTFLAGS += --remap-path-prefix=$(srcroot)/=
|
||||
KBUILD_CPPFLAGS += $(call cc-option,-fmacro-prefix-map=$(srcroot)/=)
|
||||
endif
|
||||
|
||||
# include additional Makefiles when needed
|
||||
|
|
|
|||
|
|
@ -451,7 +451,7 @@
|
|||
pwm_ef: pwm@86c0 {
|
||||
compatible = "amlogic,meson8-pwm-v2";
|
||||
clocks = <&xtal>,
|
||||
<>, /* unknown/untested, the datasheet calls it "Video PLL" */
|
||||
<0>, /* unknown/untested, the datasheet calls it "Video PLL" */
|
||||
<&clkc CLKID_FCLK_DIV4>,
|
||||
<&clkc CLKID_FCLK_DIV3>;
|
||||
reg = <0x86c0 0x10>;
|
||||
|
|
@ -705,7 +705,7 @@
|
|||
&pwm_ab {
|
||||
compatible = "amlogic,meson8-pwm-v2";
|
||||
clocks = <&xtal>,
|
||||
<>, /* unknown/untested, the datasheet calls it "Video PLL" */
|
||||
<0>, /* unknown/untested, the datasheet calls it "Video PLL" */
|
||||
<&clkc CLKID_FCLK_DIV4>,
|
||||
<&clkc CLKID_FCLK_DIV3>;
|
||||
};
|
||||
|
|
@ -713,7 +713,7 @@
|
|||
&pwm_cd {
|
||||
compatible = "amlogic,meson8-pwm-v2";
|
||||
clocks = <&xtal>,
|
||||
<>, /* unknown/untested, the datasheet calls it "Video PLL" */
|
||||
<0>, /* unknown/untested, the datasheet calls it "Video PLL" */
|
||||
<&clkc CLKID_FCLK_DIV4>,
|
||||
<&clkc CLKID_FCLK_DIV3>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -406,7 +406,7 @@
|
|||
compatible = "amlogic,meson8b-pwm-v2", "amlogic,meson8-pwm-v2";
|
||||
reg = <0x86c0 0x10>;
|
||||
clocks = <&xtal>,
|
||||
<>, /* unknown/untested, the datasheet calls it "Video PLL" */
|
||||
<0>, /* unknown/untested, the datasheet calls it "Video PLL" */
|
||||
<&clkc CLKID_FCLK_DIV4>,
|
||||
<&clkc CLKID_FCLK_DIV3>;
|
||||
#pwm-cells = <3>;
|
||||
|
|
@ -680,7 +680,7 @@
|
|||
&pwm_ab {
|
||||
compatible = "amlogic,meson8b-pwm-v2", "amlogic,meson8-pwm-v2";
|
||||
clocks = <&xtal>,
|
||||
<>, /* unknown/untested, the datasheet calls it "Video PLL" */
|
||||
<0>, /* unknown/untested, the datasheet calls it "Video PLL" */
|
||||
<&clkc CLKID_FCLK_DIV4>,
|
||||
<&clkc CLKID_FCLK_DIV3>;
|
||||
};
|
||||
|
|
@ -688,7 +688,7 @@
|
|||
&pwm_cd {
|
||||
compatible = "amlogic,meson8b-pwm-v2", "amlogic,meson8-pwm-v2";
|
||||
clocks = <&xtal>,
|
||||
<>, /* unknown/untested, the datasheet calls it "Video PLL" */
|
||||
<0>, /* unknown/untested, the datasheet calls it "Video PLL" */
|
||||
<&clkc CLKID_FCLK_DIV4>,
|
||||
<&clkc CLKID_FCLK_DIV3>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@
|
|||
al,msi-num-spis = <160>;
|
||||
};
|
||||
|
||||
io-fabric@fc000000 {
|
||||
io-bus@fc000000 {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
|
|
|||
|
|
@ -361,7 +361,7 @@
|
|||
interrupt-parent = <&gic>;
|
||||
};
|
||||
|
||||
io-fabric@fc000000 {
|
||||
io-bus@fc000000 {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
|
|
|||
|
|
@ -2313,7 +2313,7 @@
|
|||
"amlogic,meson8-pwm-v2";
|
||||
reg = <0x0 0x19000 0x0 0x20>;
|
||||
clocks = <&xtal>,
|
||||
<>, /* unknown/untested, the datasheet calls it "vid_pll" */
|
||||
<0>, /* unknown/untested, the datasheet calls it "vid_pll" */
|
||||
<&clkc CLKID_FCLK_DIV4>,
|
||||
<&clkc CLKID_FCLK_DIV3>;
|
||||
#pwm-cells = <3>;
|
||||
|
|
@ -2325,7 +2325,7 @@
|
|||
"amlogic,meson8-pwm-v2";
|
||||
reg = <0x0 0x1a000 0x0 0x20>;
|
||||
clocks = <&xtal>,
|
||||
<>, /* unknown/untested, the datasheet calls it "vid_pll" */
|
||||
<0>, /* unknown/untested, the datasheet calls it "vid_pll" */
|
||||
<&clkc CLKID_FCLK_DIV4>,
|
||||
<&clkc CLKID_FCLK_DIV3>;
|
||||
#pwm-cells = <3>;
|
||||
|
|
@ -2337,7 +2337,7 @@
|
|||
"amlogic,meson8-pwm-v2";
|
||||
reg = <0x0 0x1b000 0x0 0x20>;
|
||||
clocks = <&xtal>,
|
||||
<>, /* unknown/untested, the datasheet calls it "vid_pll" */
|
||||
<0>, /* unknown/untested, the datasheet calls it "vid_pll" */
|
||||
<&clkc CLKID_FCLK_DIV4>,
|
||||
<&clkc CLKID_FCLK_DIV3>;
|
||||
#pwm-cells = <3>;
|
||||
|
|
|
|||
|
|
@ -116,6 +116,10 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&clkc_audio {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&frddr_a {
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -741,7 +741,7 @@
|
|||
|
||||
&pwm_ab {
|
||||
clocks = <&xtal>,
|
||||
<>, /* unknown/untested, the datasheet calls it "vid_pll" */
|
||||
<0>, /* unknown/untested, the datasheet calls it "vid_pll" */
|
||||
<&clkc CLKID_FCLK_DIV4>,
|
||||
<&clkc CLKID_FCLK_DIV3>;
|
||||
};
|
||||
|
|
@ -752,14 +752,14 @@
|
|||
|
||||
&pwm_cd {
|
||||
clocks = <&xtal>,
|
||||
<>, /* unknown/untested, the datasheet calls it "vid_pll" */
|
||||
<0>, /* unknown/untested, the datasheet calls it "vid_pll" */
|
||||
<&clkc CLKID_FCLK_DIV4>,
|
||||
<&clkc CLKID_FCLK_DIV3>;
|
||||
};
|
||||
|
||||
&pwm_ef {
|
||||
clocks = <&xtal>,
|
||||
<>, /* unknown/untested, the datasheet calls it "vid_pll" */
|
||||
<0>, /* unknown/untested, the datasheet calls it "vid_pll" */
|
||||
<&clkc CLKID_FCLK_DIV4>,
|
||||
<&clkc CLKID_FCLK_DIV3>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -811,7 +811,7 @@
|
|||
|
||||
&pwm_ab {
|
||||
clocks = <&xtal>,
|
||||
<>, /* unknown/untested, the datasheet calls it "vid_pll" */
|
||||
<0>, /* unknown/untested, the datasheet calls it "vid_pll" */
|
||||
<&clkc CLKID_FCLK_DIV4>,
|
||||
<&clkc CLKID_FCLK_DIV3>;
|
||||
};
|
||||
|
|
@ -822,14 +822,14 @@
|
|||
|
||||
&pwm_cd {
|
||||
clocks = <&xtal>,
|
||||
<>, /* unknown/untested, the datasheet calls it "vid_pll" */
|
||||
<0>, /* unknown/untested, the datasheet calls it "vid_pll" */
|
||||
<&clkc CLKID_FCLK_DIV4>,
|
||||
<&clkc CLKID_FCLK_DIV3>;
|
||||
};
|
||||
|
||||
&pwm_ef {
|
||||
clocks = <&xtal>,
|
||||
<>, /* unknown/untested, the datasheet calls it "vid_pll" */
|
||||
<0>, /* unknown/untested, the datasheet calls it "vid_pll" */
|
||||
<&clkc CLKID_FCLK_DIV4>,
|
||||
<&clkc CLKID_FCLK_DIV3>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -77,6 +77,16 @@
|
|||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* The driver depends on boot loader initialized state which resets when this
|
||||
* power-domain is powered off. This happens on suspend or when the driver is
|
||||
* missing during boot. Mark the domain as always on until the driver can
|
||||
* handle this.
|
||||
*/
|
||||
&ps_dispdfr_be {
|
||||
apple,always-on;
|
||||
};
|
||||
|
||||
&display_dfr {
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -40,6 +40,16 @@
|
|||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* The driver depends on boot loader initialized state which resets when this
|
||||
* power-domain is powered off. This happens on suspend or when the driver is
|
||||
* missing during boot. Mark the domain as always on until the driver can
|
||||
* handle this.
|
||||
*/
|
||||
&ps_dispdfr_be {
|
||||
apple,always-on;
|
||||
};
|
||||
|
||||
&display_dfr {
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -88,3 +88,5 @@
|
|||
<0>, <0>, <400000000>,
|
||||
<1039500000>;
|
||||
};
|
||||
|
||||
/delete-node/ &{noc_opp_table/opp-1000000000};
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@
|
|||
<0x1 0x00000000 0 0xc0000000>;
|
||||
};
|
||||
|
||||
|
||||
reg_usdhc2_vmmc: regulator-usdhc2-vmmc {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "VSD_3V3";
|
||||
|
|
@ -46,6 +45,16 @@
|
|||
startup-delay-us = <100>;
|
||||
off-on-delay-us = <12000>;
|
||||
};
|
||||
|
||||
reg_usdhc2_vqmmc: regulator-usdhc2-vqmmc {
|
||||
compatible = "regulator-gpio";
|
||||
regulator-name = "VSD_VSEL";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
gpios = <&gpio2 12 GPIO_ACTIVE_HIGH>;
|
||||
states = <3300000 0x0 1800000 0x1>;
|
||||
vin-supply = <&ldo5>;
|
||||
};
|
||||
};
|
||||
|
||||
&A53_0 {
|
||||
|
|
@ -205,6 +214,7 @@
|
|||
pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
|
||||
cd-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
|
||||
vmmc-supply = <®_usdhc2_vmmc>;
|
||||
vqmmc-supply = <®_usdhc2_vqmmc>;
|
||||
bus-width = <4>;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1645,6 +1645,12 @@
|
|||
opp-hz = /bits/ 64 <200000000>;
|
||||
};
|
||||
|
||||
/* Nominal drive mode maximum */
|
||||
opp-800000000 {
|
||||
opp-hz = /bits/ 64 <800000000>;
|
||||
};
|
||||
|
||||
/* Overdrive mode maximum */
|
||||
opp-1000000000 {
|
||||
opp-hz = /bits/ 64 <1000000000>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
};
|
||||
|
||||
vcc3v3_btreg: vcc3v3-btreg {
|
||||
compatible = "regulator-gpio";
|
||||
compatible = "regulator-fixed";
|
||||
enable-active-high;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&bt_enable_h>;
|
||||
|
|
@ -39,7 +39,6 @@
|
|||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-always-on;
|
||||
states = <3300000 0x0>;
|
||||
};
|
||||
|
||||
vcc3v3_rf_aux_mod: regulator-vcc3v3-rf-aux-mod {
|
||||
|
|
|
|||
|
|
@ -26,5 +26,5 @@
|
|||
};
|
||||
|
||||
&vcc3v3_btreg {
|
||||
enable-gpios = <&gpio1 RK_PC3 GPIO_ACTIVE_HIGH>;
|
||||
gpios = <&gpio1 RK_PC3 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -39,5 +39,5 @@
|
|||
};
|
||||
|
||||
&vcc3v3_btreg {
|
||||
enable-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;
|
||||
gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@
|
|||
sdio_pwrseq: sdio-pwrseq {
|
||||
compatible = "mmc-pwrseq-simple";
|
||||
clocks = <&rk808 1>;
|
||||
clock-names = "lpo";
|
||||
clock-names = "ext_clock";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&wifi_enable_h>;
|
||||
reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
|
||||
|
|
|
|||
|
|
@ -775,7 +775,7 @@
|
|||
rockchip,default-sample-phase = <90>;
|
||||
status = "okay";
|
||||
|
||||
sdio-wifi@1 {
|
||||
wifi@1 {
|
||||
compatible = "brcm,bcm4329-fmac";
|
||||
reg = <1>;
|
||||
interrupt-parent = <&gpio2>;
|
||||
|
|
|
|||
|
|
@ -619,6 +619,8 @@
|
|||
bus-width = <8>;
|
||||
max-frequency = <200000000>;
|
||||
non-removable;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -610,7 +610,7 @@
|
|||
reg = <0x51>;
|
||||
clock-output-names = "hym8563";
|
||||
interrupt-parent = <&gpio0>;
|
||||
interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupts = <RK_PA0 IRQ_TYPE_LEVEL_LOW>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&hym8563_int>;
|
||||
wakeup-source;
|
||||
|
|
|
|||
|
|
@ -222,6 +222,10 @@
|
|||
compatible = "realtek,rt5616";
|
||||
reg = <0x1b>;
|
||||
#sound-dai-cells = <0>;
|
||||
assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
|
||||
assigned-clock-rates = <12288000>;
|
||||
clocks = <&cru I2S0_8CH_MCLKOUT>;
|
||||
clock-names = "mclk";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -214,6 +214,8 @@
|
|||
};
|
||||
|
||||
&package_thermal {
|
||||
polling-delay = <1000>;
|
||||
|
||||
trips {
|
||||
package_active1: trip-active1 {
|
||||
temperature = <45000>;
|
||||
|
|
|
|||
|
|
@ -11,20 +11,15 @@
|
|||
compatible = "operating-points-v2";
|
||||
opp-shared;
|
||||
|
||||
opp-1416000000 {
|
||||
opp-hz = /bits/ 64 <1416000000>;
|
||||
opp-1200000000 {
|
||||
opp-hz = /bits/ 64 <1200000000>;
|
||||
opp-microvolt = <750000 750000 950000>;
|
||||
clock-latency-ns = <40000>;
|
||||
opp-suspend;
|
||||
};
|
||||
opp-1608000000 {
|
||||
opp-hz = /bits/ 64 <1608000000>;
|
||||
opp-microvolt = <887500 887500 950000>;
|
||||
clock-latency-ns = <40000>;
|
||||
};
|
||||
opp-1704000000 {
|
||||
opp-hz = /bits/ 64 <1704000000>;
|
||||
opp-microvolt = <937500 937500 950000>;
|
||||
opp-1296000000 {
|
||||
opp-hz = /bits/ 64 <1296000000>;
|
||||
opp-microvolt = <775000 775000 950000>;
|
||||
clock-latency-ns = <40000>;
|
||||
};
|
||||
};
|
||||
|
|
@ -33,9 +28,14 @@
|
|||
compatible = "operating-points-v2";
|
||||
opp-shared;
|
||||
|
||||
opp-1200000000{
|
||||
opp-hz = /bits/ 64 <1200000000>;
|
||||
opp-microvolt = <750000 750000 950000>;
|
||||
clock-latency-ns = <40000>;
|
||||
};
|
||||
opp-1416000000 {
|
||||
opp-hz = /bits/ 64 <1416000000>;
|
||||
opp-microvolt = <750000 750000 950000>;
|
||||
opp-microvolt = <762500 762500 950000>;
|
||||
clock-latency-ns = <40000>;
|
||||
};
|
||||
opp-1608000000 {
|
||||
|
|
@ -43,25 +43,20 @@
|
|||
opp-microvolt = <787500 787500 950000>;
|
||||
clock-latency-ns = <40000>;
|
||||
};
|
||||
opp-1800000000 {
|
||||
opp-hz = /bits/ 64 <1800000000>;
|
||||
opp-microvolt = <875000 875000 950000>;
|
||||
clock-latency-ns = <40000>;
|
||||
};
|
||||
opp-2016000000 {
|
||||
opp-hz = /bits/ 64 <2016000000>;
|
||||
opp-microvolt = <950000 950000 950000>;
|
||||
clock-latency-ns = <40000>;
|
||||
};
|
||||
};
|
||||
|
||||
cluster2_opp_table: opp-table-cluster2 {
|
||||
compatible = "operating-points-v2";
|
||||
opp-shared;
|
||||
|
||||
opp-1200000000{
|
||||
opp-hz = /bits/ 64 <1200000000>;
|
||||
opp-microvolt = <750000 750000 950000>;
|
||||
clock-latency-ns = <40000>;
|
||||
};
|
||||
opp-1416000000 {
|
||||
opp-hz = /bits/ 64 <1416000000>;
|
||||
opp-microvolt = <750000 750000 950000>;
|
||||
opp-microvolt = <762500 762500 950000>;
|
||||
clock-latency-ns = <40000>;
|
||||
};
|
||||
opp-1608000000 {
|
||||
|
|
@ -69,16 +64,6 @@
|
|||
opp-microvolt = <787500 787500 950000>;
|
||||
clock-latency-ns = <40000>;
|
||||
};
|
||||
opp-1800000000 {
|
||||
opp-hz = /bits/ 64 <1800000000>;
|
||||
opp-microvolt = <875000 875000 950000>;
|
||||
clock-latency-ns = <40000>;
|
||||
};
|
||||
opp-2016000000 {
|
||||
opp-hz = /bits/ 64 <2016000000>;
|
||||
opp-microvolt = <950000 950000 950000>;
|
||||
clock-latency-ns = <40000>;
|
||||
};
|
||||
};
|
||||
|
||||
gpu_opp_table: opp-table {
|
||||
|
|
@ -104,10 +89,6 @@
|
|||
opp-hz = /bits/ 64 <700000000>;
|
||||
opp-microvolt = <750000 750000 850000>;
|
||||
};
|
||||
opp-850000000 {
|
||||
opp-hz = /bits/ 64 <800000000>;
|
||||
opp-microvolt = <787500 787500 850000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@
|
|||
#define ARM_CPU_PART_CORTEX_A78AE 0xD42
|
||||
#define ARM_CPU_PART_CORTEX_X1 0xD44
|
||||
#define ARM_CPU_PART_CORTEX_A510 0xD46
|
||||
#define ARM_CPU_PART_CORTEX_X1C 0xD4C
|
||||
#define ARM_CPU_PART_CORTEX_A520 0xD80
|
||||
#define ARM_CPU_PART_CORTEX_A710 0xD47
|
||||
#define ARM_CPU_PART_CORTEX_A715 0xD4D
|
||||
|
|
@ -168,6 +169,7 @@
|
|||
#define MIDR_CORTEX_A78AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78AE)
|
||||
#define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1)
|
||||
#define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510)
|
||||
#define MIDR_CORTEX_X1C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1C)
|
||||
#define MIDR_CORTEX_A520 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A520)
|
||||
#define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
|
||||
#define MIDR_CORTEX_A715 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A715)
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
mrs x0, id_aa64mmfr1_el1
|
||||
ubfx x0, x0, #ID_AA64MMFR1_EL1_HCX_SHIFT, #4
|
||||
cbz x0, .Lskip_hcrx_\@
|
||||
mov_q x0, HCRX_HOST_FLAGS
|
||||
mov_q x0, (HCRX_EL2_MSCEn | HCRX_EL2_TCR2En | HCRX_EL2_EnFPM)
|
||||
|
||||
/* Enable GCS if supported */
|
||||
mrs_s x1, SYS_ID_AA64PFR1_EL1
|
||||
|
|
|
|||
|
|
@ -706,6 +706,7 @@ u32 aarch64_insn_gen_cas(enum aarch64_insn_register result,
|
|||
}
|
||||
#endif
|
||||
u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type);
|
||||
u32 aarch64_insn_gen_dsb(enum aarch64_insn_mb_type type);
|
||||
u32 aarch64_insn_gen_mrs(enum aarch64_insn_register result,
|
||||
enum aarch64_insn_system_register sysreg);
|
||||
|
||||
|
|
|
|||
|
|
@ -100,9 +100,8 @@
|
|||
HCR_FMO | HCR_IMO | HCR_PTW | HCR_TID3 | HCR_TID1)
|
||||
#define HCR_HOST_NVHE_FLAGS (HCR_RW | HCR_API | HCR_APK | HCR_ATA)
|
||||
#define HCR_HOST_NVHE_PROTECTED_FLAGS (HCR_HOST_NVHE_FLAGS | HCR_TSC)
|
||||
#define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H)
|
||||
#define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H | HCR_AMO | HCR_IMO | HCR_FMO)
|
||||
|
||||
#define HCRX_HOST_FLAGS (HCRX_EL2_MSCEn | HCRX_EL2_TCR2En | HCRX_EL2_EnFPM)
|
||||
#define MPAMHCR_HOST_FLAGS 0
|
||||
|
||||
/* TCR_EL2 Registers bits */
|
||||
|
|
|
|||
|
|
@ -97,6 +97,9 @@ enum mitigation_state arm64_get_meltdown_state(void);
|
|||
|
||||
enum mitigation_state arm64_get_spectre_bhb_state(void);
|
||||
bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry, int scope);
|
||||
extern bool __nospectre_bhb;
|
||||
u8 get_spectre_bhb_loop_value(void);
|
||||
bool is_spectre_bhb_fw_mitigated(void);
|
||||
void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *__unused);
|
||||
bool try_emulate_el1_ssbs(struct pt_regs *regs, u32 instr);
|
||||
|
||||
|
|
|
|||
|
|
@ -99,6 +99,19 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
|
|||
return res;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_CC_IS_GCC) && IS_ENABLED(CONFIG_PAGE_SIZE_64KB)
|
||||
static __always_inline const struct vdso_time_data *__arch_get_vdso_u_time_data(void)
|
||||
{
|
||||
const struct vdso_time_data *ret = &vdso_u_time_data;
|
||||
|
||||
/* Work around invalid absolute relocations */
|
||||
OPTIMIZER_HIDE_VAR(ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#define __arch_get_vdso_u_time_data __arch_get_vdso_u_time_data
|
||||
#endif /* IS_ENABLED(CONFIG_CC_IS_GCC) && IS_ENABLED(CONFIG_PAGE_SIZE_64KB) */
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* __ASM_VDSO_GETTIMEOFDAY_H */
|
||||
|
|
|
|||
|
|
@ -114,7 +114,14 @@ static struct arm64_cpu_capabilities const __ro_after_init *cpucap_ptrs[ARM64_NC
|
|||
|
||||
DECLARE_BITMAP(boot_cpucaps, ARM64_NCAPS);
|
||||
|
||||
bool arm64_use_ng_mappings = false;
|
||||
/*
|
||||
* arm64_use_ng_mappings must be placed in the .data section, otherwise it
|
||||
* ends up in the .bss section where it is initialized in early_map_kernel()
|
||||
* after the MMU (with the idmap) was enabled. create_init_idmap() - which
|
||||
* runs before early_map_kernel() and reads the variable via PTE_MAYBE_NG -
|
||||
* may end up generating an incorrect idmap page table attributes.
|
||||
*/
|
||||
bool arm64_use_ng_mappings __read_mostly = false;
|
||||
EXPORT_SYMBOL(arm64_use_ng_mappings);
|
||||
|
||||
DEFINE_PER_CPU_READ_MOSTLY(const char *, this_cpu_vector) = vectors;
|
||||
|
|
|
|||
|
|
@ -891,6 +891,7 @@ static u8 spectre_bhb_loop_affected(void)
|
|||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78AE),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_X1C),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
|
||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
|
||||
|
|
@ -999,6 +1000,11 @@ bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry,
|
|||
return true;
|
||||
}
|
||||
|
||||
u8 get_spectre_bhb_loop_value(void)
|
||||
{
|
||||
return max_bhb_k;
|
||||
}
|
||||
|
||||
static void this_cpu_set_vectors(enum arm64_bp_harden_el1_vectors slot)
|
||||
{
|
||||
const char *v = arm64_get_bp_hardening_vector(slot);
|
||||
|
|
@ -1016,7 +1022,7 @@ static void this_cpu_set_vectors(enum arm64_bp_harden_el1_vectors slot)
|
|||
isb();
|
||||
}
|
||||
|
||||
static bool __read_mostly __nospectre_bhb;
|
||||
bool __read_mostly __nospectre_bhb;
|
||||
static int __init parse_spectre_bhb_param(char *str)
|
||||
{
|
||||
__nospectre_bhb = true;
|
||||
|
|
@ -1094,6 +1100,11 @@ void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *entry)
|
|||
update_mitigation_state(&spectre_bhb_state, state);
|
||||
}
|
||||
|
||||
bool is_spectre_bhb_fw_mitigated(void)
|
||||
{
|
||||
return test_bit(BHB_FW, &system_bhb_mitigations);
|
||||
}
|
||||
|
||||
/* Patched to NOP when enabled */
|
||||
void noinstr spectre_bhb_patch_loop_mitigation_enable(struct alt_instr *alt,
|
||||
__le32 *origptr,
|
||||
|
|
|
|||
|
|
@ -235,6 +235,8 @@ static inline void __deactivate_traps_mpam(void)
|
|||
|
||||
static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm_cpu_context *hctxt = host_data_ptr(host_ctxt);
|
||||
|
||||
/* Trap on AArch32 cp15 c15 (impdef sysregs) accesses (EL1 or EL0) */
|
||||
write_sysreg(1 << 15, hstr_el2);
|
||||
|
||||
|
|
@ -245,11 +247,8 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
|
|||
* EL1 instead of being trapped to EL2.
|
||||
*/
|
||||
if (system_supports_pmuv3()) {
|
||||
struct kvm_cpu_context *hctxt;
|
||||
|
||||
write_sysreg(0, pmselr_el0);
|
||||
|
||||
hctxt = host_data_ptr(host_ctxt);
|
||||
ctxt_sys_reg(hctxt, PMUSERENR_EL0) = read_sysreg(pmuserenr_el0);
|
||||
write_sysreg(ARMV8_PMU_USERENR_MASK, pmuserenr_el0);
|
||||
vcpu_set_flag(vcpu, PMUSERENR_ON_CPU);
|
||||
|
|
@ -269,6 +268,7 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
|
|||
hcrx &= ~clr;
|
||||
}
|
||||
|
||||
ctxt_sys_reg(hctxt, HCRX_EL2) = read_sysreg_s(SYS_HCRX_EL2);
|
||||
write_sysreg_s(hcrx, SYS_HCRX_EL2);
|
||||
}
|
||||
|
||||
|
|
@ -278,19 +278,18 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
|
|||
|
||||
static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm_cpu_context *hctxt = host_data_ptr(host_ctxt);
|
||||
|
||||
write_sysreg(*host_data_ptr(host_debug_state.mdcr_el2), mdcr_el2);
|
||||
|
||||
write_sysreg(0, hstr_el2);
|
||||
if (system_supports_pmuv3()) {
|
||||
struct kvm_cpu_context *hctxt;
|
||||
|
||||
hctxt = host_data_ptr(host_ctxt);
|
||||
write_sysreg(ctxt_sys_reg(hctxt, PMUSERENR_EL0), pmuserenr_el0);
|
||||
vcpu_clear_flag(vcpu, PMUSERENR_ON_CPU);
|
||||
}
|
||||
|
||||
if (cpus_have_final_cap(ARM64_HAS_HCX))
|
||||
write_sysreg_s(HCRX_HOST_FLAGS, SYS_HCRX_EL2);
|
||||
write_sysreg_s(ctxt_sys_reg(hctxt, HCRX_EL2), SYS_HCRX_EL2);
|
||||
|
||||
__deactivate_traps_hfgxtr(vcpu);
|
||||
__deactivate_traps_mpam();
|
||||
|
|
|
|||
|
|
@ -503,7 +503,7 @@ int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id)
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (!addr_is_memory(addr))
|
||||
if (!range_is_memory(addr, addr + size))
|
||||
return -EPERM;
|
||||
|
||||
ret = host_stage2_try(kvm_pgtable_stage2_set_owner, &host_mmu.pgt,
|
||||
|
|
|
|||
|
|
@ -429,23 +429,27 @@ u64 __vgic_v3_get_gic_config(void)
|
|||
/*
|
||||
* To check whether we have a MMIO-based (GICv2 compatible)
|
||||
* CPU interface, we need to disable the system register
|
||||
* view. To do that safely, we have to prevent any interrupt
|
||||
* from firing (which would be deadly).
|
||||
* view.
|
||||
*
|
||||
* Note that this only makes sense on VHE, as interrupts are
|
||||
* already masked for nVHE as part of the exception entry to
|
||||
* EL2.
|
||||
*/
|
||||
if (has_vhe())
|
||||
flags = local_daif_save();
|
||||
|
||||
/*
|
||||
* Table 11-2 "Permitted ICC_SRE_ELx.SRE settings" indicates
|
||||
* that to be able to set ICC_SRE_EL1.SRE to 0, all the
|
||||
* interrupt overrides must be set. You've got to love this.
|
||||
*
|
||||
* As we always run VHE with HCR_xMO set, no extra xMO
|
||||
* manipulation is required in that case.
|
||||
*
|
||||
* To safely disable SRE, we have to prevent any interrupt
|
||||
* from firing (which would be deadly). This only makes sense
|
||||
* on VHE, as interrupts are already masked for nVHE as part
|
||||
* of the exception entry to EL2.
|
||||
*/
|
||||
sysreg_clear_set(hcr_el2, 0, HCR_AMO | HCR_FMO | HCR_IMO);
|
||||
isb();
|
||||
if (has_vhe()) {
|
||||
flags = local_daif_save();
|
||||
} else {
|
||||
sysreg_clear_set(hcr_el2, 0, HCR_AMO | HCR_FMO | HCR_IMO);
|
||||
isb();
|
||||
}
|
||||
|
||||
write_gicreg(0, ICC_SRE_EL1);
|
||||
isb();
|
||||
|
||||
|
|
@ -453,11 +457,13 @@ u64 __vgic_v3_get_gic_config(void)
|
|||
|
||||
write_gicreg(sre, ICC_SRE_EL1);
|
||||
isb();
|
||||
sysreg_clear_set(hcr_el2, HCR_AMO | HCR_FMO | HCR_IMO, 0);
|
||||
isb();
|
||||
|
||||
if (has_vhe())
|
||||
if (has_vhe()) {
|
||||
local_daif_restore(flags);
|
||||
} else {
|
||||
sysreg_clear_set(hcr_el2, HCR_AMO | HCR_FMO | HCR_IMO, 0);
|
||||
isb();
|
||||
}
|
||||
|
||||
val = (val & ICC_SRE_EL1_SRE) ? 0 : (1ULL << 63);
|
||||
val |= read_gicreg(ICH_VTR_EL2);
|
||||
|
|
|
|||
|
|
@ -1501,6 +1501,11 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
|
|||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (!is_protected_kvm_enabled())
|
||||
memcache = &vcpu->arch.mmu_page_cache;
|
||||
else
|
||||
memcache = &vcpu->arch.pkvm_memcache;
|
||||
|
||||
/*
|
||||
* Permission faults just need to update the existing leaf entry,
|
||||
* and so normally don't require allocations from the memcache. The
|
||||
|
|
@ -1510,13 +1515,11 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
|
|||
if (!fault_is_perm || (logging_active && write_fault)) {
|
||||
int min_pages = kvm_mmu_cache_min_pages(vcpu->arch.hw_mmu);
|
||||
|
||||
if (!is_protected_kvm_enabled()) {
|
||||
memcache = &vcpu->arch.mmu_page_cache;
|
||||
if (!is_protected_kvm_enabled())
|
||||
ret = kvm_mmu_topup_memory_cache(memcache, min_pages);
|
||||
} else {
|
||||
memcache = &vcpu->arch.pkvm_memcache;
|
||||
else
|
||||
ret = topup_hyp_memcache(memcache, min_pages);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1945,6 +1945,12 @@ static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
|
|||
if ((hw_val & mpam_mask) == (user_val & mpam_mask))
|
||||
user_val &= ~ID_AA64PFR0_EL1_MPAM_MASK;
|
||||
|
||||
/* Fail the guest's request to disable the AA64 ISA at EL{0,1,2} */
|
||||
if (!FIELD_GET(ID_AA64PFR0_EL1_EL0, user_val) ||
|
||||
!FIELD_GET(ID_AA64PFR0_EL1_EL1, user_val) ||
|
||||
(vcpu_has_nv(vcpu) && !FIELD_GET(ID_AA64PFR0_EL1_EL2, user_val)))
|
||||
return -EINVAL;
|
||||
|
||||
return set_id_reg(vcpu, rd, user_val);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
*
|
||||
* Copyright (C) 2014-2016 Zi Shen Lim <zlim.lnx@gmail.com>
|
||||
*/
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/printk.h>
|
||||
|
|
@ -1500,43 +1501,41 @@ u32 aarch64_insn_gen_extr(enum aarch64_insn_variant variant,
|
|||
return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, Rm);
|
||||
}
|
||||
|
||||
static u32 __get_barrier_crm_val(enum aarch64_insn_mb_type type)
|
||||
{
|
||||
switch (type) {
|
||||
case AARCH64_INSN_MB_SY:
|
||||
return 0xf;
|
||||
case AARCH64_INSN_MB_ST:
|
||||
return 0xe;
|
||||
case AARCH64_INSN_MB_LD:
|
||||
return 0xd;
|
||||
case AARCH64_INSN_MB_ISH:
|
||||
return 0xb;
|
||||
case AARCH64_INSN_MB_ISHST:
|
||||
return 0xa;
|
||||
case AARCH64_INSN_MB_ISHLD:
|
||||
return 0x9;
|
||||
case AARCH64_INSN_MB_NSH:
|
||||
return 0x7;
|
||||
case AARCH64_INSN_MB_NSHST:
|
||||
return 0x6;
|
||||
case AARCH64_INSN_MB_NSHLD:
|
||||
return 0x5;
|
||||
default:
|
||||
pr_err("%s: unknown barrier type %d\n", __func__, type);
|
||||
return AARCH64_BREAK_FAULT;
|
||||
}
|
||||
}
|
||||
|
||||
u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type)
|
||||
{
|
||||
u32 opt;
|
||||
u32 insn;
|
||||
|
||||
switch (type) {
|
||||
case AARCH64_INSN_MB_SY:
|
||||
opt = 0xf;
|
||||
break;
|
||||
case AARCH64_INSN_MB_ST:
|
||||
opt = 0xe;
|
||||
break;
|
||||
case AARCH64_INSN_MB_LD:
|
||||
opt = 0xd;
|
||||
break;
|
||||
case AARCH64_INSN_MB_ISH:
|
||||
opt = 0xb;
|
||||
break;
|
||||
case AARCH64_INSN_MB_ISHST:
|
||||
opt = 0xa;
|
||||
break;
|
||||
case AARCH64_INSN_MB_ISHLD:
|
||||
opt = 0x9;
|
||||
break;
|
||||
case AARCH64_INSN_MB_NSH:
|
||||
opt = 0x7;
|
||||
break;
|
||||
case AARCH64_INSN_MB_NSHST:
|
||||
opt = 0x6;
|
||||
break;
|
||||
case AARCH64_INSN_MB_NSHLD:
|
||||
opt = 0x5;
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: unknown dmb type %d\n", __func__, type);
|
||||
opt = __get_barrier_crm_val(type);
|
||||
if (opt == AARCH64_BREAK_FAULT)
|
||||
return AARCH64_BREAK_FAULT;
|
||||
}
|
||||
|
||||
insn = aarch64_insn_get_dmb_value();
|
||||
insn &= ~GENMASK(11, 8);
|
||||
|
|
@ -1545,6 +1544,21 @@ u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type)
|
|||
return insn;
|
||||
}
|
||||
|
||||
u32 aarch64_insn_gen_dsb(enum aarch64_insn_mb_type type)
|
||||
{
|
||||
u32 opt, insn;
|
||||
|
||||
opt = __get_barrier_crm_val(type);
|
||||
if (opt == AARCH64_BREAK_FAULT)
|
||||
return AARCH64_BREAK_FAULT;
|
||||
|
||||
insn = aarch64_insn_get_dsb_base_value();
|
||||
insn &= ~GENMASK(11, 8);
|
||||
insn |= (opt << 8);
|
||||
|
||||
return insn;
|
||||
}
|
||||
|
||||
u32 aarch64_insn_gen_mrs(enum aarch64_insn_register result,
|
||||
enum aarch64_insn_system_register sysreg)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#define pr_fmt(fmt) "bpf_jit: " fmt
|
||||
|
||||
#include <linux/arm-smccc.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bpf.h>
|
||||
#include <linux/filter.h>
|
||||
|
|
@ -17,6 +18,7 @@
|
|||
#include <asm/asm-extable.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/cpufeature.h>
|
||||
#include <asm/debug-monitors.h>
|
||||
#include <asm/insn.h>
|
||||
#include <asm/text-patching.h>
|
||||
|
|
@ -939,7 +941,51 @@ static void build_plt(struct jit_ctx *ctx)
|
|||
plt->target = (u64)&dummy_tramp;
|
||||
}
|
||||
|
||||
static void build_epilogue(struct jit_ctx *ctx)
|
||||
/* Clobbers BPF registers 1-4, aka x0-x3 */
|
||||
static void __maybe_unused build_bhb_mitigation(struct jit_ctx *ctx)
|
||||
{
|
||||
const u8 r1 = bpf2a64[BPF_REG_1]; /* aka x0 */
|
||||
u8 k = get_spectre_bhb_loop_value();
|
||||
|
||||
if (!IS_ENABLED(CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY) ||
|
||||
cpu_mitigations_off() || __nospectre_bhb ||
|
||||
arm64_get_spectre_v2_state() == SPECTRE_VULNERABLE)
|
||||
return;
|
||||
|
||||
if (capable(CAP_SYS_ADMIN))
|
||||
return;
|
||||
|
||||
if (supports_clearbhb(SCOPE_SYSTEM)) {
|
||||
emit(aarch64_insn_gen_hint(AARCH64_INSN_HINT_CLEARBHB), ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
if (k) {
|
||||
emit_a64_mov_i64(r1, k, ctx);
|
||||
emit(A64_B(1), ctx);
|
||||
emit(A64_SUBS_I(true, r1, r1, 1), ctx);
|
||||
emit(A64_B_(A64_COND_NE, -2), ctx);
|
||||
emit(aarch64_insn_gen_dsb(AARCH64_INSN_MB_ISH), ctx);
|
||||
emit(aarch64_insn_get_isb_value(), ctx);
|
||||
}
|
||||
|
||||
if (is_spectre_bhb_fw_mitigated()) {
|
||||
emit(A64_ORR_I(false, r1, AARCH64_INSN_REG_ZR,
|
||||
ARM_SMCCC_ARCH_WORKAROUND_3), ctx);
|
||||
switch (arm_smccc_1_1_get_conduit()) {
|
||||
case SMCCC_CONDUIT_HVC:
|
||||
emit(aarch64_insn_get_hvc_value(), ctx);
|
||||
break;
|
||||
case SMCCC_CONDUIT_SMC:
|
||||
emit(aarch64_insn_get_smc_value(), ctx);
|
||||
break;
|
||||
default:
|
||||
pr_err_once("Firmware mitigation enabled with unknown conduit\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void build_epilogue(struct jit_ctx *ctx, bool was_classic)
|
||||
{
|
||||
const u8 r0 = bpf2a64[BPF_REG_0];
|
||||
const u8 ptr = bpf2a64[TCCNT_PTR];
|
||||
|
|
@ -952,10 +998,13 @@ static void build_epilogue(struct jit_ctx *ctx)
|
|||
|
||||
emit(A64_POP(A64_ZR, ptr, A64_SP), ctx);
|
||||
|
||||
if (was_classic)
|
||||
build_bhb_mitigation(ctx);
|
||||
|
||||
/* Restore FP/LR registers */
|
||||
emit(A64_POP(A64_FP, A64_LR, A64_SP), ctx);
|
||||
|
||||
/* Set return value */
|
||||
/* Move the return value from bpf:r0 (aka x7) to x0 */
|
||||
emit(A64_MOV(1, A64_R(0), r0), ctx);
|
||||
|
||||
/* Authenticate lr */
|
||||
|
|
@ -1898,7 +1947,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
|
|||
}
|
||||
|
||||
ctx.epilogue_offset = ctx.idx;
|
||||
build_epilogue(&ctx);
|
||||
build_epilogue(&ctx, was_classic);
|
||||
build_plt(&ctx);
|
||||
|
||||
extable_align = __alignof__(struct exception_table_entry);
|
||||
|
|
@ -1961,7 +2010,7 @@ skip_init_ctx:
|
|||
goto out_free_hdr;
|
||||
}
|
||||
|
||||
build_epilogue(&ctx);
|
||||
build_epilogue(&ctx, was_classic);
|
||||
build_plt(&ctx);
|
||||
|
||||
/* Extra pass to validate JITed code. */
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ static inline void instruction_pointer_set(struct pt_regs *regs, unsigned long v
|
|||
|
||||
/* Query offset/name of register from its name/offset */
|
||||
extern int regs_query_register_offset(const char *name);
|
||||
#define MAX_REG_OFFSET (offsetof(struct pt_regs, __last))
|
||||
#define MAX_REG_OFFSET (offsetof(struct pt_regs, __last) - sizeof(unsigned long))
|
||||
|
||||
/**
|
||||
* regs_get_register() - get register value from its offset
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ typedef u32 uprobe_opcode_t;
|
|||
#define UPROBE_XOLBP_INSN __emit_break(BRK_UPROBE_XOLBP)
|
||||
|
||||
struct arch_uprobe {
|
||||
unsigned long resume_era;
|
||||
u32 insn[2];
|
||||
u32 ixol[2];
|
||||
bool simulate;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include <asm/stackframe.h>
|
||||
#include <asm/thread_info.h>
|
||||
|
||||
.section .cpuidle.text, "ax"
|
||||
.align 5
|
||||
SYM_FUNC_START(__arch_cpu_idle)
|
||||
/* start of idle interrupt region */
|
||||
|
|
@ -31,14 +32,16 @@ SYM_FUNC_START(__arch_cpu_idle)
|
|||
*/
|
||||
idle 0
|
||||
/* end of idle interrupt region */
|
||||
1: jr ra
|
||||
idle_exit:
|
||||
jr ra
|
||||
SYM_FUNC_END(__arch_cpu_idle)
|
||||
.previous
|
||||
|
||||
SYM_CODE_START(handle_vint)
|
||||
UNWIND_HINT_UNDEFINED
|
||||
BACKUP_T0T1
|
||||
SAVE_ALL
|
||||
la_abs t1, 1b
|
||||
la_abs t1, idle_exit
|
||||
LONG_L t0, sp, PT_ERA
|
||||
/* 3 instructions idle interrupt region */
|
||||
ori t0, t0, 0b1100
|
||||
|
|
|
|||
|
|
@ -18,11 +18,28 @@ static unsigned int euen_mask = CSR_EUEN_FPEN;
|
|||
static DEFINE_PER_CPU(bool, in_kernel_fpu);
|
||||
static DEFINE_PER_CPU(unsigned int, euen_current);
|
||||
|
||||
static inline void fpregs_lock(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_PREEMPT_RT))
|
||||
preempt_disable();
|
||||
else
|
||||
local_bh_disable();
|
||||
}
|
||||
|
||||
static inline void fpregs_unlock(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_PREEMPT_RT))
|
||||
preempt_enable();
|
||||
else
|
||||
local_bh_enable();
|
||||
}
|
||||
|
||||
void kernel_fpu_begin(void)
|
||||
{
|
||||
unsigned int *euen_curr;
|
||||
|
||||
preempt_disable();
|
||||
if (!irqs_disabled())
|
||||
fpregs_lock();
|
||||
|
||||
WARN_ON(this_cpu_read(in_kernel_fpu));
|
||||
|
||||
|
|
@ -73,7 +90,8 @@ void kernel_fpu_end(void)
|
|||
|
||||
this_cpu_write(in_kernel_fpu, false);
|
||||
|
||||
preempt_enable();
|
||||
if (!irqs_disabled())
|
||||
fpregs_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kernel_fpu_end);
|
||||
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ static unsigned long __init get_loops_per_jiffy(void)
|
|||
return lpj;
|
||||
}
|
||||
|
||||
static long init_offset __nosavedata;
|
||||
static long init_offset;
|
||||
|
||||
void save_counter(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
|
|||
utask->autask.saved_trap_nr = current->thread.trap_nr;
|
||||
current->thread.trap_nr = UPROBE_TRAP_NR;
|
||||
instruction_pointer_set(regs, utask->xol_vaddr);
|
||||
user_enable_single_step(current);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -53,13 +52,7 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
|
|||
|
||||
WARN_ON_ONCE(current->thread.trap_nr != UPROBE_TRAP_NR);
|
||||
current->thread.trap_nr = utask->autask.saved_trap_nr;
|
||||
|
||||
if (auprobe->simulate)
|
||||
instruction_pointer_set(regs, auprobe->resume_era);
|
||||
else
|
||||
instruction_pointer_set(regs, utask->vaddr + LOONGARCH_INSN_SIZE);
|
||||
|
||||
user_disable_single_step(current);
|
||||
instruction_pointer_set(regs, utask->vaddr + LOONGARCH_INSN_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -70,7 +63,6 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
|
|||
|
||||
current->thread.trap_nr = utask->autask.saved_trap_nr;
|
||||
instruction_pointer_set(regs, utask->vaddr);
|
||||
user_disable_single_step(current);
|
||||
}
|
||||
|
||||
bool arch_uprobe_xol_was_trapped(struct task_struct *t)
|
||||
|
|
@ -90,7 +82,6 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
|
|||
|
||||
insn.word = auprobe->insn[0];
|
||||
arch_simulate_insn(insn, regs);
|
||||
auprobe->resume_era = regs->csr_era;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include <asm/fpu.h>
|
||||
#include <asm/loongson.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <linux/suspend.h>
|
||||
|
||||
|
|
@ -14,6 +15,7 @@ struct pt_regs saved_regs;
|
|||
|
||||
void save_processor_state(void)
|
||||
{
|
||||
save_counter();
|
||||
saved_crmd = csr_read32(LOONGARCH_CSR_CRMD);
|
||||
saved_prmd = csr_read32(LOONGARCH_CSR_PRMD);
|
||||
saved_euen = csr_read32(LOONGARCH_CSR_EUEN);
|
||||
|
|
@ -26,6 +28,7 @@ void save_processor_state(void)
|
|||
|
||||
void restore_processor_state(void)
|
||||
{
|
||||
sync_counter();
|
||||
csr_write32(saved_crmd, LOONGARCH_CSR_CRMD);
|
||||
csr_write32(saved_prmd, LOONGARCH_CSR_PRMD);
|
||||
csr_write32(saved_euen, LOONGARCH_CSR_EUEN);
|
||||
|
|
|
|||
|
|
@ -6,11 +6,10 @@
|
|||
#include <linux/linkage.h>
|
||||
|
||||
extern void (*cpu_wait)(void);
|
||||
extern void r4k_wait(void);
|
||||
extern asmlinkage void __r4k_wait(void);
|
||||
extern asmlinkage void r4k_wait(void);
|
||||
extern void r4k_wait_irqoff(void);
|
||||
|
||||
static inline int using_rollback_handler(void)
|
||||
static inline int using_skipover_handler(void)
|
||||
{
|
||||
return cpu_wait == r4k_wait;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,8 @@ static inline void instruction_pointer_set(struct pt_regs *regs,
|
|||
|
||||
/* Query offset/name of register from its name/offset */
|
||||
extern int regs_query_register_offset(const char *name);
|
||||
#define MAX_REG_OFFSET (offsetof(struct pt_regs, __last))
|
||||
#define MAX_REG_OFFSET \
|
||||
(offsetof(struct pt_regs, __last) - sizeof(unsigned long))
|
||||
|
||||
/**
|
||||
* regs_get_register() - get register value from its offset
|
||||
|
|
|
|||
|
|
@ -104,48 +104,59 @@ handle_vcei:
|
|||
|
||||
__FINIT
|
||||
|
||||
.align 5 /* 32 byte rollback region */
|
||||
LEAF(__r4k_wait)
|
||||
.set push
|
||||
.set noreorder
|
||||
/* start of rollback region */
|
||||
LONG_L t0, TI_FLAGS($28)
|
||||
nop
|
||||
andi t0, _TIF_NEED_RESCHED
|
||||
bnez t0, 1f
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
#ifdef CONFIG_CPU_MICROMIPS
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
#endif
|
||||
.section .cpuidle.text,"ax"
|
||||
/* Align to 32 bytes for the maximum idle interrupt region size. */
|
||||
.align 5
|
||||
LEAF(r4k_wait)
|
||||
/* Keep the ISA bit clear for calculations on local labels here. */
|
||||
0: .fill 0
|
||||
/* Start of idle interrupt region. */
|
||||
local_irq_enable
|
||||
/*
|
||||
* If an interrupt lands here, before going idle on the next
|
||||
* instruction, we must *NOT* go idle since the interrupt could
|
||||
* have set TIF_NEED_RESCHED or caused a timer to need resched.
|
||||
* Fall through -- see skipover_handler below -- and have the
|
||||
* idle loop take care of things.
|
||||
*/
|
||||
1: .fill 0
|
||||
/* The R2 EI/EHB sequence takes 8 bytes, otherwise pad up. */
|
||||
.if 1b - 0b > 32
|
||||
.error "overlong idle interrupt region"
|
||||
.elseif 1b - 0b > 8
|
||||
.align 4
|
||||
.endif
|
||||
2: .fill 0
|
||||
.equ r4k_wait_idle_size, 2b - 0b
|
||||
/* End of idle interrupt region; size has to be a power of 2. */
|
||||
.set MIPS_ISA_ARCH_LEVEL_RAW
|
||||
r4k_wait_insn:
|
||||
wait
|
||||
/* end of rollback region (the region size must be power of two) */
|
||||
1:
|
||||
r4k_wait_exit:
|
||||
.set mips0
|
||||
local_irq_disable
|
||||
jr ra
|
||||
nop
|
||||
.set pop
|
||||
END(__r4k_wait)
|
||||
END(r4k_wait)
|
||||
.previous
|
||||
|
||||
.macro BUILD_ROLLBACK_PROLOGUE handler
|
||||
FEXPORT(rollback_\handler)
|
||||
.macro BUILD_SKIPOVER_PROLOGUE handler
|
||||
FEXPORT(skipover_\handler)
|
||||
.set push
|
||||
.set noat
|
||||
MFC0 k0, CP0_EPC
|
||||
PTR_LA k1, __r4k_wait
|
||||
ori k0, 0x1f /* 32 byte rollback region */
|
||||
xori k0, 0x1f
|
||||
/* Subtract/add 2 to let the ISA bit propagate through the mask. */
|
||||
PTR_LA k1, r4k_wait_insn - 2
|
||||
ori k0, r4k_wait_idle_size - 2
|
||||
.set noreorder
|
||||
bne k0, k1, \handler
|
||||
PTR_ADDIU k0, r4k_wait_exit - r4k_wait_insn + 2
|
||||
.set reorder
|
||||
MTC0 k0, CP0_EPC
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
.align 5
|
||||
BUILD_ROLLBACK_PROLOGUE handle_int
|
||||
BUILD_SKIPOVER_PROLOGUE handle_int
|
||||
NESTED(handle_int, PT_SIZE, sp)
|
||||
.cfi_signal_frame
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
|
|
@ -265,7 +276,7 @@ NESTED(except_vec_ejtag_debug, 0, sp)
|
|||
* This prototype is copied to ebase + n*IntCtl.VS and patched
|
||||
* to invoke the handler
|
||||
*/
|
||||
BUILD_ROLLBACK_PROLOGUE except_vec_vi
|
||||
BUILD_SKIPOVER_PROLOGUE except_vec_vi
|
||||
NESTED(except_vec_vi, 0, sp)
|
||||
SAVE_SOME docfi=1
|
||||
SAVE_AT docfi=1
|
||||
|
|
|
|||
|
|
@ -35,13 +35,6 @@ static void __cpuidle r3081_wait(void)
|
|||
write_c0_conf(cfg | R30XX_CONF_HALT);
|
||||
}
|
||||
|
||||
void __cpuidle r4k_wait(void)
|
||||
{
|
||||
raw_local_irq_enable();
|
||||
__r4k_wait();
|
||||
raw_local_irq_disable();
|
||||
}
|
||||
|
||||
/*
|
||||
* This variant is preferable as it allows testing need_resched and going to
|
||||
* sleep depending on the outcome atomically. Unfortunately the "It is
|
||||
|
|
|
|||
|
|
@ -332,6 +332,8 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
|
|||
mips_cps_cluster_bootcfg = kcalloc(nclusters,
|
||||
sizeof(*mips_cps_cluster_bootcfg),
|
||||
GFP_KERNEL);
|
||||
if (!mips_cps_cluster_bootcfg)
|
||||
goto err_out;
|
||||
|
||||
if (nclusters > 1)
|
||||
mips_cm_update_property();
|
||||
|
|
@ -348,6 +350,8 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
|
|||
mips_cps_cluster_bootcfg[cl].core_power =
|
||||
kcalloc(BITS_TO_LONGS(ncores), sizeof(unsigned long),
|
||||
GFP_KERNEL);
|
||||
if (!mips_cps_cluster_bootcfg[cl].core_power)
|
||||
goto err_out;
|
||||
|
||||
/* Allocate VPE boot configuration structs */
|
||||
for (c = 0; c < ncores; c++) {
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@
|
|||
#include "access-helper.h"
|
||||
|
||||
extern void check_wait(void);
|
||||
extern asmlinkage void rollback_handle_int(void);
|
||||
extern asmlinkage void skipover_handle_int(void);
|
||||
extern asmlinkage void handle_int(void);
|
||||
extern asmlinkage void handle_adel(void);
|
||||
extern asmlinkage void handle_ades(void);
|
||||
|
|
@ -2066,7 +2066,7 @@ void *set_vi_handler(int n, vi_handler_t addr)
|
|||
{
|
||||
extern const u8 except_vec_vi[];
|
||||
extern const u8 except_vec_vi_ori[], except_vec_vi_end[];
|
||||
extern const u8 rollback_except_vec_vi[];
|
||||
extern const u8 skipover_except_vec_vi[];
|
||||
unsigned long handler;
|
||||
unsigned long old_handler = vi_handlers[n];
|
||||
int srssets = current_cpu_data.srsets;
|
||||
|
|
@ -2095,7 +2095,7 @@ void *set_vi_handler(int n, vi_handler_t addr)
|
|||
change_c0_srsmap(0xf << n*4, 0 << n*4);
|
||||
}
|
||||
|
||||
vec_start = using_rollback_handler() ? rollback_except_vec_vi :
|
||||
vec_start = using_skipover_handler() ? skipover_except_vec_vi :
|
||||
except_vec_vi;
|
||||
#if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_BIG_ENDIAN)
|
||||
ori_offset = except_vec_vi_ori - vec_start + 2;
|
||||
|
|
@ -2426,8 +2426,8 @@ void __init trap_init(void)
|
|||
if (board_be_init)
|
||||
board_be_init();
|
||||
|
||||
set_except_vector(EXCCODE_INT, using_rollback_handler() ?
|
||||
rollback_handle_int : handle_int);
|
||||
set_except_vector(EXCCODE_INT, using_skipover_handler() ?
|
||||
skipover_handle_int : handle_int);
|
||||
set_except_vector(EXCCODE_MOD, handle_tlbm);
|
||||
set_except_vector(EXCCODE_TLBL, handle_tlbl);
|
||||
set_except_vector(EXCCODE_TLBS, handle_tlbs);
|
||||
|
|
|
|||
|
|
@ -341,7 +341,7 @@
|
|||
1024 1024 1024 1024>;
|
||||
snps,priority = <0 1 2 3 4 5 6 7>;
|
||||
snps,dma-masters = <2>;
|
||||
snps,data-width = <4>;
|
||||
snps,data-width = <2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -275,6 +275,9 @@ long set_tagged_addr_ctrl(struct task_struct *task, unsigned long arg)
|
|||
unsigned long pmm;
|
||||
u8 pmlen;
|
||||
|
||||
if (!riscv_has_extension_unlikely(RISCV_ISA_EXT_SUPM))
|
||||
return -EINVAL;
|
||||
|
||||
if (is_compat_thread(ti))
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -330,6 +333,9 @@ long get_tagged_addr_ctrl(struct task_struct *task)
|
|||
struct thread_info *ti = task_thread_info(task);
|
||||
long ret = 0;
|
||||
|
||||
if (!riscv_has_extension_unlikely(RISCV_ISA_EXT_SUPM))
|
||||
return -EINVAL;
|
||||
|
||||
if (is_compat_thread(ti))
|
||||
return -EINVAL;
|
||||
|
||||
|
|
|
|||
|
|
@ -198,47 +198,57 @@ asmlinkage __visible __trap_section void do_trap_insn_illegal(struct pt_regs *re
|
|||
DO_ERROR_INFO(do_trap_load_fault,
|
||||
SIGSEGV, SEGV_ACCERR, "load access fault");
|
||||
|
||||
asmlinkage __visible __trap_section void do_trap_load_misaligned(struct pt_regs *regs)
|
||||
enum misaligned_access_type {
|
||||
MISALIGNED_STORE,
|
||||
MISALIGNED_LOAD,
|
||||
};
|
||||
static const struct {
|
||||
const char *type_str;
|
||||
int (*handler)(struct pt_regs *regs);
|
||||
} misaligned_handler[] = {
|
||||
[MISALIGNED_STORE] = {
|
||||
.type_str = "Oops - store (or AMO) address misaligned",
|
||||
.handler = handle_misaligned_store,
|
||||
},
|
||||
[MISALIGNED_LOAD] = {
|
||||
.type_str = "Oops - load address misaligned",
|
||||
.handler = handle_misaligned_load,
|
||||
},
|
||||
};
|
||||
|
||||
static void do_trap_misaligned(struct pt_regs *regs, enum misaligned_access_type type)
|
||||
{
|
||||
irqentry_state_t state;
|
||||
|
||||
if (user_mode(regs)) {
|
||||
irqentry_enter_from_user_mode(regs);
|
||||
local_irq_enable();
|
||||
} else {
|
||||
state = irqentry_nmi_enter(regs);
|
||||
}
|
||||
|
||||
if (handle_misaligned_load(regs))
|
||||
do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
|
||||
"Oops - load address misaligned");
|
||||
if (misaligned_handler[type].handler(regs))
|
||||
do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
|
||||
misaligned_handler[type].type_str);
|
||||
|
||||
if (user_mode(regs)) {
|
||||
local_irq_disable();
|
||||
irqentry_exit_to_user_mode(regs);
|
||||
} else {
|
||||
irqentry_state_t state = irqentry_nmi_enter(regs);
|
||||
|
||||
if (handle_misaligned_load(regs))
|
||||
do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
|
||||
"Oops - load address misaligned");
|
||||
|
||||
irqentry_nmi_exit(regs, state);
|
||||
}
|
||||
}
|
||||
|
||||
asmlinkage __visible __trap_section void do_trap_load_misaligned(struct pt_regs *regs)
|
||||
{
|
||||
do_trap_misaligned(regs, MISALIGNED_LOAD);
|
||||
}
|
||||
|
||||
asmlinkage __visible __trap_section void do_trap_store_misaligned(struct pt_regs *regs)
|
||||
{
|
||||
if (user_mode(regs)) {
|
||||
irqentry_enter_from_user_mode(regs);
|
||||
|
||||
if (handle_misaligned_store(regs))
|
||||
do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
|
||||
"Oops - store (or AMO) address misaligned");
|
||||
|
||||
irqentry_exit_to_user_mode(regs);
|
||||
} else {
|
||||
irqentry_state_t state = irqentry_nmi_enter(regs);
|
||||
|
||||
if (handle_misaligned_store(regs))
|
||||
do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
|
||||
"Oops - store (or AMO) address misaligned");
|
||||
|
||||
irqentry_nmi_exit(regs, state);
|
||||
}
|
||||
do_trap_misaligned(regs, MISALIGNED_STORE);
|
||||
}
|
||||
|
||||
DO_ERROR_INFO(do_trap_store_fault,
|
||||
SIGSEGV, SEGV_ACCERR, "store (or AMO) access fault");
|
||||
DO_ERROR_INFO(do_trap_ecall_s,
|
||||
|
|
|
|||
|
|
@ -88,6 +88,13 @@
|
|||
#define INSN_MATCH_C_FSWSP 0xe002
|
||||
#define INSN_MASK_C_FSWSP 0xe003
|
||||
|
||||
#define INSN_MATCH_C_LHU 0x8400
|
||||
#define INSN_MASK_C_LHU 0xfc43
|
||||
#define INSN_MATCH_C_LH 0x8440
|
||||
#define INSN_MASK_C_LH 0xfc43
|
||||
#define INSN_MATCH_C_SH 0x8c00
|
||||
#define INSN_MASK_C_SH 0xfc43
|
||||
|
||||
#define INSN_LEN(insn) ((((insn) & 0x3) < 0x3) ? 2 : 4)
|
||||
|
||||
#if defined(CONFIG_64BIT)
|
||||
|
|
@ -268,7 +275,7 @@ static unsigned long get_f32_rs(unsigned long insn, u8 fp_reg_offset,
|
|||
int __ret; \
|
||||
\
|
||||
if (user_mode(regs)) { \
|
||||
__ret = __get_user(insn, (type __user *) insn_addr); \
|
||||
__ret = get_user(insn, (type __user *) insn_addr); \
|
||||
} else { \
|
||||
insn = *(type *)insn_addr; \
|
||||
__ret = 0; \
|
||||
|
|
@ -431,6 +438,13 @@ static int handle_scalar_misaligned_load(struct pt_regs *regs)
|
|||
fp = 1;
|
||||
len = 4;
|
||||
#endif
|
||||
} else if ((insn & INSN_MASK_C_LHU) == INSN_MATCH_C_LHU) {
|
||||
len = 2;
|
||||
insn = RVC_RS2S(insn) << SH_RD;
|
||||
} else if ((insn & INSN_MASK_C_LH) == INSN_MATCH_C_LH) {
|
||||
len = 2;
|
||||
shift = 8 * (sizeof(ulong) - len);
|
||||
insn = RVC_RS2S(insn) << SH_RD;
|
||||
} else {
|
||||
regs->epc = epc;
|
||||
return -1;
|
||||
|
|
@ -530,6 +544,9 @@ static int handle_scalar_misaligned_store(struct pt_regs *regs)
|
|||
len = 4;
|
||||
val.data_ulong = GET_F32_RS2C(insn, regs);
|
||||
#endif
|
||||
} else if ((insn & INSN_MASK_C_SH) == INSN_MATCH_C_SH) {
|
||||
len = 2;
|
||||
val.data_ulong = GET_RS2S(insn, regs);
|
||||
} else {
|
||||
regs->epc = epc;
|
||||
return -1;
|
||||
|
|
|
|||
|
|
@ -77,6 +77,8 @@ static void kvm_riscv_reset_vcpu(struct kvm_vcpu *vcpu)
|
|||
memcpy(cntx, reset_cntx, sizeof(*cntx));
|
||||
spin_unlock(&vcpu->arch.reset_cntx_lock);
|
||||
|
||||
memset(&vcpu->arch.smstateen_csr, 0, sizeof(vcpu->arch.smstateen_csr));
|
||||
|
||||
kvm_riscv_vcpu_fp_reset(vcpu);
|
||||
|
||||
kvm_riscv_vcpu_vector_reset(vcpu);
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ CONFIG_USER_NS=y
|
|||
CONFIG_CHECKPOINT_RESTORE=y
|
||||
CONFIG_SCHED_AUTOGROUP=y
|
||||
CONFIG_EXPERT=y
|
||||
# CONFIG_SYSFS_SYSCALL is not set
|
||||
CONFIG_PROFILING=y
|
||||
CONFIG_KEXEC=y
|
||||
CONFIG_KEXEC_FILE=y
|
||||
|
|
@ -92,7 +91,6 @@ CONFIG_UNIXWARE_DISKLABEL=y
|
|||
CONFIG_IOSCHED_BFQ=y
|
||||
CONFIG_BINFMT_MISC=m
|
||||
CONFIG_ZSWAP=y
|
||||
CONFIG_ZSMALLOC=y
|
||||
CONFIG_ZSMALLOC_STAT=y
|
||||
CONFIG_SLAB_BUCKETS=y
|
||||
CONFIG_SLUB_STATS=y
|
||||
|
|
@ -395,6 +393,9 @@ CONFIG_CLS_U32_MARK=y
|
|||
CONFIG_NET_CLS_FLOW=m
|
||||
CONFIG_NET_CLS_CGROUP=y
|
||||
CONFIG_NET_CLS_BPF=m
|
||||
CONFIG_NET_CLS_FLOWER=m
|
||||
CONFIG_NET_CLS_MATCHALL=m
|
||||
CONFIG_NET_EMATCH=y
|
||||
CONFIG_NET_CLS_ACT=y
|
||||
CONFIG_NET_ACT_POLICE=m
|
||||
CONFIG_NET_ACT_GACT=m
|
||||
|
|
@ -405,6 +406,9 @@ CONFIG_NET_ACT_PEDIT=m
|
|||
CONFIG_NET_ACT_SIMP=m
|
||||
CONFIG_NET_ACT_SKBEDIT=m
|
||||
CONFIG_NET_ACT_CSUM=m
|
||||
CONFIG_NET_ACT_VLAN=m
|
||||
CONFIG_NET_ACT_TUNNEL_KEY=m
|
||||
CONFIG_NET_ACT_CT=m
|
||||
CONFIG_NET_ACT_GATE=m
|
||||
CONFIG_NET_TC_SKB_EXT=y
|
||||
CONFIG_DNS_RESOLVER=y
|
||||
|
|
@ -628,8 +632,16 @@ CONFIG_VIRTIO_PCI=m
|
|||
CONFIG_VIRTIO_BALLOON=m
|
||||
CONFIG_VIRTIO_MEM=m
|
||||
CONFIG_VIRTIO_INPUT=y
|
||||
CONFIG_VDPA=m
|
||||
CONFIG_VDPA_SIM=m
|
||||
CONFIG_VDPA_SIM_NET=m
|
||||
CONFIG_VDPA_SIM_BLOCK=m
|
||||
CONFIG_VDPA_USER=m
|
||||
CONFIG_MLX5_VDPA_NET=m
|
||||
CONFIG_VP_VDPA=m
|
||||
CONFIG_VHOST_NET=m
|
||||
CONFIG_VHOST_VSOCK=m
|
||||
CONFIG_VHOST_VDPA=m
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
|
|
@ -654,7 +666,6 @@ CONFIG_NILFS2_FS=m
|
|||
CONFIG_BCACHEFS_FS=y
|
||||
CONFIG_BCACHEFS_QUOTA=y
|
||||
CONFIG_BCACHEFS_POSIX_ACL=y
|
||||
CONFIG_FS_DAX=y
|
||||
CONFIG_EXPORTFS_BLOCK_OPS=y
|
||||
CONFIG_FS_ENCRYPTION=y
|
||||
CONFIG_FS_VERITY=y
|
||||
|
|
@ -724,11 +735,10 @@ CONFIG_NLS_UTF8=m
|
|||
CONFIG_DLM=m
|
||||
CONFIG_UNICODE=y
|
||||
CONFIG_PERSISTENT_KEYRINGS=y
|
||||
CONFIG_BIG_KEYS=y
|
||||
CONFIG_ENCRYPTED_KEYS=m
|
||||
CONFIG_KEY_NOTIFICATIONS=y
|
||||
CONFIG_SECURITY=y
|
||||
CONFIG_HARDENED_USERCOPY=y
|
||||
CONFIG_FORTIFY_SOURCE=y
|
||||
CONFIG_SECURITY_SELINUX=y
|
||||
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
|
||||
CONFIG_SECURITY_LOCKDOWN_LSM=y
|
||||
|
|
@ -741,6 +751,8 @@ CONFIG_IMA=y
|
|||
CONFIG_IMA_DEFAULT_HASH_SHA256=y
|
||||
CONFIG_IMA_WRITE_POLICY=y
|
||||
CONFIG_IMA_APPRAISE=y
|
||||
CONFIG_FORTIFY_SOURCE=y
|
||||
CONFIG_HARDENED_USERCOPY=y
|
||||
CONFIG_BUG_ON_DATA_CORRUPTION=y
|
||||
CONFIG_CRYPTO_USER=m
|
||||
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
|
||||
|
|
@ -756,7 +768,6 @@ CONFIG_CRYPTO_AES_TI=m
|
|||
CONFIG_CRYPTO_ANUBIS=m
|
||||
CONFIG_CRYPTO_ARIA=m
|
||||
CONFIG_CRYPTO_BLOWFISH=m
|
||||
CONFIG_CRYPTO_CAMELLIA=m
|
||||
CONFIG_CRYPTO_CAST5=m
|
||||
CONFIG_CRYPTO_CAST6=m
|
||||
CONFIG_CRYPTO_DES=m
|
||||
|
|
@ -801,7 +812,6 @@ CONFIG_CRYPTO_SHA3_512_S390=m
|
|||
CONFIG_CRYPTO_GHASH_S390=m
|
||||
CONFIG_CRYPTO_AES_S390=m
|
||||
CONFIG_CRYPTO_DES_S390=m
|
||||
CONFIG_CRYPTO_CHACHA_S390=m
|
||||
CONFIG_CRYPTO_HMAC_S390=m
|
||||
CONFIG_ZCRYPT=m
|
||||
CONFIG_PKEY=m
|
||||
|
|
@ -812,9 +822,9 @@ CONFIG_PKEY_UV=m
|
|||
CONFIG_CRYPTO_PAES_S390=m
|
||||
CONFIG_CRYPTO_DEV_VIRTIO=m
|
||||
CONFIG_SYSTEM_BLACKLIST_KEYRING=y
|
||||
CONFIG_CRYPTO_KRB5=m
|
||||
CONFIG_CRYPTO_KRB5_SELFTESTS=y
|
||||
CONFIG_CORDIC=m
|
||||
CONFIG_CRYPTO_LIB_CURVE25519=m
|
||||
CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m
|
||||
CONFIG_RANDOM32_SELFTEST=y
|
||||
CONFIG_XZ_DEC_MICROLZMA=y
|
||||
CONFIG_DMA_CMA=y
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ CONFIG_USER_NS=y
|
|||
CONFIG_CHECKPOINT_RESTORE=y
|
||||
CONFIG_SCHED_AUTOGROUP=y
|
||||
CONFIG_EXPERT=y
|
||||
# CONFIG_SYSFS_SYSCALL is not set
|
||||
CONFIG_PROFILING=y
|
||||
CONFIG_KEXEC=y
|
||||
CONFIG_KEXEC_FILE=y
|
||||
|
|
@ -86,7 +85,6 @@ CONFIG_UNIXWARE_DISKLABEL=y
|
|||
CONFIG_IOSCHED_BFQ=y
|
||||
CONFIG_BINFMT_MISC=m
|
||||
CONFIG_ZSWAP=y
|
||||
CONFIG_ZSMALLOC=y
|
||||
CONFIG_ZSMALLOC_STAT=y
|
||||
CONFIG_SLAB_BUCKETS=y
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
|
|
@ -385,6 +383,9 @@ CONFIG_CLS_U32_MARK=y
|
|||
CONFIG_NET_CLS_FLOW=m
|
||||
CONFIG_NET_CLS_CGROUP=y
|
||||
CONFIG_NET_CLS_BPF=m
|
||||
CONFIG_NET_CLS_FLOWER=m
|
||||
CONFIG_NET_CLS_MATCHALL=m
|
||||
CONFIG_NET_EMATCH=y
|
||||
CONFIG_NET_CLS_ACT=y
|
||||
CONFIG_NET_ACT_POLICE=m
|
||||
CONFIG_NET_ACT_GACT=m
|
||||
|
|
@ -395,6 +396,9 @@ CONFIG_NET_ACT_PEDIT=m
|
|||
CONFIG_NET_ACT_SIMP=m
|
||||
CONFIG_NET_ACT_SKBEDIT=m
|
||||
CONFIG_NET_ACT_CSUM=m
|
||||
CONFIG_NET_ACT_VLAN=m
|
||||
CONFIG_NET_ACT_TUNNEL_KEY=m
|
||||
CONFIG_NET_ACT_CT=m
|
||||
CONFIG_NET_ACT_GATE=m
|
||||
CONFIG_NET_TC_SKB_EXT=y
|
||||
CONFIG_DNS_RESOLVER=y
|
||||
|
|
@ -618,8 +622,16 @@ CONFIG_VIRTIO_PCI=m
|
|||
CONFIG_VIRTIO_BALLOON=m
|
||||
CONFIG_VIRTIO_MEM=m
|
||||
CONFIG_VIRTIO_INPUT=y
|
||||
CONFIG_VDPA=m
|
||||
CONFIG_VDPA_SIM=m
|
||||
CONFIG_VDPA_SIM_NET=m
|
||||
CONFIG_VDPA_SIM_BLOCK=m
|
||||
CONFIG_VDPA_USER=m
|
||||
CONFIG_MLX5_VDPA_NET=m
|
||||
CONFIG_VP_VDPA=m
|
||||
CONFIG_VHOST_NET=m
|
||||
CONFIG_VHOST_VSOCK=m
|
||||
CONFIG_VHOST_VDPA=m
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
|
|
@ -641,7 +653,6 @@ CONFIG_NILFS2_FS=m
|
|||
CONFIG_BCACHEFS_FS=m
|
||||
CONFIG_BCACHEFS_QUOTA=y
|
||||
CONFIG_BCACHEFS_POSIX_ACL=y
|
||||
CONFIG_FS_DAX=y
|
||||
CONFIG_EXPORTFS_BLOCK_OPS=y
|
||||
CONFIG_FS_ENCRYPTION=y
|
||||
CONFIG_FS_VERITY=y
|
||||
|
|
@ -711,6 +722,7 @@ CONFIG_NLS_UTF8=m
|
|||
CONFIG_DLM=m
|
||||
CONFIG_UNICODE=y
|
||||
CONFIG_PERSISTENT_KEYRINGS=y
|
||||
CONFIG_BIG_KEYS=y
|
||||
CONFIG_ENCRYPTED_KEYS=m
|
||||
CONFIG_KEY_NOTIFICATIONS=y
|
||||
CONFIG_SECURITY=y
|
||||
|
|
@ -742,7 +754,6 @@ CONFIG_CRYPTO_AES_TI=m
|
|||
CONFIG_CRYPTO_ANUBIS=m
|
||||
CONFIG_CRYPTO_ARIA=m
|
||||
CONFIG_CRYPTO_BLOWFISH=m
|
||||
CONFIG_CRYPTO_CAMELLIA=m
|
||||
CONFIG_CRYPTO_CAST5=m
|
||||
CONFIG_CRYPTO_CAST6=m
|
||||
CONFIG_CRYPTO_DES=m
|
||||
|
|
@ -788,7 +799,6 @@ CONFIG_CRYPTO_SHA3_512_S390=m
|
|||
CONFIG_CRYPTO_GHASH_S390=m
|
||||
CONFIG_CRYPTO_AES_S390=m
|
||||
CONFIG_CRYPTO_DES_S390=m
|
||||
CONFIG_CRYPTO_CHACHA_S390=m
|
||||
CONFIG_CRYPTO_HMAC_S390=m
|
||||
CONFIG_ZCRYPT=m
|
||||
CONFIG_PKEY=m
|
||||
|
|
@ -799,10 +809,10 @@ CONFIG_PKEY_UV=m
|
|||
CONFIG_CRYPTO_PAES_S390=m
|
||||
CONFIG_CRYPTO_DEV_VIRTIO=m
|
||||
CONFIG_SYSTEM_BLACKLIST_KEYRING=y
|
||||
CONFIG_CRYPTO_KRB5=m
|
||||
CONFIG_CRYPTO_KRB5_SELFTESTS=y
|
||||
CONFIG_CORDIC=m
|
||||
CONFIG_PRIME_NUMBERS=m
|
||||
CONFIG_CRYPTO_LIB_CURVE25519=m
|
||||
CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m
|
||||
CONFIG_XZ_DEC_MICROLZMA=y
|
||||
CONFIG_DMA_CMA=y
|
||||
CONFIG_CMA_SIZE_MBYTES=0
|
||||
|
|
|
|||
|
|
@ -70,7 +70,6 @@ CONFIG_DEBUG_KERNEL=y
|
|||
CONFIG_DEBUG_INFO_DWARF4=y
|
||||
CONFIG_DEBUG_FS=y
|
||||
CONFIG_PANIC_ON_OOPS=y
|
||||
# CONFIG_SCHED_DEBUG is not set
|
||||
CONFIG_RCU_CPU_STALL_TIMEOUT=60
|
||||
# CONFIG_RCU_TRACE is not set
|
||||
# CONFIG_FTRACE is not set
|
||||
|
|
|
|||
|
|
@ -602,7 +602,8 @@ SYM_CODE_START(stack_invalid)
|
|||
stmg %r0,%r7,__PT_R0(%r11)
|
||||
stmg %r8,%r9,__PT_PSW(%r11)
|
||||
mvc __PT_R8(64,%r11),0(%r14)
|
||||
stg %r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2
|
||||
GET_LC %r2
|
||||
mvc __PT_ORIG_GPR2(8,%r11),__LC_PGM_LAST_BREAK(%r2)
|
||||
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
|
||||
lgr %r2,%r11 # pass pointer to pt_regs
|
||||
jg kernel_stack_invalid
|
||||
|
|
|
|||
|
|
@ -428,6 +428,8 @@ static void __clp_add(struct clp_fh_list_entry *entry, void *data)
|
|||
return;
|
||||
}
|
||||
zdev = zpci_create_device(entry->fid, entry->fh, entry->config_state);
|
||||
if (IS_ERR(zdev))
|
||||
return;
|
||||
list_add_tail(&zdev->entry, scan_list);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -154,5 +154,6 @@ MRPROPER_FILES += $(HOST_DIR)/include/generated
|
|||
archclean:
|
||||
@find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
|
||||
-o -name '*.gcov' \) -type f -print | xargs rm -f
|
||||
$(Q)$(MAKE) -f $(srctree)/Makefile ARCH=$(HEADER_ARCH) clean
|
||||
|
||||
export HEADER_ARCH SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING DEV_NULL_PATH
|
||||
|
|
|
|||
|
|
@ -2368,6 +2368,7 @@ config STRICT_SIGALTSTACK_SIZE
|
|||
config CFI_AUTO_DEFAULT
|
||||
bool "Attempt to use FineIBT by default at boot time"
|
||||
depends on FINEIBT
|
||||
depends on !RUST || RUSTC_VERSION >= 108800
|
||||
default y
|
||||
help
|
||||
Attempt to use FineIBT by default at boot time. If enabled,
|
||||
|
|
@ -2710,6 +2711,18 @@ config MITIGATION_SSB
|
|||
of speculative execution in a similar way to the Meltdown and Spectre
|
||||
security vulnerabilities.
|
||||
|
||||
config MITIGATION_ITS
|
||||
bool "Enable Indirect Target Selection mitigation"
|
||||
depends on CPU_SUP_INTEL && X86_64
|
||||
depends on MITIGATION_RETPOLINE && MITIGATION_RETHUNK
|
||||
select EXECMEM
|
||||
default y
|
||||
help
|
||||
Enable Indirect Target Selection (ITS) mitigation. ITS is a bug in
|
||||
BPU on some Intel CPUs that may allow Spectre V2 style attacks. If
|
||||
disabled, mitigation cannot be enabled via cmdline.
|
||||
See <file:Documentation/admin-guide/hw-vuln/indirect-target-selection.rst>
|
||||
|
||||
endif
|
||||
|
||||
config ARCH_HAS_ADD_PAGES
|
||||
|
|
|
|||
|
|
@ -959,6 +959,102 @@ void snp_accept_memory(phys_addr_t start, phys_addr_t end)
|
|||
set_pages_state(vaddr, npages, SNP_PAGE_STATE_PRIVATE);
|
||||
}
|
||||
|
||||
static int vmgexit_ap_control(u64 event, struct sev_es_save_area *vmsa, u32 apic_id)
|
||||
{
|
||||
bool create = event != SVM_VMGEXIT_AP_DESTROY;
|
||||
struct ghcb_state state;
|
||||
unsigned long flags;
|
||||
struct ghcb *ghcb;
|
||||
int ret = 0;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
ghcb = __sev_get_ghcb(&state);
|
||||
|
||||
vc_ghcb_invalidate(ghcb);
|
||||
|
||||
if (create)
|
||||
ghcb_set_rax(ghcb, vmsa->sev_features);
|
||||
|
||||
ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_AP_CREATION);
|
||||
ghcb_set_sw_exit_info_1(ghcb,
|
||||
((u64)apic_id << 32) |
|
||||
((u64)snp_vmpl << 16) |
|
||||
event);
|
||||
ghcb_set_sw_exit_info_2(ghcb, __pa(vmsa));
|
||||
|
||||
sev_es_wr_ghcb_msr(__pa(ghcb));
|
||||
VMGEXIT();
|
||||
|
||||
if (!ghcb_sw_exit_info_1_is_valid(ghcb) ||
|
||||
lower_32_bits(ghcb->save.sw_exit_info_1)) {
|
||||
pr_err("SNP AP %s error\n", (create ? "CREATE" : "DESTROY"));
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
__sev_put_ghcb(&state);
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int snp_set_vmsa(void *va, void *caa, int apic_id, bool make_vmsa)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (snp_vmpl) {
|
||||
struct svsm_call call = {};
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
call.caa = this_cpu_read(svsm_caa);
|
||||
call.rcx = __pa(va);
|
||||
|
||||
if (make_vmsa) {
|
||||
/* Protocol 0, Call ID 2 */
|
||||
call.rax = SVSM_CORE_CALL(SVSM_CORE_CREATE_VCPU);
|
||||
call.rdx = __pa(caa);
|
||||
call.r8 = apic_id;
|
||||
} else {
|
||||
/* Protocol 0, Call ID 3 */
|
||||
call.rax = SVSM_CORE_CALL(SVSM_CORE_DELETE_VCPU);
|
||||
}
|
||||
|
||||
ret = svsm_perform_call_protocol(&call);
|
||||
|
||||
local_irq_restore(flags);
|
||||
} else {
|
||||
/*
|
||||
* If the kernel runs at VMPL0, it can change the VMSA
|
||||
* bit for a page using the RMPADJUST instruction.
|
||||
* However, for the instruction to succeed it must
|
||||
* target the permissions of a lesser privileged (higher
|
||||
* numbered) VMPL level, so use VMPL1.
|
||||
*/
|
||||
u64 attrs = 1;
|
||||
|
||||
if (make_vmsa)
|
||||
attrs |= RMPADJUST_VMSA_PAGE_BIT;
|
||||
|
||||
ret = rmpadjust((unsigned long)va, RMP_PG_SIZE_4K, attrs);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void snp_cleanup_vmsa(struct sev_es_save_area *vmsa, int apic_id)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = snp_set_vmsa(vmsa, NULL, apic_id, false);
|
||||
if (err)
|
||||
pr_err("clear VMSA page failed (%u), leaking page\n", err);
|
||||
else
|
||||
free_page((unsigned long)vmsa);
|
||||
}
|
||||
|
||||
static void set_pte_enc(pte_t *kpte, int level, void *va)
|
||||
{
|
||||
struct pte_enc_desc d = {
|
||||
|
|
@ -1005,7 +1101,8 @@ static void unshare_all_memory(void)
|
|||
data = per_cpu(runtime_data, cpu);
|
||||
ghcb = (unsigned long)&data->ghcb_page;
|
||||
|
||||
if (addr <= ghcb && ghcb <= addr + size) {
|
||||
/* Handle the case of a huge page containing the GHCB page */
|
||||
if (addr <= ghcb && ghcb < addr + size) {
|
||||
skipped_addr = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1055,11 +1152,70 @@ void snp_kexec_begin(void)
|
|||
pr_warn("Failed to stop shared<->private conversions\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Shutdown all APs except the one handling kexec/kdump and clearing
|
||||
* the VMSA tag on AP's VMSA pages as they are not being used as
|
||||
* VMSA page anymore.
|
||||
*/
|
||||
static void shutdown_all_aps(void)
|
||||
{
|
||||
struct sev_es_save_area *vmsa;
|
||||
int apic_id, this_cpu, cpu;
|
||||
|
||||
this_cpu = get_cpu();
|
||||
|
||||
/*
|
||||
* APs are already in HLT loop when enc_kexec_finish() callback
|
||||
* is invoked.
|
||||
*/
|
||||
for_each_present_cpu(cpu) {
|
||||
vmsa = per_cpu(sev_vmsa, cpu);
|
||||
|
||||
/*
|
||||
* The BSP or offlined APs do not have guest allocated VMSA
|
||||
* and there is no need to clear the VMSA tag for this page.
|
||||
*/
|
||||
if (!vmsa)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Cannot clear the VMSA tag for the currently running vCPU.
|
||||
*/
|
||||
if (this_cpu == cpu) {
|
||||
unsigned long pa;
|
||||
struct page *p;
|
||||
|
||||
pa = __pa(vmsa);
|
||||
/*
|
||||
* Mark the VMSA page of the running vCPU as offline
|
||||
* so that is excluded and not touched by makedumpfile
|
||||
* while generating vmcore during kdump.
|
||||
*/
|
||||
p = pfn_to_online_page(pa >> PAGE_SHIFT);
|
||||
if (p)
|
||||
__SetPageOffline(p);
|
||||
continue;
|
||||
}
|
||||
|
||||
apic_id = cpuid_to_apicid[cpu];
|
||||
|
||||
/*
|
||||
* Issue AP destroy to ensure AP gets kicked out of guest mode
|
||||
* to allow using RMPADJUST to remove the VMSA tag on it's
|
||||
* VMSA page.
|
||||
*/
|
||||
vmgexit_ap_control(SVM_VMGEXIT_AP_DESTROY, vmsa, apic_id);
|
||||
snp_cleanup_vmsa(vmsa, apic_id);
|
||||
}
|
||||
|
||||
put_cpu();
|
||||
}
|
||||
|
||||
void snp_kexec_finish(void)
|
||||
{
|
||||
struct sev_es_runtime_data *data;
|
||||
unsigned long size, addr;
|
||||
unsigned int level, cpu;
|
||||
unsigned long size;
|
||||
struct ghcb *ghcb;
|
||||
pte_t *pte;
|
||||
|
||||
|
|
@ -1069,6 +1225,8 @@ void snp_kexec_finish(void)
|
|||
if (!IS_ENABLED(CONFIG_KEXEC_CORE))
|
||||
return;
|
||||
|
||||
shutdown_all_aps();
|
||||
|
||||
unshare_all_memory();
|
||||
|
||||
/*
|
||||
|
|
@ -1085,56 +1243,13 @@ void snp_kexec_finish(void)
|
|||
ghcb = &data->ghcb_page;
|
||||
pte = lookup_address((unsigned long)ghcb, &level);
|
||||
size = page_level_size(level);
|
||||
set_pte_enc(pte, level, (void *)ghcb);
|
||||
snp_set_memory_private((unsigned long)ghcb, (size / PAGE_SIZE));
|
||||
/* Handle the case of a huge page containing the GHCB page */
|
||||
addr = (unsigned long)ghcb & page_level_mask(level);
|
||||
set_pte_enc(pte, level, (void *)addr);
|
||||
snp_set_memory_private(addr, (size / PAGE_SIZE));
|
||||
}
|
||||
}
|
||||
|
||||
static int snp_set_vmsa(void *va, void *caa, int apic_id, bool make_vmsa)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (snp_vmpl) {
|
||||
struct svsm_call call = {};
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
call.caa = this_cpu_read(svsm_caa);
|
||||
call.rcx = __pa(va);
|
||||
|
||||
if (make_vmsa) {
|
||||
/* Protocol 0, Call ID 2 */
|
||||
call.rax = SVSM_CORE_CALL(SVSM_CORE_CREATE_VCPU);
|
||||
call.rdx = __pa(caa);
|
||||
call.r8 = apic_id;
|
||||
} else {
|
||||
/* Protocol 0, Call ID 3 */
|
||||
call.rax = SVSM_CORE_CALL(SVSM_CORE_DELETE_VCPU);
|
||||
}
|
||||
|
||||
ret = svsm_perform_call_protocol(&call);
|
||||
|
||||
local_irq_restore(flags);
|
||||
} else {
|
||||
/*
|
||||
* If the kernel runs at VMPL0, it can change the VMSA
|
||||
* bit for a page using the RMPADJUST instruction.
|
||||
* However, for the instruction to succeed it must
|
||||
* target the permissions of a lesser privileged (higher
|
||||
* numbered) VMPL level, so use VMPL1.
|
||||
*/
|
||||
u64 attrs = 1;
|
||||
|
||||
if (make_vmsa)
|
||||
attrs |= RMPADJUST_VMSA_PAGE_BIT;
|
||||
|
||||
ret = rmpadjust((unsigned long)va, RMP_PG_SIZE_4K, attrs);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define __ATTR_BASE (SVM_SELECTOR_P_MASK | SVM_SELECTOR_S_MASK)
|
||||
#define INIT_CS_ATTRIBS (__ATTR_BASE | SVM_SELECTOR_READ_MASK | SVM_SELECTOR_CODE_MASK)
|
||||
#define INIT_DS_ATTRIBS (__ATTR_BASE | SVM_SELECTOR_WRITE_MASK)
|
||||
|
|
@ -1166,24 +1281,10 @@ static void *snp_alloc_vmsa_page(int cpu)
|
|||
return page_address(p + 1);
|
||||
}
|
||||
|
||||
static void snp_cleanup_vmsa(struct sev_es_save_area *vmsa, int apic_id)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = snp_set_vmsa(vmsa, NULL, apic_id, false);
|
||||
if (err)
|
||||
pr_err("clear VMSA page failed (%u), leaking page\n", err);
|
||||
else
|
||||
free_page((unsigned long)vmsa);
|
||||
}
|
||||
|
||||
static int wakeup_cpu_via_vmgexit(u32 apic_id, unsigned long start_ip)
|
||||
{
|
||||
struct sev_es_save_area *cur_vmsa, *vmsa;
|
||||
struct ghcb_state state;
|
||||
struct svsm_ca *caa;
|
||||
unsigned long flags;
|
||||
struct ghcb *ghcb;
|
||||
u8 sipi_vector;
|
||||
int cpu, ret;
|
||||
u64 cr4;
|
||||
|
|
@ -1297,33 +1398,7 @@ static int wakeup_cpu_via_vmgexit(u32 apic_id, unsigned long start_ip)
|
|||
}
|
||||
|
||||
/* Issue VMGEXIT AP Creation NAE event */
|
||||
local_irq_save(flags);
|
||||
|
||||
ghcb = __sev_get_ghcb(&state);
|
||||
|
||||
vc_ghcb_invalidate(ghcb);
|
||||
ghcb_set_rax(ghcb, vmsa->sev_features);
|
||||
ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_AP_CREATION);
|
||||
ghcb_set_sw_exit_info_1(ghcb,
|
||||
((u64)apic_id << 32) |
|
||||
((u64)snp_vmpl << 16) |
|
||||
SVM_VMGEXIT_AP_CREATE);
|
||||
ghcb_set_sw_exit_info_2(ghcb, __pa(vmsa));
|
||||
|
||||
sev_es_wr_ghcb_msr(__pa(ghcb));
|
||||
VMGEXIT();
|
||||
|
||||
if (!ghcb_sw_exit_info_1_is_valid(ghcb) ||
|
||||
lower_32_bits(ghcb->save.sw_exit_info_1)) {
|
||||
pr_err("SNP AP Creation error\n");
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
__sev_put_ghcb(&state);
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
/* Perform cleanup if there was an error */
|
||||
ret = vmgexit_ap_control(SVM_VMGEXIT_AP_CREATE, vmsa, apic_id);
|
||||
if (ret) {
|
||||
snp_cleanup_vmsa(vmsa, apic_id);
|
||||
vmsa = NULL;
|
||||
|
|
|
|||
|
|
@ -1525,7 +1525,9 @@ SYM_CODE_END(rewind_stack_and_make_dead)
|
|||
* ORC to unwind properly.
|
||||
*
|
||||
* The alignment is for performance and not for safety, and may be safely
|
||||
* refactored in the future if needed.
|
||||
* refactored in the future if needed. The .skips are for safety, to ensure
|
||||
* that all RETs are in the second half of a cacheline to mitigate Indirect
|
||||
* Target Selection, rather than taking the slowpath via its_return_thunk.
|
||||
*/
|
||||
SYM_FUNC_START(clear_bhb_loop)
|
||||
ANNOTATE_NOENDBR
|
||||
|
|
@ -1536,10 +1538,22 @@ SYM_FUNC_START(clear_bhb_loop)
|
|||
call 1f
|
||||
jmp 5f
|
||||
.align 64, 0xcc
|
||||
/*
|
||||
* Shift instructions so that the RET is in the upper half of the
|
||||
* cacheline and don't take the slowpath to its_return_thunk.
|
||||
*/
|
||||
.skip 32 - (.Lret1 - 1f), 0xcc
|
||||
ANNOTATE_INTRA_FUNCTION_CALL
|
||||
1: call 2f
|
||||
RET
|
||||
.Lret1: RET
|
||||
.align 64, 0xcc
|
||||
/*
|
||||
* As above shift instructions for RET at .Lret2 as well.
|
||||
*
|
||||
* This should be ideally be: .skip 32 - (.Lret2 - 2f), 0xcc
|
||||
* but some Clang versions (e.g. 18) don't like this.
|
||||
*/
|
||||
.skip 32 - 18, 0xcc
|
||||
2: movl $5, %eax
|
||||
3: jmp 4f
|
||||
nop
|
||||
|
|
@ -1547,7 +1561,7 @@ SYM_FUNC_START(clear_bhb_loop)
|
|||
jnz 3b
|
||||
sub $1, %ecx
|
||||
jnz 1b
|
||||
RET
|
||||
.Lret2: RET
|
||||
5: lfence
|
||||
pop %rbp
|
||||
RET
|
||||
|
|
|
|||
|
|
@ -2465,8 +2465,9 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs, struct perf_sample_
|
|||
setup_pebs_fixed_sample_data);
|
||||
}
|
||||
|
||||
static void intel_pmu_pebs_event_update_no_drain(struct cpu_hw_events *cpuc, int size)
|
||||
static void intel_pmu_pebs_event_update_no_drain(struct cpu_hw_events *cpuc, u64 mask)
|
||||
{
|
||||
u64 pebs_enabled = cpuc->pebs_enabled & mask;
|
||||
struct perf_event *event;
|
||||
int bit;
|
||||
|
||||
|
|
@ -2477,7 +2478,7 @@ static void intel_pmu_pebs_event_update_no_drain(struct cpu_hw_events *cpuc, int
|
|||
* It needs to call intel_pmu_save_and_restart_reload() to
|
||||
* update the event->count for this case.
|
||||
*/
|
||||
for_each_set_bit(bit, (unsigned long *)&cpuc->pebs_enabled, size) {
|
||||
for_each_set_bit(bit, (unsigned long *)&pebs_enabled, X86_PMC_IDX_MAX) {
|
||||
event = cpuc->events[bit];
|
||||
if (event->hw.flags & PERF_X86_EVENT_AUTO_RELOAD)
|
||||
intel_pmu_save_and_restart_reload(event, 0);
|
||||
|
|
@ -2512,7 +2513,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs, struct perf_sample_d
|
|||
}
|
||||
|
||||
if (unlikely(base >= top)) {
|
||||
intel_pmu_pebs_event_update_no_drain(cpuc, size);
|
||||
intel_pmu_pebs_event_update_no_drain(cpuc, mask);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2626,7 +2627,7 @@ static void intel_pmu_drain_pebs_icl(struct pt_regs *iregs, struct perf_sample_d
|
|||
(hybrid(cpuc->pmu, fixed_cntr_mask64) << INTEL_PMC_IDX_FIXED);
|
||||
|
||||
if (unlikely(base >= top)) {
|
||||
intel_pmu_pebs_event_update_no_drain(cpuc, X86_PMC_IDX_MAX);
|
||||
intel_pmu_pebs_event_update_no_drain(cpuc, mask);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include <linux/stringify.h>
|
||||
#include <linux/objtool.h>
|
||||
#include <asm/asm.h>
|
||||
#include <asm/bug.h>
|
||||
|
||||
#define ALT_FLAGS_SHIFT 16
|
||||
|
||||
|
|
@ -124,6 +125,37 @@ static __always_inline int x86_call_depth_emit_accounting(u8 **pprog,
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MITIGATION_ITS
|
||||
extern void its_init_mod(struct module *mod);
|
||||
extern void its_fini_mod(struct module *mod);
|
||||
extern void its_free_mod(struct module *mod);
|
||||
extern u8 *its_static_thunk(int reg);
|
||||
#else /* CONFIG_MITIGATION_ITS */
|
||||
static inline void its_init_mod(struct module *mod) { }
|
||||
static inline void its_fini_mod(struct module *mod) { }
|
||||
static inline void its_free_mod(struct module *mod) { }
|
||||
static inline u8 *its_static_thunk(int reg)
|
||||
{
|
||||
WARN_ONCE(1, "ITS not compiled in");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MITIGATION_RETHUNK) && defined(CONFIG_OBJTOOL)
|
||||
extern bool cpu_wants_rethunk(void);
|
||||
extern bool cpu_wants_rethunk_at(void *addr);
|
||||
#else
|
||||
static __always_inline bool cpu_wants_rethunk(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static __always_inline bool cpu_wants_rethunk_at(void *addr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
extern void alternatives_smp_module_add(struct module *mod, char *name,
|
||||
void *locks, void *locks_end,
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@
|
|||
#define X86_FEATURE_CENTAUR_MCR ( 3*32+ 3) /* "centaur_mcr" Centaur MCRs (= MTRRs) */
|
||||
#define X86_FEATURE_K8 ( 3*32+ 4) /* Opteron, Athlon64 */
|
||||
#define X86_FEATURE_ZEN5 ( 3*32+ 5) /* CPU based on Zen5 microarchitecture */
|
||||
/* Free ( 3*32+ 6) */
|
||||
#define X86_FEATURE_ZEN6 ( 3*32+ 6) /* CPU based on Zen6 microarchitecture */
|
||||
/* Free ( 3*32+ 7) */
|
||||
#define X86_FEATURE_CONSTANT_TSC ( 3*32+ 8) /* "constant_tsc" TSC ticks at a constant rate */
|
||||
#define X86_FEATURE_UP ( 3*32+ 9) /* "up" SMP kernel running on UP */
|
||||
|
|
@ -481,6 +481,7 @@
|
|||
#define X86_FEATURE_AMD_HETEROGENEOUS_CORES (21*32 + 6) /* Heterogeneous Core Topology */
|
||||
#define X86_FEATURE_AMD_WORKLOAD_CLASS (21*32 + 7) /* Workload Classification */
|
||||
#define X86_FEATURE_PREFER_YMM (21*32 + 8) /* Avoid ZMM registers due to downclocking */
|
||||
#define X86_FEATURE_INDIRECT_THUNK_ITS (21*32 + 9) /* Use thunk for indirect branches in lower half of cacheline */
|
||||
|
||||
/*
|
||||
* BUG word(s)
|
||||
|
|
@ -533,4 +534,6 @@
|
|||
#define X86_BUG_BHI X86_BUG(1*32 + 3) /* "bhi" CPU is affected by Branch History Injection */
|
||||
#define X86_BUG_IBPB_NO_RET X86_BUG(1*32 + 4) /* "ibpb_no_ret" IBPB omits return target predictions */
|
||||
#define X86_BUG_SPECTRE_V2_USER X86_BUG(1*32 + 5) /* "spectre_v2_user" CPU is affected by Spectre variant 2 attack between user processes */
|
||||
#define X86_BUG_ITS X86_BUG(1*32 + 6) /* "its" CPU is affected by Indirect Target Selection */
|
||||
#define X86_BUG_ITS_NATIVE_ONLY X86_BUG(1*32 + 7) /* "its_native_only" CPU is affected by ITS, VMX is not affected */
|
||||
#endif /* _ASM_X86_CPUFEATURES_H */
|
||||
|
|
|
|||
|
|
@ -17,10 +17,12 @@ struct ucode_cpu_info {
|
|||
void load_ucode_bsp(void);
|
||||
void load_ucode_ap(void);
|
||||
void microcode_bsp_resume(void);
|
||||
bool __init microcode_loader_disabled(void);
|
||||
#else
|
||||
static inline void load_ucode_bsp(void) { }
|
||||
static inline void load_ucode_ap(void) { }
|
||||
static inline void microcode_bsp_resume(void) { }
|
||||
static inline bool __init microcode_loader_disabled(void) { return false; }
|
||||
#endif
|
||||
|
||||
extern unsigned long initrd_start_early;
|
||||
|
|
|
|||
|
|
@ -211,6 +211,14 @@
|
|||
* VERW clears CPU Register
|
||||
* File.
|
||||
*/
|
||||
#define ARCH_CAP_ITS_NO BIT_ULL(62) /*
|
||||
* Not susceptible to
|
||||
* Indirect Target Selection.
|
||||
* This bit is not set by
|
||||
* HW, but is synthesized by
|
||||
* VMMs for guests to know
|
||||
* their affected status.
|
||||
*/
|
||||
|
||||
#define MSR_IA32_FLUSH_CMD 0x0000010b
|
||||
#define L1D_FLUSH BIT(0) /*
|
||||
|
|
|
|||
|
|
@ -336,10 +336,14 @@
|
|||
|
||||
#else /* __ASSEMBLER__ */
|
||||
|
||||
#define ITS_THUNK_SIZE 64
|
||||
|
||||
typedef u8 retpoline_thunk_t[RETPOLINE_THUNK_SIZE];
|
||||
typedef u8 its_thunk_t[ITS_THUNK_SIZE];
|
||||
extern retpoline_thunk_t __x86_indirect_thunk_array[];
|
||||
extern retpoline_thunk_t __x86_indirect_call_thunk_array[];
|
||||
extern retpoline_thunk_t __x86_indirect_jump_thunk_array[];
|
||||
extern its_thunk_t __x86_indirect_its_thunk_array[];
|
||||
|
||||
#ifdef CONFIG_MITIGATION_RETHUNK
|
||||
extern void __x86_return_thunk(void);
|
||||
|
|
@ -363,6 +367,12 @@ static inline void srso_return_thunk(void) {}
|
|||
static inline void srso_alias_return_thunk(void) {}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MITIGATION_ITS
|
||||
extern void its_return_thunk(void);
|
||||
#else
|
||||
static inline void its_return_thunk(void) {}
|
||||
#endif
|
||||
|
||||
extern void retbleed_return_thunk(void);
|
||||
extern void srso_return_thunk(void);
|
||||
extern void srso_alias_return_thunk(void);
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ enum psc_op {
|
|||
#define GHCB_MSR_VMPL_REQ 0x016
|
||||
#define GHCB_MSR_VMPL_REQ_LEVEL(v) \
|
||||
/* GHCBData[39:32] */ \
|
||||
(((u64)(v) & GENMASK_ULL(7, 0) << 32) | \
|
||||
((((u64)(v) & GENMASK_ULL(7, 0)) << 32) | \
|
||||
/* GHCBDdata[11:0] */ \
|
||||
GHCB_MSR_VMPL_REQ)
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include <linux/mmu_context.h>
|
||||
#include <linux/bsearch.h>
|
||||
#include <linux/sync_core.h>
|
||||
#include <linux/execmem.h>
|
||||
#include <asm/text-patching.h>
|
||||
#include <asm/alternative.h>
|
||||
#include <asm/sections.h>
|
||||
|
|
@ -31,6 +32,8 @@
|
|||
#include <asm/paravirt.h>
|
||||
#include <asm/asm-prototypes.h>
|
||||
#include <asm/cfi.h>
|
||||
#include <asm/ibt.h>
|
||||
#include <asm/set_memory.h>
|
||||
|
||||
int __read_mostly alternatives_patched;
|
||||
|
||||
|
|
@ -124,6 +127,171 @@ const unsigned char * const x86_nops[ASM_NOP_MAX+1] =
|
|||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_FINEIBT
|
||||
static bool cfi_paranoid __ro_after_init;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MITIGATION_ITS
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
static struct module *its_mod;
|
||||
#endif
|
||||
static void *its_page;
|
||||
static unsigned int its_offset;
|
||||
|
||||
/* Initialize a thunk with the "jmp *reg; int3" instructions. */
|
||||
static void *its_init_thunk(void *thunk, int reg)
|
||||
{
|
||||
u8 *bytes = thunk;
|
||||
int offset = 0;
|
||||
int i = 0;
|
||||
|
||||
#ifdef CONFIG_FINEIBT
|
||||
if (cfi_paranoid) {
|
||||
/*
|
||||
* When ITS uses indirect branch thunk the fineibt_paranoid
|
||||
* caller sequence doesn't fit in the caller site. So put the
|
||||
* remaining part of the sequence (<ea> + JNE) into the ITS
|
||||
* thunk.
|
||||
*/
|
||||
bytes[i++] = 0xea; /* invalid instruction */
|
||||
bytes[i++] = 0x75; /* JNE */
|
||||
bytes[i++] = 0xfd;
|
||||
|
||||
offset = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (reg >= 8) {
|
||||
bytes[i++] = 0x41; /* REX.B prefix */
|
||||
reg -= 8;
|
||||
}
|
||||
bytes[i++] = 0xff;
|
||||
bytes[i++] = 0xe0 + reg; /* jmp *reg */
|
||||
bytes[i++] = 0xcc;
|
||||
|
||||
return thunk + offset;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
void its_init_mod(struct module *mod)
|
||||
{
|
||||
if (!cpu_feature_enabled(X86_FEATURE_INDIRECT_THUNK_ITS))
|
||||
return;
|
||||
|
||||
mutex_lock(&text_mutex);
|
||||
its_mod = mod;
|
||||
its_page = NULL;
|
||||
}
|
||||
|
||||
void its_fini_mod(struct module *mod)
|
||||
{
|
||||
if (!cpu_feature_enabled(X86_FEATURE_INDIRECT_THUNK_ITS))
|
||||
return;
|
||||
|
||||
WARN_ON_ONCE(its_mod != mod);
|
||||
|
||||
its_mod = NULL;
|
||||
its_page = NULL;
|
||||
mutex_unlock(&text_mutex);
|
||||
|
||||
for (int i = 0; i < mod->its_num_pages; i++) {
|
||||
void *page = mod->its_page_array[i];
|
||||
execmem_restore_rox(page, PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
void its_free_mod(struct module *mod)
|
||||
{
|
||||
if (!cpu_feature_enabled(X86_FEATURE_INDIRECT_THUNK_ITS))
|
||||
return;
|
||||
|
||||
for (int i = 0; i < mod->its_num_pages; i++) {
|
||||
void *page = mod->its_page_array[i];
|
||||
execmem_free(page);
|
||||
}
|
||||
kfree(mod->its_page_array);
|
||||
}
|
||||
#endif /* CONFIG_MODULES */
|
||||
|
||||
static void *its_alloc(void)
|
||||
{
|
||||
void *page __free(execmem) = execmem_alloc(EXECMEM_MODULE_TEXT, PAGE_SIZE);
|
||||
|
||||
if (!page)
|
||||
return NULL;
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
if (its_mod) {
|
||||
void *tmp = krealloc(its_mod->its_page_array,
|
||||
(its_mod->its_num_pages+1) * sizeof(void *),
|
||||
GFP_KERNEL);
|
||||
if (!tmp)
|
||||
return NULL;
|
||||
|
||||
its_mod->its_page_array = tmp;
|
||||
its_mod->its_page_array[its_mod->its_num_pages++] = page;
|
||||
|
||||
execmem_make_temp_rw(page, PAGE_SIZE);
|
||||
}
|
||||
#endif /* CONFIG_MODULES */
|
||||
|
||||
return no_free_ptr(page);
|
||||
}
|
||||
|
||||
static void *its_allocate_thunk(int reg)
|
||||
{
|
||||
int size = 3 + (reg / 8);
|
||||
void *thunk;
|
||||
|
||||
#ifdef CONFIG_FINEIBT
|
||||
/*
|
||||
* The ITS thunk contains an indirect jump and an int3 instruction so
|
||||
* its size is 3 or 4 bytes depending on the register used. If CFI
|
||||
* paranoid is used then 3 extra bytes are added in the ITS thunk to
|
||||
* complete the fineibt_paranoid caller sequence.
|
||||
*/
|
||||
if (cfi_paranoid)
|
||||
size += 3;
|
||||
#endif
|
||||
|
||||
if (!its_page || (its_offset + size - 1) >= PAGE_SIZE) {
|
||||
its_page = its_alloc();
|
||||
if (!its_page) {
|
||||
pr_err("ITS page allocation failed\n");
|
||||
return NULL;
|
||||
}
|
||||
memset(its_page, INT3_INSN_OPCODE, PAGE_SIZE);
|
||||
its_offset = 32;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the indirect branch instruction will be in the lower half
|
||||
* of a cacheline, then update the offset to reach the upper half.
|
||||
*/
|
||||
if ((its_offset + size - 1) % 64 < 32)
|
||||
its_offset = ((its_offset - 1) | 0x3F) + 33;
|
||||
|
||||
thunk = its_page + its_offset;
|
||||
its_offset += size;
|
||||
|
||||
return its_init_thunk(thunk, reg);
|
||||
}
|
||||
|
||||
u8 *its_static_thunk(int reg)
|
||||
{
|
||||
u8 *thunk = __x86_indirect_its_thunk_array[reg];
|
||||
|
||||
#ifdef CONFIG_FINEIBT
|
||||
/* Paranoid thunk starts 2 bytes before */
|
||||
if (cfi_paranoid)
|
||||
return thunk - 2;
|
||||
#endif
|
||||
return thunk;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Nomenclature for variable names to simplify and clarify this code and ease
|
||||
* any potential staring at it:
|
||||
|
|
@ -581,7 +749,8 @@ static int emit_indirect(int op, int reg, u8 *bytes)
|
|||
return i;
|
||||
}
|
||||
|
||||
static int emit_call_track_retpoline(void *addr, struct insn *insn, int reg, u8 *bytes)
|
||||
static int __emit_trampoline(void *addr, struct insn *insn, u8 *bytes,
|
||||
void *call_dest, void *jmp_dest)
|
||||
{
|
||||
u8 op = insn->opcode.bytes[0];
|
||||
int i = 0;
|
||||
|
|
@ -602,7 +771,7 @@ static int emit_call_track_retpoline(void *addr, struct insn *insn, int reg, u8
|
|||
switch (op) {
|
||||
case CALL_INSN_OPCODE:
|
||||
__text_gen_insn(bytes+i, op, addr+i,
|
||||
__x86_indirect_call_thunk_array[reg],
|
||||
call_dest,
|
||||
CALL_INSN_SIZE);
|
||||
i += CALL_INSN_SIZE;
|
||||
break;
|
||||
|
|
@ -610,7 +779,7 @@ static int emit_call_track_retpoline(void *addr, struct insn *insn, int reg, u8
|
|||
case JMP32_INSN_OPCODE:
|
||||
clang_jcc:
|
||||
__text_gen_insn(bytes+i, op, addr+i,
|
||||
__x86_indirect_jump_thunk_array[reg],
|
||||
jmp_dest,
|
||||
JMP32_INSN_SIZE);
|
||||
i += JMP32_INSN_SIZE;
|
||||
break;
|
||||
|
|
@ -625,6 +794,48 @@ clang_jcc:
|
|||
return i;
|
||||
}
|
||||
|
||||
static int emit_call_track_retpoline(void *addr, struct insn *insn, int reg, u8 *bytes)
|
||||
{
|
||||
return __emit_trampoline(addr, insn, bytes,
|
||||
__x86_indirect_call_thunk_array[reg],
|
||||
__x86_indirect_jump_thunk_array[reg]);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MITIGATION_ITS
|
||||
static int emit_its_trampoline(void *addr, struct insn *insn, int reg, u8 *bytes)
|
||||
{
|
||||
u8 *thunk = __x86_indirect_its_thunk_array[reg];
|
||||
u8 *tmp = its_allocate_thunk(reg);
|
||||
|
||||
if (tmp)
|
||||
thunk = tmp;
|
||||
|
||||
return __emit_trampoline(addr, insn, bytes, thunk, thunk);
|
||||
}
|
||||
|
||||
/* Check if an indirect branch is at ITS-unsafe address */
|
||||
static bool cpu_wants_indirect_its_thunk_at(unsigned long addr, int reg)
|
||||
{
|
||||
if (!cpu_feature_enabled(X86_FEATURE_INDIRECT_THUNK_ITS))
|
||||
return false;
|
||||
|
||||
/* Indirect branch opcode is 2 or 3 bytes depending on reg */
|
||||
addr += 1 + reg / 8;
|
||||
|
||||
/* Lower-half of the cacheline? */
|
||||
return !(addr & 0x20);
|
||||
}
|
||||
#else /* CONFIG_MITIGATION_ITS */
|
||||
|
||||
#ifdef CONFIG_FINEIBT
|
||||
static bool cpu_wants_indirect_its_thunk_at(unsigned long addr, int reg)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_MITIGATION_ITS */
|
||||
|
||||
/*
|
||||
* Rewrite the compiler generated retpoline thunk calls.
|
||||
*
|
||||
|
|
@ -699,6 +910,15 @@ static int patch_retpoline(void *addr, struct insn *insn, u8 *bytes)
|
|||
bytes[i++] = 0xe8; /* LFENCE */
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MITIGATION_ITS
|
||||
/*
|
||||
* Check if the address of last byte of emitted-indirect is in
|
||||
* lower-half of the cacheline. Such branches need ITS mitigation.
|
||||
*/
|
||||
if (cpu_wants_indirect_its_thunk_at((unsigned long)addr + i, reg))
|
||||
return emit_its_trampoline(addr, insn, reg, bytes);
|
||||
#endif
|
||||
|
||||
ret = emit_indirect(op, reg, bytes + i);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
|
@ -732,6 +952,7 @@ void __init_or_module noinline apply_retpolines(s32 *start, s32 *end)
|
|||
int len, ret;
|
||||
u8 bytes[16];
|
||||
u8 op1, op2;
|
||||
u8 *dest;
|
||||
|
||||
ret = insn_decode_kernel(&insn, addr);
|
||||
if (WARN_ON_ONCE(ret < 0))
|
||||
|
|
@ -748,6 +969,12 @@ void __init_or_module noinline apply_retpolines(s32 *start, s32 *end)
|
|||
|
||||
case CALL_INSN_OPCODE:
|
||||
case JMP32_INSN_OPCODE:
|
||||
/* Check for cfi_paranoid + ITS */
|
||||
dest = addr + insn.length + insn.immediate.value;
|
||||
if (dest[-1] == 0xea && (dest[0] & 0xf0) == 0x70) {
|
||||
WARN_ON_ONCE(cfi_mode != CFI_FINEIBT);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0f: /* escape */
|
||||
|
|
@ -775,6 +1002,21 @@ void __init_or_module noinline apply_retpolines(s32 *start, s32 *end)
|
|||
|
||||
#ifdef CONFIG_MITIGATION_RETHUNK
|
||||
|
||||
bool cpu_wants_rethunk(void)
|
||||
{
|
||||
return cpu_feature_enabled(X86_FEATURE_RETHUNK);
|
||||
}
|
||||
|
||||
bool cpu_wants_rethunk_at(void *addr)
|
||||
{
|
||||
if (!cpu_feature_enabled(X86_FEATURE_RETHUNK))
|
||||
return false;
|
||||
if (x86_return_thunk != its_return_thunk)
|
||||
return true;
|
||||
|
||||
return !((unsigned long)addr & 0x20);
|
||||
}
|
||||
|
||||
/*
|
||||
* Rewrite the compiler generated return thunk tail-calls.
|
||||
*
|
||||
|
|
@ -791,7 +1033,7 @@ static int patch_return(void *addr, struct insn *insn, u8 *bytes)
|
|||
int i = 0;
|
||||
|
||||
/* Patch the custom return thunks... */
|
||||
if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) {
|
||||
if (cpu_wants_rethunk_at(addr)) {
|
||||
i = JMP32_INSN_SIZE;
|
||||
__text_gen_insn(bytes, JMP32_INSN_OPCODE, addr, x86_return_thunk, i);
|
||||
} else {
|
||||
|
|
@ -808,7 +1050,7 @@ void __init_or_module noinline apply_returns(s32 *start, s32 *end)
|
|||
{
|
||||
s32 *s;
|
||||
|
||||
if (cpu_feature_enabled(X86_FEATURE_RETHUNK))
|
||||
if (cpu_wants_rethunk())
|
||||
static_call_force_reinit();
|
||||
|
||||
for (s = start; s < end; s++) {
|
||||
|
|
@ -1022,8 +1264,6 @@ int cfi_get_func_arity(void *func)
|
|||
static bool cfi_rand __ro_after_init = true;
|
||||
static u32 cfi_seed __ro_after_init;
|
||||
|
||||
static bool cfi_paranoid __ro_after_init = false;
|
||||
|
||||
/*
|
||||
* Re-hash the CFI hash with a boot-time seed while making sure the result is
|
||||
* not a valid ENDBR instruction.
|
||||
|
|
@ -1436,6 +1676,19 @@ static int cfi_rand_callers(s32 *start, s32 *end)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int emit_paranoid_trampoline(void *addr, struct insn *insn, int reg, u8 *bytes)
|
||||
{
|
||||
u8 *thunk = (void *)__x86_indirect_its_thunk_array[reg] - 2;
|
||||
|
||||
#ifdef CONFIG_MITIGATION_ITS
|
||||
u8 *tmp = its_allocate_thunk(reg);
|
||||
if (tmp)
|
||||
thunk = tmp;
|
||||
#endif
|
||||
|
||||
return __emit_trampoline(addr, insn, bytes, thunk, thunk);
|
||||
}
|
||||
|
||||
static int cfi_rewrite_callers(s32 *start, s32 *end)
|
||||
{
|
||||
s32 *s;
|
||||
|
|
@ -1477,9 +1730,14 @@ static int cfi_rewrite_callers(s32 *start, s32 *end)
|
|||
memcpy(bytes, fineibt_paranoid_start, fineibt_paranoid_size);
|
||||
memcpy(bytes + fineibt_caller_hash, &hash, 4);
|
||||
|
||||
ret = emit_indirect(op, 11, bytes + fineibt_paranoid_ind);
|
||||
if (WARN_ON_ONCE(ret != 3))
|
||||
continue;
|
||||
if (cpu_wants_indirect_its_thunk_at((unsigned long)addr + fineibt_paranoid_ind, 11)) {
|
||||
emit_paranoid_trampoline(addr + fineibt_caller_size,
|
||||
&insn, 11, bytes + fineibt_caller_size);
|
||||
} else {
|
||||
ret = emit_indirect(op, 11, bytes + fineibt_paranoid_ind);
|
||||
if (WARN_ON_ONCE(ret != 3))
|
||||
continue;
|
||||
}
|
||||
|
||||
text_poke_early(addr, bytes, fineibt_paranoid_size);
|
||||
}
|
||||
|
|
@ -1706,29 +1964,66 @@ Efault:
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool is_paranoid_thunk(unsigned long addr)
|
||||
{
|
||||
u32 thunk;
|
||||
|
||||
__get_kernel_nofault(&thunk, (u32 *)addr, u32, Efault);
|
||||
return (thunk & 0x00FFFFFF) == 0xfd75ea;
|
||||
|
||||
Efault:
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* regs->ip points to a LOCK Jcc.d8 instruction from the fineibt_paranoid_start[]
|
||||
* sequence.
|
||||
* sequence, or to an invalid instruction (0xea) + Jcc.d8 for cfi_paranoid + ITS
|
||||
* thunk.
|
||||
*/
|
||||
static bool decode_fineibt_paranoid(struct pt_regs *regs, unsigned long *target, u32 *type)
|
||||
{
|
||||
unsigned long addr = regs->ip - fineibt_paranoid_ud;
|
||||
u32 hash;
|
||||
|
||||
if (!cfi_paranoid || !is_cfi_trap(addr + fineibt_caller_size - LEN_UD2))
|
||||
if (!cfi_paranoid)
|
||||
return false;
|
||||
|
||||
__get_kernel_nofault(&hash, addr + fineibt_caller_hash, u32, Efault);
|
||||
*target = regs->r11 + fineibt_preamble_size;
|
||||
*type = regs->r10;
|
||||
if (is_cfi_trap(addr + fineibt_caller_size - LEN_UD2)) {
|
||||
*target = regs->r11 + fineibt_preamble_size;
|
||||
*type = regs->r10;
|
||||
|
||||
/*
|
||||
* Since the trapping instruction is the exact, but LOCK prefixed,
|
||||
* Jcc.d8 that got us here, the normal fixup will work.
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since the trapping instruction is the exact, but LOCK prefixed,
|
||||
* Jcc.d8 that got us here, the normal fixup will work.
|
||||
* The cfi_paranoid + ITS thunk combination results in:
|
||||
*
|
||||
* 0: 41 ba 78 56 34 12 mov $0x12345678, %r10d
|
||||
* 6: 45 3b 53 f7 cmp -0x9(%r11), %r10d
|
||||
* a: 4d 8d 5b f0 lea -0x10(%r11), %r11
|
||||
* e: 2e e8 XX XX XX XX cs call __x86_indirect_paranoid_thunk_r11
|
||||
*
|
||||
* Where the paranoid_thunk looks like:
|
||||
*
|
||||
* 1d: <ea> (bad)
|
||||
* __x86_indirect_paranoid_thunk_r11:
|
||||
* 1e: 75 fd jne 1d
|
||||
* __x86_indirect_its_thunk_r11:
|
||||
* 20: 41 ff eb jmp *%r11
|
||||
* 23: cc int3
|
||||
*
|
||||
*/
|
||||
return true;
|
||||
if (is_paranoid_thunk(regs->ip)) {
|
||||
*target = regs->r11 + fineibt_preamble_size;
|
||||
*type = regs->r10;
|
||||
|
||||
regs->ip = *target;
|
||||
return true;
|
||||
}
|
||||
|
||||
Efault:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2031,6 +2326,8 @@ static noinline void __init alt_reloc_selftest(void)
|
|||
|
||||
void __init alternative_instructions(void)
|
||||
{
|
||||
u64 ibt;
|
||||
|
||||
int3_selftest();
|
||||
|
||||
/*
|
||||
|
|
@ -2057,6 +2354,9 @@ void __init alternative_instructions(void)
|
|||
*/
|
||||
paravirt_set_cap();
|
||||
|
||||
/* Keep CET-IBT disabled until caller/callee are patched */
|
||||
ibt = ibt_save(/*disable*/ true);
|
||||
|
||||
__apply_fineibt(__retpoline_sites, __retpoline_sites_end,
|
||||
__cfi_sites, __cfi_sites_end, true);
|
||||
|
||||
|
|
@ -2080,6 +2380,8 @@ void __init alternative_instructions(void)
|
|||
*/
|
||||
apply_seal_endbr(__ibt_endbr_seal, __ibt_endbr_seal_end);
|
||||
|
||||
ibt_restore(ibt);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* Patch to UP if other cpus not imminent. */
|
||||
if (!noreplace_smp && (num_present_cpus() == 1 || setup_max_cpus <= 1)) {
|
||||
|
|
|
|||
|
|
@ -472,6 +472,11 @@ static void bsp_init_amd(struct cpuinfo_x86 *c)
|
|||
case 0x60 ... 0x7f:
|
||||
setup_force_cpu_cap(X86_FEATURE_ZEN5);
|
||||
break;
|
||||
case 0x50 ... 0x5f:
|
||||
case 0x90 ... 0xaf:
|
||||
case 0xc0 ... 0xcf:
|
||||
setup_force_cpu_cap(X86_FEATURE_ZEN6);
|
||||
break;
|
||||
default:
|
||||
goto warn;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ static void __init srbds_select_mitigation(void);
|
|||
static void __init l1d_flush_select_mitigation(void);
|
||||
static void __init srso_select_mitigation(void);
|
||||
static void __init gds_select_mitigation(void);
|
||||
static void __init its_select_mitigation(void);
|
||||
|
||||
/* The base value of the SPEC_CTRL MSR without task-specific bits set */
|
||||
u64 x86_spec_ctrl_base;
|
||||
|
|
@ -66,6 +67,14 @@ static DEFINE_MUTEX(spec_ctrl_mutex);
|
|||
|
||||
void (*x86_return_thunk)(void) __ro_after_init = __x86_return_thunk;
|
||||
|
||||
static void __init set_return_thunk(void *thunk)
|
||||
{
|
||||
if (x86_return_thunk != __x86_return_thunk)
|
||||
pr_warn("x86/bugs: return thunk changed\n");
|
||||
|
||||
x86_return_thunk = thunk;
|
||||
}
|
||||
|
||||
/* Update SPEC_CTRL MSR and its cached copy unconditionally */
|
||||
static void update_spec_ctrl(u64 val)
|
||||
{
|
||||
|
|
@ -178,6 +187,7 @@ void __init cpu_select_mitigations(void)
|
|||
*/
|
||||
srso_select_mitigation();
|
||||
gds_select_mitigation();
|
||||
its_select_mitigation();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1118,7 +1128,7 @@ do_cmd_auto:
|
|||
setup_force_cpu_cap(X86_FEATURE_RETHUNK);
|
||||
setup_force_cpu_cap(X86_FEATURE_UNRET);
|
||||
|
||||
x86_return_thunk = retbleed_return_thunk;
|
||||
set_return_thunk(retbleed_return_thunk);
|
||||
|
||||
if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
|
||||
boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
|
||||
|
|
@ -1153,7 +1163,7 @@ do_cmd_auto:
|
|||
setup_force_cpu_cap(X86_FEATURE_RETHUNK);
|
||||
setup_force_cpu_cap(X86_FEATURE_CALL_DEPTH);
|
||||
|
||||
x86_return_thunk = call_depth_return_thunk;
|
||||
set_return_thunk(call_depth_return_thunk);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -1187,6 +1197,145 @@ do_cmd_auto:
|
|||
pr_info("%s\n", retbleed_strings[retbleed_mitigation]);
|
||||
}
|
||||
|
||||
#undef pr_fmt
|
||||
#define pr_fmt(fmt) "ITS: " fmt
|
||||
|
||||
enum its_mitigation_cmd {
|
||||
ITS_CMD_OFF,
|
||||
ITS_CMD_ON,
|
||||
ITS_CMD_VMEXIT,
|
||||
ITS_CMD_RSB_STUFF,
|
||||
};
|
||||
|
||||
enum its_mitigation {
|
||||
ITS_MITIGATION_OFF,
|
||||
ITS_MITIGATION_VMEXIT_ONLY,
|
||||
ITS_MITIGATION_ALIGNED_THUNKS,
|
||||
ITS_MITIGATION_RETPOLINE_STUFF,
|
||||
};
|
||||
|
||||
static const char * const its_strings[] = {
|
||||
[ITS_MITIGATION_OFF] = "Vulnerable",
|
||||
[ITS_MITIGATION_VMEXIT_ONLY] = "Mitigation: Vulnerable, KVM: Not affected",
|
||||
[ITS_MITIGATION_ALIGNED_THUNKS] = "Mitigation: Aligned branch/return thunks",
|
||||
[ITS_MITIGATION_RETPOLINE_STUFF] = "Mitigation: Retpolines, Stuffing RSB",
|
||||
};
|
||||
|
||||
static enum its_mitigation its_mitigation __ro_after_init = ITS_MITIGATION_ALIGNED_THUNKS;
|
||||
|
||||
static enum its_mitigation_cmd its_cmd __ro_after_init =
|
||||
IS_ENABLED(CONFIG_MITIGATION_ITS) ? ITS_CMD_ON : ITS_CMD_OFF;
|
||||
|
||||
static int __init its_parse_cmdline(char *str)
|
||||
{
|
||||
if (!str)
|
||||
return -EINVAL;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_MITIGATION_ITS)) {
|
||||
pr_err("Mitigation disabled at compile time, ignoring option (%s)", str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(str, "off")) {
|
||||
its_cmd = ITS_CMD_OFF;
|
||||
} else if (!strcmp(str, "on")) {
|
||||
its_cmd = ITS_CMD_ON;
|
||||
} else if (!strcmp(str, "force")) {
|
||||
its_cmd = ITS_CMD_ON;
|
||||
setup_force_cpu_bug(X86_BUG_ITS);
|
||||
} else if (!strcmp(str, "vmexit")) {
|
||||
its_cmd = ITS_CMD_VMEXIT;
|
||||
} else if (!strcmp(str, "stuff")) {
|
||||
its_cmd = ITS_CMD_RSB_STUFF;
|
||||
} else {
|
||||
pr_err("Ignoring unknown indirect_target_selection option (%s).", str);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
early_param("indirect_target_selection", its_parse_cmdline);
|
||||
|
||||
static void __init its_select_mitigation(void)
|
||||
{
|
||||
enum its_mitigation_cmd cmd = its_cmd;
|
||||
|
||||
if (!boot_cpu_has_bug(X86_BUG_ITS) || cpu_mitigations_off()) {
|
||||
its_mitigation = ITS_MITIGATION_OFF;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Retpoline+CDT mitigates ITS, bail out */
|
||||
if (boot_cpu_has(X86_FEATURE_RETPOLINE) &&
|
||||
boot_cpu_has(X86_FEATURE_CALL_DEPTH)) {
|
||||
its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Exit early to avoid irrelevant warnings */
|
||||
if (cmd == ITS_CMD_OFF) {
|
||||
its_mitigation = ITS_MITIGATION_OFF;
|
||||
goto out;
|
||||
}
|
||||
if (spectre_v2_enabled == SPECTRE_V2_NONE) {
|
||||
pr_err("WARNING: Spectre-v2 mitigation is off, disabling ITS\n");
|
||||
its_mitigation = ITS_MITIGATION_OFF;
|
||||
goto out;
|
||||
}
|
||||
if (!IS_ENABLED(CONFIG_MITIGATION_RETPOLINE) ||
|
||||
!IS_ENABLED(CONFIG_MITIGATION_RETHUNK)) {
|
||||
pr_err("WARNING: ITS mitigation depends on retpoline and rethunk support\n");
|
||||
its_mitigation = ITS_MITIGATION_OFF;
|
||||
goto out;
|
||||
}
|
||||
if (IS_ENABLED(CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B)) {
|
||||
pr_err("WARNING: ITS mitigation is not compatible with CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B\n");
|
||||
its_mitigation = ITS_MITIGATION_OFF;
|
||||
goto out;
|
||||
}
|
||||
if (boot_cpu_has(X86_FEATURE_RETPOLINE_LFENCE)) {
|
||||
pr_err("WARNING: ITS mitigation is not compatible with lfence mitigation\n");
|
||||
its_mitigation = ITS_MITIGATION_OFF;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (cmd == ITS_CMD_RSB_STUFF &&
|
||||
(!boot_cpu_has(X86_FEATURE_RETPOLINE) || !IS_ENABLED(CONFIG_MITIGATION_CALL_DEPTH_TRACKING))) {
|
||||
pr_err("RSB stuff mitigation not supported, using default\n");
|
||||
cmd = ITS_CMD_ON;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case ITS_CMD_OFF:
|
||||
its_mitigation = ITS_MITIGATION_OFF;
|
||||
break;
|
||||
case ITS_CMD_VMEXIT:
|
||||
if (boot_cpu_has_bug(X86_BUG_ITS_NATIVE_ONLY)) {
|
||||
its_mitigation = ITS_MITIGATION_VMEXIT_ONLY;
|
||||
goto out;
|
||||
}
|
||||
fallthrough;
|
||||
case ITS_CMD_ON:
|
||||
its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
|
||||
if (!boot_cpu_has(X86_FEATURE_RETPOLINE))
|
||||
setup_force_cpu_cap(X86_FEATURE_INDIRECT_THUNK_ITS);
|
||||
setup_force_cpu_cap(X86_FEATURE_RETHUNK);
|
||||
set_return_thunk(its_return_thunk);
|
||||
break;
|
||||
case ITS_CMD_RSB_STUFF:
|
||||
its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF;
|
||||
setup_force_cpu_cap(X86_FEATURE_RETHUNK);
|
||||
setup_force_cpu_cap(X86_FEATURE_CALL_DEPTH);
|
||||
set_return_thunk(call_depth_return_thunk);
|
||||
if (retbleed_mitigation == RETBLEED_MITIGATION_NONE) {
|
||||
retbleed_mitigation = RETBLEED_MITIGATION_STUFF;
|
||||
pr_info("Retbleed mitigation updated to stuffing\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
out:
|
||||
pr_info("%s\n", its_strings[its_mitigation]);
|
||||
}
|
||||
|
||||
#undef pr_fmt
|
||||
#define pr_fmt(fmt) "Spectre V2 : " fmt
|
||||
|
||||
|
|
@ -1697,11 +1846,11 @@ static void __init bhi_select_mitigation(void)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Mitigate in hardware if supported */
|
||||
if (spec_ctrl_bhi_dis())
|
||||
if (!IS_ENABLED(CONFIG_X86_64))
|
||||
return;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_X86_64))
|
||||
/* Mitigate in hardware if supported */
|
||||
if (spec_ctrl_bhi_dis())
|
||||
return;
|
||||
|
||||
if (bhi_mitigation == BHI_MITIGATION_VMEXIT_ONLY) {
|
||||
|
|
@ -2607,10 +2756,10 @@ static void __init srso_select_mitigation(void)
|
|||
|
||||
if (boot_cpu_data.x86 == 0x19) {
|
||||
setup_force_cpu_cap(X86_FEATURE_SRSO_ALIAS);
|
||||
x86_return_thunk = srso_alias_return_thunk;
|
||||
set_return_thunk(srso_alias_return_thunk);
|
||||
} else {
|
||||
setup_force_cpu_cap(X86_FEATURE_SRSO);
|
||||
x86_return_thunk = srso_return_thunk;
|
||||
set_return_thunk(srso_return_thunk);
|
||||
}
|
||||
if (has_microcode)
|
||||
srso_mitigation = SRSO_MITIGATION_SAFE_RET;
|
||||
|
|
@ -2800,6 +2949,11 @@ static ssize_t rfds_show_state(char *buf)
|
|||
return sysfs_emit(buf, "%s\n", rfds_strings[rfds_mitigation]);
|
||||
}
|
||||
|
||||
static ssize_t its_show_state(char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "%s\n", its_strings[its_mitigation]);
|
||||
}
|
||||
|
||||
static char *stibp_state(void)
|
||||
{
|
||||
if (spectre_v2_in_eibrs_mode(spectre_v2_enabled) &&
|
||||
|
|
@ -2982,6 +3136,9 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
|
|||
case X86_BUG_RFDS:
|
||||
return rfds_show_state(buf);
|
||||
|
||||
case X86_BUG_ITS:
|
||||
return its_show_state(buf);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -3061,6 +3218,11 @@ ssize_t cpu_show_reg_file_data_sampling(struct device *dev, struct device_attrib
|
|||
{
|
||||
return cpu_show_common(dev, attr, buf, X86_BUG_RFDS);
|
||||
}
|
||||
|
||||
ssize_t cpu_show_indirect_target_selection(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return cpu_show_common(dev, attr, buf, X86_BUG_ITS);
|
||||
}
|
||||
#endif
|
||||
|
||||
void __warn_thunk(void)
|
||||
|
|
|
|||
|
|
@ -1227,6 +1227,10 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
|
|||
#define GDS BIT(6)
|
||||
/* CPU is affected by Register File Data Sampling */
|
||||
#define RFDS BIT(7)
|
||||
/* CPU is affected by Indirect Target Selection */
|
||||
#define ITS BIT(8)
|
||||
/* CPU is affected by Indirect Target Selection, but guest-host isolation is not affected */
|
||||
#define ITS_NATIVE_ONLY BIT(9)
|
||||
|
||||
static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
|
||||
VULNBL_INTEL_STEPS(INTEL_IVYBRIDGE, X86_STEP_MAX, SRBDS),
|
||||
|
|
@ -1238,22 +1242,25 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
|
|||
VULNBL_INTEL_STEPS(INTEL_BROADWELL_G, X86_STEP_MAX, SRBDS),
|
||||
VULNBL_INTEL_STEPS(INTEL_BROADWELL_X, X86_STEP_MAX, MMIO),
|
||||
VULNBL_INTEL_STEPS(INTEL_BROADWELL, X86_STEP_MAX, SRBDS),
|
||||
VULNBL_INTEL_STEPS(INTEL_SKYLAKE_X, X86_STEP_MAX, MMIO | RETBLEED | GDS),
|
||||
VULNBL_INTEL_STEPS(INTEL_SKYLAKE_X, 0x5, MMIO | RETBLEED | GDS),
|
||||
VULNBL_INTEL_STEPS(INTEL_SKYLAKE_X, X86_STEP_MAX, MMIO | RETBLEED | GDS | ITS),
|
||||
VULNBL_INTEL_STEPS(INTEL_SKYLAKE_L, X86_STEP_MAX, MMIO | RETBLEED | GDS | SRBDS),
|
||||
VULNBL_INTEL_STEPS(INTEL_SKYLAKE, X86_STEP_MAX, MMIO | RETBLEED | GDS | SRBDS),
|
||||
VULNBL_INTEL_STEPS(INTEL_KABYLAKE_L, X86_STEP_MAX, MMIO | RETBLEED | GDS | SRBDS),
|
||||
VULNBL_INTEL_STEPS(INTEL_KABYLAKE, X86_STEP_MAX, MMIO | RETBLEED | GDS | SRBDS),
|
||||
VULNBL_INTEL_STEPS(INTEL_KABYLAKE_L, 0xb, MMIO | RETBLEED | GDS | SRBDS),
|
||||
VULNBL_INTEL_STEPS(INTEL_KABYLAKE_L, X86_STEP_MAX, MMIO | RETBLEED | GDS | SRBDS | ITS),
|
||||
VULNBL_INTEL_STEPS(INTEL_KABYLAKE, 0xc, MMIO | RETBLEED | GDS | SRBDS),
|
||||
VULNBL_INTEL_STEPS(INTEL_KABYLAKE, X86_STEP_MAX, MMIO | RETBLEED | GDS | SRBDS | ITS),
|
||||
VULNBL_INTEL_STEPS(INTEL_CANNONLAKE_L, X86_STEP_MAX, RETBLEED),
|
||||
VULNBL_INTEL_STEPS(INTEL_ICELAKE_L, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED | GDS),
|
||||
VULNBL_INTEL_STEPS(INTEL_ICELAKE_D, X86_STEP_MAX, MMIO | GDS),
|
||||
VULNBL_INTEL_STEPS(INTEL_ICELAKE_X, X86_STEP_MAX, MMIO | GDS),
|
||||
VULNBL_INTEL_STEPS(INTEL_COMETLAKE, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED | GDS),
|
||||
VULNBL_INTEL_STEPS(INTEL_COMETLAKE_L, 0x0, MMIO | RETBLEED),
|
||||
VULNBL_INTEL_STEPS(INTEL_COMETLAKE_L, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED | GDS),
|
||||
VULNBL_INTEL_STEPS(INTEL_TIGERLAKE_L, X86_STEP_MAX, GDS),
|
||||
VULNBL_INTEL_STEPS(INTEL_TIGERLAKE, X86_STEP_MAX, GDS),
|
||||
VULNBL_INTEL_STEPS(INTEL_ICELAKE_L, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED | GDS | ITS | ITS_NATIVE_ONLY),
|
||||
VULNBL_INTEL_STEPS(INTEL_ICELAKE_D, X86_STEP_MAX, MMIO | GDS | ITS | ITS_NATIVE_ONLY),
|
||||
VULNBL_INTEL_STEPS(INTEL_ICELAKE_X, X86_STEP_MAX, MMIO | GDS | ITS | ITS_NATIVE_ONLY),
|
||||
VULNBL_INTEL_STEPS(INTEL_COMETLAKE, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED | GDS | ITS),
|
||||
VULNBL_INTEL_STEPS(INTEL_COMETLAKE_L, 0x0, MMIO | RETBLEED | ITS),
|
||||
VULNBL_INTEL_STEPS(INTEL_COMETLAKE_L, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED | GDS | ITS),
|
||||
VULNBL_INTEL_STEPS(INTEL_TIGERLAKE_L, X86_STEP_MAX, GDS | ITS | ITS_NATIVE_ONLY),
|
||||
VULNBL_INTEL_STEPS(INTEL_TIGERLAKE, X86_STEP_MAX, GDS | ITS | ITS_NATIVE_ONLY),
|
||||
VULNBL_INTEL_STEPS(INTEL_LAKEFIELD, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED),
|
||||
VULNBL_INTEL_STEPS(INTEL_ROCKETLAKE, X86_STEP_MAX, MMIO | RETBLEED | GDS),
|
||||
VULNBL_INTEL_STEPS(INTEL_ROCKETLAKE, X86_STEP_MAX, MMIO | RETBLEED | GDS | ITS | ITS_NATIVE_ONLY),
|
||||
VULNBL_INTEL_TYPE(INTEL_ALDERLAKE, ATOM, RFDS),
|
||||
VULNBL_INTEL_STEPS(INTEL_ALDERLAKE_L, X86_STEP_MAX, RFDS),
|
||||
VULNBL_INTEL_TYPE(INTEL_RAPTORLAKE, ATOM, RFDS),
|
||||
|
|
@ -1318,6 +1325,32 @@ static bool __init vulnerable_to_rfds(u64 x86_arch_cap_msr)
|
|||
return cpu_matches(cpu_vuln_blacklist, RFDS);
|
||||
}
|
||||
|
||||
static bool __init vulnerable_to_its(u64 x86_arch_cap_msr)
|
||||
{
|
||||
/* The "immunity" bit trumps everything else: */
|
||||
if (x86_arch_cap_msr & ARCH_CAP_ITS_NO)
|
||||
return false;
|
||||
if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
|
||||
return false;
|
||||
|
||||
/* None of the affected CPUs have BHI_CTRL */
|
||||
if (boot_cpu_has(X86_FEATURE_BHI_CTRL))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* If a VMM did not expose ITS_NO, assume that a guest could
|
||||
* be running on a vulnerable hardware or may migrate to such
|
||||
* hardware.
|
||||
*/
|
||||
if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
|
||||
return true;
|
||||
|
||||
if (cpu_matches(cpu_vuln_blacklist, ITS))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
|
||||
{
|
||||
u64 x86_arch_cap_msr = x86_read_arch_cap_msr();
|
||||
|
|
@ -1439,9 +1472,12 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
|
|||
if (vulnerable_to_rfds(x86_arch_cap_msr))
|
||||
setup_force_cpu_bug(X86_BUG_RFDS);
|
||||
|
||||
/* When virtualized, eIBRS could be hidden, assume vulnerable */
|
||||
if (!(x86_arch_cap_msr & ARCH_CAP_BHI_NO) &&
|
||||
!cpu_matches(cpu_vuln_whitelist, NO_BHI) &&
|
||||
/*
|
||||
* Intel parts with eIBRS are vulnerable to BHI attacks. Parts with
|
||||
* BHI_NO still need to use the BHI mitigation to prevent Intra-mode
|
||||
* attacks. When virtualized, eIBRS could be hidden, assume vulnerable.
|
||||
*/
|
||||
if (!cpu_matches(cpu_vuln_whitelist, NO_BHI) &&
|
||||
(boot_cpu_has(X86_FEATURE_IBRS_ENHANCED) ||
|
||||
boot_cpu_has(X86_FEATURE_HYPERVISOR)))
|
||||
setup_force_cpu_bug(X86_BUG_BHI);
|
||||
|
|
@ -1449,6 +1485,12 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
|
|||
if (cpu_has(c, X86_FEATURE_AMD_IBPB) && !cpu_has(c, X86_FEATURE_AMD_IBPB_RET))
|
||||
setup_force_cpu_bug(X86_BUG_IBPB_NO_RET);
|
||||
|
||||
if (vulnerable_to_its(x86_arch_cap_msr)) {
|
||||
setup_force_cpu_bug(X86_BUG_ITS);
|
||||
if (cpu_matches(cpu_vuln_blacklist, ITS_NATIVE_ONLY))
|
||||
setup_force_cpu_bug(X86_BUG_ITS_NATIVE_ONLY);
|
||||
}
|
||||
|
||||
if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN))
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -1098,15 +1098,17 @@ static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t siz
|
|||
|
||||
static int __init save_microcode_in_initrd(void)
|
||||
{
|
||||
unsigned int cpuid_1_eax = native_cpuid_eax(1);
|
||||
struct cpuinfo_x86 *c = &boot_cpu_data;
|
||||
struct cont_desc desc = { 0 };
|
||||
unsigned int cpuid_1_eax;
|
||||
enum ucode_state ret;
|
||||
struct cpio_data cp;
|
||||
|
||||
if (dis_ucode_ldr || c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10)
|
||||
if (microcode_loader_disabled() || c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10)
|
||||
return 0;
|
||||
|
||||
cpuid_1_eax = native_cpuid_eax(1);
|
||||
|
||||
if (!find_blobs_in_containers(&cp))
|
||||
return -EINVAL;
|
||||
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@
|
|||
|
||||
#include "internal.h"
|
||||
|
||||
static struct microcode_ops *microcode_ops;
|
||||
bool dis_ucode_ldr = true;
|
||||
static struct microcode_ops *microcode_ops;
|
||||
static bool dis_ucode_ldr = false;
|
||||
|
||||
bool force_minrev = IS_ENABLED(CONFIG_MICROCODE_LATE_FORCE_MINREV);
|
||||
module_param(force_minrev, bool, S_IRUSR | S_IWUSR);
|
||||
|
|
@ -84,6 +84,9 @@ static bool amd_check_current_patch_level(void)
|
|||
u32 lvl, dummy, i;
|
||||
u32 *levels;
|
||||
|
||||
if (x86_cpuid_vendor() != X86_VENDOR_AMD)
|
||||
return false;
|
||||
|
||||
native_rdmsr(MSR_AMD64_PATCH_LEVEL, lvl, dummy);
|
||||
|
||||
levels = final_levels;
|
||||
|
|
@ -95,27 +98,29 @@ static bool amd_check_current_patch_level(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool __init check_loader_disabled_bsp(void)
|
||||
bool __init microcode_loader_disabled(void)
|
||||
{
|
||||
static const char *__dis_opt_str = "dis_ucode_ldr";
|
||||
const char *cmdline = boot_command_line;
|
||||
const char *option = __dis_opt_str;
|
||||
|
||||
/*
|
||||
* CPUID(1).ECX[31]: reserved for hypervisor use. This is still not
|
||||
* completely accurate as xen pv guests don't see that CPUID bit set but
|
||||
* that's good enough as they don't land on the BSP path anyway.
|
||||
*/
|
||||
if (native_cpuid_ecx(1) & BIT(31))
|
||||
if (dis_ucode_ldr)
|
||||
return true;
|
||||
|
||||
if (x86_cpuid_vendor() == X86_VENDOR_AMD) {
|
||||
if (amd_check_current_patch_level())
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cmdline_find_option_bool(cmdline, option) <= 0)
|
||||
dis_ucode_ldr = false;
|
||||
/*
|
||||
* Disable when:
|
||||
*
|
||||
* 1) The CPU does not support CPUID.
|
||||
*
|
||||
* 2) Bit 31 in CPUID[1]:ECX is clear
|
||||
* The bit is reserved for hypervisor use. This is still not
|
||||
* completely accurate as XEN PV guests don't see that CPUID bit
|
||||
* set, but that's good enough as they don't land on the BSP
|
||||
* path anyway.
|
||||
*
|
||||
* 3) Certain AMD patch levels are not allowed to be
|
||||
* overwritten.
|
||||
*/
|
||||
if (!have_cpuid_p() ||
|
||||
native_cpuid_ecx(1) & BIT(31) ||
|
||||
amd_check_current_patch_level())
|
||||
dis_ucode_ldr = true;
|
||||
|
||||
return dis_ucode_ldr;
|
||||
}
|
||||
|
|
@ -125,7 +130,10 @@ void __init load_ucode_bsp(void)
|
|||
unsigned int cpuid_1_eax;
|
||||
bool intel = true;
|
||||
|
||||
if (!have_cpuid_p())
|
||||
if (cmdline_find_option_bool(boot_command_line, "dis_ucode_ldr") > 0)
|
||||
dis_ucode_ldr = true;
|
||||
|
||||
if (microcode_loader_disabled())
|
||||
return;
|
||||
|
||||
cpuid_1_eax = native_cpuid_eax(1);
|
||||
|
|
@ -146,9 +154,6 @@ void __init load_ucode_bsp(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (check_loader_disabled_bsp())
|
||||
return;
|
||||
|
||||
if (intel)
|
||||
load_ucode_intel_bsp(&early_data);
|
||||
else
|
||||
|
|
@ -159,6 +164,11 @@ void load_ucode_ap(void)
|
|||
{
|
||||
unsigned int cpuid_1_eax;
|
||||
|
||||
/*
|
||||
* Can't use microcode_loader_disabled() here - .init section
|
||||
* hell. It doesn't have to either - the BSP variant must've
|
||||
* parsed cmdline already anyway.
|
||||
*/
|
||||
if (dis_ucode_ldr)
|
||||
return;
|
||||
|
||||
|
|
@ -810,7 +820,7 @@ static int __init microcode_init(void)
|
|||
struct cpuinfo_x86 *c = &boot_cpu_data;
|
||||
int error;
|
||||
|
||||
if (dis_ucode_ldr)
|
||||
if (microcode_loader_disabled())
|
||||
return -EINVAL;
|
||||
|
||||
if (c->x86_vendor == X86_VENDOR_INTEL)
|
||||
|
|
|
|||
|
|
@ -389,7 +389,7 @@ static int __init save_builtin_microcode(void)
|
|||
if (xchg(&ucode_patch_va, NULL) != UCODE_BSP_LOADED)
|
||||
return 0;
|
||||
|
||||
if (dis_ucode_ldr || boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
|
||||
if (microcode_loader_disabled() || boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
|
||||
return 0;
|
||||
|
||||
uci.mc = get_microcode_blob(&uci, true);
|
||||
|
|
|
|||
|
|
@ -94,7 +94,6 @@ static inline unsigned int x86_cpuid_family(void)
|
|||
return x86_family(eax);
|
||||
}
|
||||
|
||||
extern bool dis_ucode_ldr;
|
||||
extern bool force_minrev;
|
||||
|
||||
#ifdef CONFIG_CPU_SUP_AMD
|
||||
|
|
|
|||
|
|
@ -354,7 +354,7 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size)
|
|||
goto fail;
|
||||
|
||||
ip = trampoline + size;
|
||||
if (cpu_feature_enabled(X86_FEATURE_RETHUNK))
|
||||
if (cpu_wants_rethunk_at(ip))
|
||||
__text_gen_insn(ip, JMP32_INSN_OPCODE, ip, x86_return_thunk, JMP32_INSN_SIZE);
|
||||
else
|
||||
memcpy(ip, retq, sizeof(retq));
|
||||
|
|
|
|||
|
|
@ -145,10 +145,6 @@ void __init __no_stack_protector mk_early_pgtbl_32(void)
|
|||
*ptr = (unsigned long)ptep + PAGE_OFFSET;
|
||||
|
||||
#ifdef CONFIG_MICROCODE_INITRD32
|
||||
/* Running on a hypervisor? */
|
||||
if (native_cpuid_ecx(1) & BIT(31))
|
||||
return;
|
||||
|
||||
params = (struct boot_params *)__pa_nodebug(&boot_params);
|
||||
if (!params->hdr.ramdisk_size || !params->hdr.ramdisk_image)
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -266,6 +266,8 @@ int module_finalize(const Elf_Ehdr *hdr,
|
|||
ibt_endbr = s;
|
||||
}
|
||||
|
||||
its_init_mod(me);
|
||||
|
||||
if (retpolines || cfi) {
|
||||
void *rseg = NULL, *cseg = NULL;
|
||||
unsigned int rsize = 0, csize = 0;
|
||||
|
|
@ -286,6 +288,9 @@ int module_finalize(const Elf_Ehdr *hdr,
|
|||
void *rseg = (void *)retpolines->sh_addr;
|
||||
apply_retpolines(rseg, rseg + retpolines->sh_size);
|
||||
}
|
||||
|
||||
its_fini_mod(me);
|
||||
|
||||
if (returns) {
|
||||
void *rseg = (void *)returns->sh_addr;
|
||||
apply_returns(rseg, rseg + returns->sh_size);
|
||||
|
|
@ -326,4 +331,5 @@ int module_finalize(const Elf_Ehdr *hdr,
|
|||
void module_arch_cleanup(struct module *mod)
|
||||
{
|
||||
alternatives_smp_module_del(mod);
|
||||
its_free_mod(mod);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ static void __ref __static_call_transform(void *insn, enum insn_type type,
|
|||
break;
|
||||
|
||||
case RET:
|
||||
if (cpu_feature_enabled(X86_FEATURE_RETHUNK))
|
||||
if (cpu_wants_rethunk_at(insn))
|
||||
code = text_gen_insn(JMP32_INSN_OPCODE, insn, x86_return_thunk);
|
||||
else
|
||||
code = &retinsn;
|
||||
|
|
@ -90,7 +90,7 @@ static void __ref __static_call_transform(void *insn, enum insn_type type,
|
|||
case JCC:
|
||||
if (!func) {
|
||||
func = __static_call_return;
|
||||
if (cpu_feature_enabled(X86_FEATURE_RETHUNK))
|
||||
if (cpu_wants_rethunk())
|
||||
func = x86_return_thunk;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -466,10 +466,18 @@ SECTIONS
|
|||
}
|
||||
|
||||
/*
|
||||
* The ASSERT() sink to . is intentional, for binutils 2.14 compatibility:
|
||||
* COMPILE_TEST kernels can be large - CONFIG_KASAN, for example, can cause
|
||||
* this. Let's assume that nobody will be running a COMPILE_TEST kernel and
|
||||
* let's assert that fuller build coverage is more valuable than being able to
|
||||
* run a COMPILE_TEST kernel.
|
||||
*/
|
||||
#ifndef CONFIG_COMPILE_TEST
|
||||
/*
|
||||
* The ASSERT() sync to . is intentional, for binutils 2.14 compatibility:
|
||||
*/
|
||||
. = ASSERT((_end - LOAD_OFFSET <= KERNEL_IMAGE_SIZE),
|
||||
"kernel image bigger than KERNEL_IMAGE_SIZE");
|
||||
#endif
|
||||
|
||||
/* needed for Clang - see arch/x86/entry/entry.S */
|
||||
PROVIDE(__ref_stack_chk_guard = __stack_chk_guard);
|
||||
|
|
@ -497,6 +505,16 @@ PROVIDE(__ref_stack_chk_guard = __stack_chk_guard);
|
|||
"SRSO function pair won't alias");
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MITIGATION_ITS) && !defined(CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B)
|
||||
. = ASSERT(__x86_indirect_its_thunk_rax & 0x20, "__x86_indirect_thunk_rax not in second half of cacheline");
|
||||
. = ASSERT(((__x86_indirect_its_thunk_rcx - __x86_indirect_its_thunk_rax) % 64) == 0, "Indirect thunks are not cacheline apart");
|
||||
. = ASSERT(__x86_indirect_its_thunk_array == __x86_indirect_its_thunk_rax, "Gap in ITS thunk array");
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MITIGATION_ITS) && !defined(CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B)
|
||||
. = ASSERT(its_return_thunk & 0x20, "its_return_thunk not in second half of cacheline");
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_X86_64 */
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -104,6 +104,9 @@ void kvm_mmu_track_write(struct kvm_vcpu *vcpu, gpa_t gpa, const u8 *new,
|
|||
|
||||
static inline int kvm_mmu_reload(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (kvm_check_request(KVM_REQ_MMU_FREE_OBSOLETE_ROOTS, vcpu))
|
||||
kvm_mmu_free_obsolete_roots(vcpu);
|
||||
|
||||
/*
|
||||
* Checking root.hpa is sufficient even when KVM has mirror root.
|
||||
* We can have either:
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue