mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-04 04:02:26 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Cross-merge networking fixes after downstream PR. No conflicts or adjacent changes. Link: https://patch.msgid.link/20240801131917.34494-1-pabeni@redhat.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
5fa35bd39c
1
.mailmap
1
.mailmap
@ -260,6 +260,7 @@ Jaegeuk Kim <jaegeuk@kernel.org> <jaegeuk@motorola.com>
|
||||
Jakub Kicinski <kuba@kernel.org> <jakub.kicinski@netronome.com>
|
||||
James Bottomley <jejb@mulgrave.(none)>
|
||||
James Bottomley <jejb@titanic.il.steeleye.com>
|
||||
James Clark <james.clark@linaro.org> <james.clark@arm.com>
|
||||
James E Wilson <wilson@specifix.com>
|
||||
James Hogan <jhogan@kernel.org> <james@albanarts.com>
|
||||
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
|
||||
|
@ -14,9 +14,10 @@ Description:
|
||||
event to its internal Informational Event log, updates the
|
||||
Event Status register, and if configured, interrupts the host.
|
||||
It is not an error to inject poison into an address that
|
||||
already has poison present and no error is returned. The
|
||||
inject_poison attribute is only visible for devices supporting
|
||||
the capability.
|
||||
already has poison present and no error is returned. If the
|
||||
device returns 'Inject Poison Limit Reached' an -EBUSY error
|
||||
is returned to the user. The inject_poison attribute is only
|
||||
visible for devices supporting the capability.
|
||||
|
||||
|
||||
What: /sys/kernel/debug/memX/clear_poison
|
||||
|
@ -3830,9 +3830,6 @@
|
||||
|
||||
noalign [KNL,ARM]
|
||||
|
||||
noaltinstr [S390,EARLY] Disables alternative instructions
|
||||
patching (CPU alternatives feature).
|
||||
|
||||
noapic [SMP,APIC,EARLY] Tells the kernel to not make use of any
|
||||
IOAPICs that may be present in the system.
|
||||
|
||||
|
@ -264,3 +264,5 @@ The following keys are defined:
|
||||
|
||||
* :c:macro:`RISCV_HWPROBE_KEY_HIGHEST_VIRT_ADDRESS`: An unsigned long which
|
||||
represent the highest userspace virtual address usable.
|
||||
|
||||
* :c:macro:`RISCV_HWPROBE_KEY_TIME_CSR_FREQ`: Frequency (in Hz) of `time CSR`.
|
||||
|
@ -47,11 +47,12 @@ RISC-V Linux Kernel SV39
|
||||
| Kernel-space virtual memory, shared between all processes:
|
||||
____________________________________________________________|___________________________________________________________
|
||||
| | | |
|
||||
ffffffc6fea00000 | -228 GB | ffffffc6feffffff | 6 MB | fixmap
|
||||
ffffffc6ff000000 | -228 GB | ffffffc6ffffffff | 16 MB | PCI io
|
||||
ffffffc700000000 | -228 GB | ffffffc7ffffffff | 4 GB | vmemmap
|
||||
ffffffc800000000 | -224 GB | ffffffd7ffffffff | 64 GB | vmalloc/ioremap space
|
||||
ffffffd800000000 | -160 GB | fffffff6ffffffff | 124 GB | direct mapping of all physical memory
|
||||
ffffffc4fea00000 | -236 GB | ffffffc4feffffff | 6 MB | fixmap
|
||||
ffffffc4ff000000 | -236 GB | ffffffc4ffffffff | 16 MB | PCI io
|
||||
ffffffc500000000 | -236 GB | ffffffc5ffffffff | 4 GB | vmemmap
|
||||
ffffffc600000000 | -232 GB | ffffffd5ffffffff | 64 GB | vmalloc/ioremap space
|
||||
ffffffd600000000 | -168 GB | fffffff5ffffffff | 128 GB | direct mapping of all physical memory
|
||||
| | | |
|
||||
fffffff700000000 | -36 GB | fffffffeffffffff | 32 GB | kasan
|
||||
__________________|____________|__________________|_________|____________________________________________________________
|
||||
|
|
||||
|
@ -30,7 +30,7 @@ description: |
|
||||
maintainers:
|
||||
- Mike Leach <mike.leach@linaro.org>
|
||||
- Suzuki K Poulose <suzuki.poulose@arm.com>
|
||||
- James Clark <james.clark@arm.com>
|
||||
- James Clark <james.clark@linaro.org>
|
||||
- Mao Jinlong <quic_jinlmao@quicinc.com>
|
||||
- Hao Zhang <quic_hazha@quicinc.com>
|
||||
|
||||
|
@ -29,7 +29,7 @@ description: |
|
||||
maintainers:
|
||||
- Mike Leach <mike.leach@linaro.org>
|
||||
- Suzuki K Poulose <suzuki.poulose@arm.com>
|
||||
- James Clark <james.clark@arm.com>
|
||||
- James Clark <james.clark@linaro.org>
|
||||
- Mao Jinlong <quic_jinlmao@quicinc.com>
|
||||
- Hao Zhang <quic_hazha@quicinc.com>
|
||||
|
||||
|
@ -14,7 +14,13 @@ allOf:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: samsung,atna33xc20
|
||||
oneOf:
|
||||
# Samsung 13.3" FHD (1920x1080 pixels) eDP AMOLED panel
|
||||
- const: samsung,atna33xc20
|
||||
# Samsung 14.5" WQXGA+ (2880x1800 pixels) eDP AMOLED panel
|
||||
- items:
|
||||
- const: samsung,atna45af01
|
||||
- const: samsung,atna33xc20
|
||||
|
||||
enable-gpios: true
|
||||
port: true
|
||||
|
@ -91,6 +91,7 @@ patternProperties:
|
||||
- const: 0
|
||||
- description: |
|
||||
Shall encode the I3C LVR (Legacy Virtual Register):
|
||||
See include/dt-bindings/i3c/i3c.h
|
||||
bit[31:8]: unused/ignored
|
||||
bit[7:5]: I2C device index. Possible values:
|
||||
* 0: I2C device has a 50 ns spike filter
|
||||
@ -153,6 +154,8 @@ additionalProperties: true
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/i3c/i3c.h>
|
||||
|
||||
i3c@d040000 {
|
||||
compatible = "cdns,i3c-master";
|
||||
clocks = <&coreclock>, <&i3csysclock>;
|
||||
@ -166,7 +169,7 @@ examples:
|
||||
/* I2C device. */
|
||||
eeprom@57 {
|
||||
compatible = "atmel,24c01";
|
||||
reg = <0x57 0x0 0x10>;
|
||||
reg = <0x57 0x0 (I2C_FM | I2C_FILTER)>;
|
||||
pagesize = <0x8>;
|
||||
};
|
||||
|
||||
|
@ -20,7 +20,16 @@ properties:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
minItems: 1
|
||||
items:
|
||||
- description: Core clock
|
||||
- description: APB clock
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: core
|
||||
- const: apb
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
@ -120,9 +120,8 @@ patternProperties:
|
||||
description:
|
||||
Positive input can be connected to pins AIN1 to AIN16 by choosing the
|
||||
appropriate value from 1 to 16. Negative input is connected to AINCOM.
|
||||
items:
|
||||
minimum: 1
|
||||
maximum: 16
|
||||
minimum: 1
|
||||
maximum: 16
|
||||
|
||||
oneOf:
|
||||
- required:
|
||||
|
@ -328,7 +328,9 @@ properties:
|
||||
- renesas,hs3001
|
||||
# Renesas ISL29501 time-of-flight sensor
|
||||
- renesas,isl29501
|
||||
# Rohm DH2228FV
|
||||
# Rohm BH2228FV 8 channel DAC
|
||||
- rohm,bh2228fv
|
||||
# Rohm DH2228FV - This device does not exist, use rohm,bh2228fv instead.
|
||||
- rohm,dh2228fv
|
||||
# S524AD0XF1 (128K/256K-bit Serial EEPROM for Low Power)
|
||||
- samsung,24ad0xd1
|
||||
|
@ -21,6 +21,7 @@ properties:
|
||||
- amlogic,t7-wdt
|
||||
- items:
|
||||
- enum:
|
||||
- amlogic,a4-wdt
|
||||
- amlogic,c3-wdt
|
||||
- amlogic,s4-wdt
|
||||
- const: amlogic,t7-wdt
|
||||
|
@ -9,4 +9,6 @@ Compute Express Link
|
||||
|
||||
memory-devices
|
||||
|
||||
maturity-map
|
||||
|
||||
.. only:: subproject and html
|
||||
|
202
Documentation/driver-api/cxl/maturity-map.rst
Normal file
202
Documentation/driver-api/cxl/maturity-map.rst
Normal file
@ -0,0 +1,202 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
.. include:: <isonum.txt>
|
||||
|
||||
===========================================
|
||||
Compute Express Link Subsystem Maturity Map
|
||||
===========================================
|
||||
|
||||
The Linux CXL subsystem tracks the dynamic `CXL specification
|
||||
<https://computeexpresslink.org/cxl-specification-landing-page>`_ that
|
||||
continues to respond to new use cases with new features, capability
|
||||
updates and fixes. At any given point some aspects of the subsystem are
|
||||
more mature than others. While the periodic pull requests summarize the
|
||||
`work being incorporated each merge window
|
||||
<https://lore.kernel.org/linux-cxl/?q=s%3APULL+s%3ACXL+tc%3Atorvalds+NOT+s%3ARe>`_,
|
||||
those do not always convey progress relative to a starting point and a
|
||||
future end goal.
|
||||
|
||||
What follows is a coarse breakdown of the subsystem's major
|
||||
responsibilities along with a maturity score. The expectation is that
|
||||
the change-history of this document provides an overview summary of the
|
||||
subsystem maturation over time.
|
||||
|
||||
The maturity scores are:
|
||||
|
||||
- [3] Mature: Work in this area is complete and no changes on the horizon.
|
||||
Note that this score can regress from one kernel release to the next
|
||||
based on new test results or end user reports.
|
||||
|
||||
- [2] Stabilizing: Major functionality operational, common cases are
|
||||
mature, but known corner cases are still a work in progress.
|
||||
|
||||
- [1] Initial: Capability that has exited the Proof of Concept phase, but
|
||||
may still have significant gaps to close and fixes to apply as real
|
||||
world testing occurs.
|
||||
|
||||
- [0] Known gap: Feature is on a medium to long term horizon to
|
||||
implement. If the specification has a feature that does not even have
|
||||
a '0' score in this document, there is a good chance that no one in
|
||||
the linux-cxl@vger.kernel.org community has started to look at it.
|
||||
|
||||
- X: Out of scope for kernel enabling, or kernel enabling not required
|
||||
|
||||
Feature and Capabilities
|
||||
========================
|
||||
|
||||
Enumeration / Provisioning
|
||||
--------------------------
|
||||
All of the fundamental enumeration an object model of the subsystem is
|
||||
in place, but there are several corner cases that are pending closure.
|
||||
|
||||
|
||||
* [2] CXL Window Enumeration
|
||||
|
||||
* [0] :ref:`Extended-linear memory-side cache <extended-linear>`
|
||||
* [0] Low Memory-hole
|
||||
* [0] Hetero-interleave
|
||||
|
||||
* [2] Switch Enumeration
|
||||
|
||||
* [0] CXL register enumeration link-up dependency
|
||||
|
||||
* [2] HDM Decoder Configuration
|
||||
|
||||
* [0] Decoder target and granularity constraints
|
||||
|
||||
* [2] Performance enumeration
|
||||
|
||||
* [3] Endpoint CDAT
|
||||
* [3] Switch CDAT
|
||||
* [1] CDAT to Core-mm integration
|
||||
|
||||
* [1] x86
|
||||
* [0] Arm64
|
||||
* [0] All other arch.
|
||||
|
||||
* [0] Shared link
|
||||
|
||||
* [2] Hotplug
|
||||
(see CXL Window Enumeration)
|
||||
|
||||
* [0] Handle Soft Reserved conflicts
|
||||
|
||||
* [0] :ref:`RCH link status <rch-link-status>`
|
||||
* [0] Fabrics / G-FAM (chapter 7)
|
||||
* [0] Global Access Endpoint
|
||||
|
||||
|
||||
RAS
|
||||
---
|
||||
In many ways CXL can be seen as a standardization of what would normally
|
||||
be handled by custom EDAC drivers. The open development here is
|
||||
mainly caused by the enumeration corner cases above.
|
||||
|
||||
* [3] Component events (OS)
|
||||
* [2] Component events (FFM)
|
||||
* [1] Endpoint protocol errors (OS)
|
||||
* [1] Endpoint protocol errors (FFM)
|
||||
* [0] Switch protocol errors (OS)
|
||||
* [1] Switch protocol errors (FFM)
|
||||
* [2] DPA->HPA Address translation
|
||||
|
||||
* [1] XOR Interleave translation
|
||||
(see CXL Window Enumeration)
|
||||
|
||||
* [1] Memory Failure coordination
|
||||
* [0] Scrub control
|
||||
* [2] ACPI error injection EINJ
|
||||
|
||||
* [0] EINJ v2
|
||||
* [X] Compliance DOE
|
||||
|
||||
* [2] Native error injection
|
||||
* [3] RCH error handling
|
||||
* [1] VH error handling
|
||||
* [0] PPR
|
||||
* [0] Sparing
|
||||
* [0] Device built in test
|
||||
|
||||
|
||||
Mailbox commands
|
||||
----------------
|
||||
|
||||
* [3] Firmware update
|
||||
* [3] Health / Alerts
|
||||
* [1] :ref:`Background commands <background-commands>`
|
||||
* [3] Sanitization
|
||||
* [3] Security commands
|
||||
* [3] RAW Command Debug Passthrough
|
||||
* [0] CEL-only-validation Passthrough
|
||||
* [0] Switch CCI
|
||||
* [3] Timestamp
|
||||
* [1] PMEM labels
|
||||
* [0] PMEM GPF / Dirty Shutdown
|
||||
* [0] Scan Media
|
||||
|
||||
PMU
|
||||
---
|
||||
* [1] Type 3 PMU
|
||||
* [0] Switch USP/ DSP, Root Port
|
||||
|
||||
Security
|
||||
--------
|
||||
|
||||
* [X] CXL Trusted Execution Environment Security Protocol (TSP)
|
||||
* [X] CXL IDE (subsumed by TSP)
|
||||
|
||||
Memory-pooling
|
||||
--------------
|
||||
|
||||
* [1] Hotplug of LDs (via PCI hotplug)
|
||||
* [0] Dynamic Capacity Device (DCD) Support
|
||||
|
||||
Multi-host sharing
|
||||
------------------
|
||||
|
||||
* [0] Hardware coherent shared memory
|
||||
* [0] Software managed coherency shared memory
|
||||
|
||||
Multi-host memory
|
||||
-----------------
|
||||
|
||||
* [0] Dynamic Capacity Device Support
|
||||
* [0] Sharing
|
||||
|
||||
Accelerator
|
||||
-----------
|
||||
|
||||
* [0] Accelerator memory enumeration HDM-D (CXL 1.1/2.0 Type-2)
|
||||
* [0] Accelerator memory enumeration HDM-DB (CXL 3.0 Type-2)
|
||||
* [0] CXL.cache 68b (CXL 2.0)
|
||||
* [0] CXL.cache 256b Cache IDs (CXL 3.0)
|
||||
|
||||
User Flow Support
|
||||
-----------------
|
||||
|
||||
* [0] HPA->DPA Address translation (need xormaps export solution)
|
||||
|
||||
Details
|
||||
=======
|
||||
|
||||
.. _extended-linear:
|
||||
|
||||
* **Extended-linear memory-side cache**: An HMAT proposal to enumerate the presence of a
|
||||
memory-side cache where the cache capacity extends the SRAT address
|
||||
range capacity. `See the ECN
|
||||
<https://lore.kernel.org/linux-cxl/6650e4f835a0e_195e294a8@dwillia2-mobl3.amr.corp.intel.com.notmuch/>`_
|
||||
for more details:
|
||||
|
||||
.. _rch-link-status:
|
||||
|
||||
* **RCH Link Status**: RCH (Restricted CXL Host) topologies, end up
|
||||
hiding some standard registers like PCIe Link Status / Capabilities in
|
||||
the CXL RCRB (Root Complex Register Block).
|
||||
|
||||
.. _background-commands:
|
||||
|
||||
* **Background commands**: The CXL background command mechanism is
|
||||
awkward as the single slot is monopolized potentially indefinitely by
|
||||
various commands. A `cancel on conflict
|
||||
<http://lore.kernel.org/r/66035c2e8ba17_770232948b@dwillia2-xfh.jf.intel.com.notmuch>`_
|
||||
facility is needed to make sure the kernel can ensure forward progress
|
||||
of priority commands.
|
@ -8,37 +8,22 @@ and the code documentation when it is automatically generated.
|
||||
DCHUBBUB
|
||||
--------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
|
||||
:doc: overview
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
|
||||
:internal:
|
||||
|
||||
HUBP
|
||||
----
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
|
||||
:doc: overview
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
|
||||
:internal:
|
||||
|
||||
DPP
|
||||
---
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
|
||||
:doc: overview
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
|
||||
:internal:
|
||||
|
||||
MPC
|
||||
@ -47,11 +32,9 @@ MPC
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
|
||||
:doc: overview
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
|
||||
:internal:
|
||||
:no-identifiers: mpcc_blnd_cfg mpcc_alpha_blend_mode
|
||||
|
||||
OPP
|
||||
---
|
||||
@ -59,20 +42,14 @@ OPP
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/opp.h
|
||||
:doc: overview
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/opp.h
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/opp.h
|
||||
:internal:
|
||||
|
||||
DIO
|
||||
---
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.h
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
|
||||
:doc: overview
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.h
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.h
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
|
||||
:internal:
|
||||
|
@ -132,7 +132,7 @@ The DRM blend mode and its elements are then mapped by AMDGPU display manager
|
||||
(MPC), as follows:
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
|
||||
:functions: mpcc_blnd_cfg
|
||||
:identifiers: mpcc_blnd_cfg
|
||||
|
||||
Therefore, the blending configuration for a single MPCC instance on the MPC
|
||||
tree is defined by :c:type:`mpcc_blnd_cfg`, where
|
||||
@ -144,7 +144,7 @@ alpha and plane alpha values. It sets one of the three modes for
|
||||
:c:type:`MPCC_ALPHA_BLND_MODE`, as described below.
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
|
||||
:functions: mpcc_alpha_blend_mode
|
||||
:identifiers: mpcc_alpha_blend_mode
|
||||
|
||||
DM then maps the elements of `enum mpcc_alpha_blend_mode` to those in the DRM
|
||||
blend formula, as follows:
|
||||
|
@ -1753,6 +1753,7 @@ operations:
|
||||
request:
|
||||
attributes:
|
||||
- header
|
||||
- context
|
||||
reply:
|
||||
attributes:
|
||||
- header
|
||||
@ -1761,7 +1762,6 @@ operations:
|
||||
- indir
|
||||
- hkey
|
||||
- input_xfrm
|
||||
dump: *rss-get-op
|
||||
-
|
||||
name: plca-get-cfg
|
||||
doc: Get PLCA params.
|
||||
|
@ -1875,6 +1875,7 @@ Kernel response contents:
|
||||
|
||||
===================================== ====== ==========================
|
||||
``ETHTOOL_A_RSS_HEADER`` nested reply header
|
||||
``ETHTOOL_A_RSS_CONTEXT`` u32 context number
|
||||
``ETHTOOL_A_RSS_HFUNC`` u32 RSS hash func
|
||||
``ETHTOOL_A_RSS_INDIR`` binary Indir table bytes
|
||||
``ETHTOOL_A_RSS_HKEY`` binary Hash key bytes
|
||||
|
@ -89,14 +89,7 @@ docs on :ref:`Building Linux with Clang/LLVM <kbuild_llvm>`.
|
||||
Rust (optional)
|
||||
---------------
|
||||
|
||||
A particular version of the Rust toolchain is required. Newer versions may or
|
||||
may not work because the kernel depends on some unstable Rust features, for
|
||||
the moment.
|
||||
|
||||
Each Rust toolchain comes with several "components", some of which are required
|
||||
(like ``rustc``) and some that are optional. The ``rust-src`` component (which
|
||||
is optional) needs to be installed to build the kernel. Other components are
|
||||
useful for developing.
|
||||
A recent version of the Rust compiler is required.
|
||||
|
||||
Please see Documentation/rust/quick-start.rst for instructions on how to
|
||||
satisfy the build requirements of Rust support. In particular, the ``Makefile``
|
||||
|
@ -7,6 +7,14 @@ This document contains useful information to know when working with
|
||||
the Rust support in the kernel.
|
||||
|
||||
|
||||
``no_std``
|
||||
----------
|
||||
|
||||
The Rust support in the kernel can link only `core <https://doc.rust-lang.org/core/>`_,
|
||||
but not `std <https://doc.rust-lang.org/std/>`_. Crates for use in the
|
||||
kernel must opt into this behavior using the ``#![no_std]`` attribute.
|
||||
|
||||
|
||||
Code documentation
|
||||
------------------
|
||||
|
||||
|
@ -5,17 +5,93 @@ Quick Start
|
||||
|
||||
This document describes how to get started with kernel development in Rust.
|
||||
|
||||
There are a few ways to install a Rust toolchain needed for kernel development.
|
||||
A simple way is to use the packages from your Linux distribution if they are
|
||||
suitable -- the first section below explains this approach. An advantage of this
|
||||
approach is that, typically, the distribution will match the LLVM used by Rust
|
||||
and Clang.
|
||||
|
||||
Another way is using the prebuilt stable versions of LLVM+Rust provided on
|
||||
`kernel.org <https://kernel.org/pub/tools/llvm/rust/>`_. These are the same slim
|
||||
and fast LLVM toolchains from :ref:`Getting LLVM <getting_llvm>` with versions
|
||||
of Rust added to them that Rust for Linux supports. Two sets are provided: the
|
||||
"latest LLVM" and "matching LLVM" (please see the link for more information).
|
||||
|
||||
Alternatively, the next two "Requirements" sections explain each component and
|
||||
how to install them through ``rustup``, the standalone installers from Rust
|
||||
and/or building them.
|
||||
|
||||
The rest of the document explains other aspects on how to get started.
|
||||
|
||||
|
||||
Distributions
|
||||
-------------
|
||||
|
||||
Arch Linux
|
||||
**********
|
||||
|
||||
Arch Linux provides recent Rust releases and thus it should generally work out
|
||||
of the box, e.g.::
|
||||
|
||||
pacman -S rust rust-src rust-bindgen
|
||||
|
||||
|
||||
Debian
|
||||
******
|
||||
|
||||
Debian Unstable (Sid), outside of the freeze period, provides recent Rust
|
||||
releases and thus it should generally work out of the box, e.g.::
|
||||
|
||||
apt install rustc rust-src bindgen rustfmt rust-clippy
|
||||
|
||||
|
||||
Fedora Linux
|
||||
************
|
||||
|
||||
Fedora Linux provides recent Rust releases and thus it should generally work out
|
||||
of the box, e.g.::
|
||||
|
||||
dnf install rust rust-src bindgen-cli rustfmt clippy
|
||||
|
||||
|
||||
Gentoo Linux
|
||||
************
|
||||
|
||||
Gentoo Linux (and especially the testing branch) provides recent Rust releases
|
||||
and thus it should generally work out of the box, e.g.::
|
||||
|
||||
USE='rust-src rustfmt clippy' emerge dev-lang/rust dev-util/bindgen
|
||||
|
||||
``LIBCLANG_PATH`` may need to be set.
|
||||
|
||||
|
||||
Nix
|
||||
***
|
||||
|
||||
Nix (unstable channel) provides recent Rust releases and thus it should
|
||||
generally work out of the box, e.g.::
|
||||
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
pkgs.mkShell {
|
||||
nativeBuildInputs = with pkgs; [ rustc rust-bindgen rustfmt clippy ];
|
||||
RUST_LIB_SRC = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";
|
||||
}
|
||||
|
||||
|
||||
openSUSE
|
||||
********
|
||||
|
||||
openSUSE Slowroll and openSUSE Tumbleweed provide recent Rust releases and thus
|
||||
they should generally work out of the box, e.g.::
|
||||
|
||||
zypper install rust rust1.79-src rust-bindgen clang
|
||||
|
||||
|
||||
Requirements: Building
|
||||
----------------------
|
||||
|
||||
This section explains how to fetch the tools needed for building.
|
||||
|
||||
Some of these requirements might be available from Linux distributions
|
||||
under names like ``rustc``, ``rust-src``, ``rust-bindgen``, etc. However,
|
||||
at the time of writing, they are likely not to be recent enough unless
|
||||
the distribution tracks the latest releases.
|
||||
|
||||
To easily check whether the requirements are met, the following target
|
||||
can be used::
|
||||
|
||||
@ -29,16 +105,15 @@ if that is the case.
|
||||
rustc
|
||||
*****
|
||||
|
||||
A particular version of the Rust compiler is required. Newer versions may or
|
||||
may not work because, for the moment, the kernel depends on some unstable
|
||||
Rust features.
|
||||
A recent version of the Rust compiler is required.
|
||||
|
||||
If ``rustup`` is being used, enter the kernel build directory (or use
|
||||
``--path=<build-dir>`` argument to the ``set`` sub-command) and run::
|
||||
``--path=<build-dir>`` argument to the ``set`` sub-command) and run,
|
||||
for instance::
|
||||
|
||||
rustup override set $(scripts/min-tool-version.sh rustc)
|
||||
rustup override set stable
|
||||
|
||||
This will configure your working directory to use the correct version of
|
||||
This will configure your working directory to use the given version of
|
||||
``rustc`` without affecting your default toolchain.
|
||||
|
||||
Note that the override applies to the current working directory (and its
|
||||
@ -65,9 +140,9 @@ version later on requires re-adding the component.
|
||||
Otherwise, if a standalone installer is used, the Rust source tree may be
|
||||
downloaded into the toolchain's installation folder::
|
||||
|
||||
curl -L "https://static.rust-lang.org/dist/rust-src-$(scripts/min-tool-version.sh rustc).tar.gz" |
|
||||
curl -L "https://static.rust-lang.org/dist/rust-src-$(rustc --version | cut -d' ' -f2).tar.gz" |
|
||||
tar -xzf - -C "$(rustc --print sysroot)/lib" \
|
||||
"rust-src-$(scripts/min-tool-version.sh rustc)/rust-src/lib/" \
|
||||
"rust-src-$(rustc --version | cut -d' ' -f2)/rust-src/lib/" \
|
||||
--strip-components=3
|
||||
|
||||
In this case, upgrading the Rust compiler version later on requires manually
|
||||
@ -101,26 +176,22 @@ bindgen
|
||||
*******
|
||||
|
||||
The bindings to the C side of the kernel are generated at build time using
|
||||
the ``bindgen`` tool. A particular version is required.
|
||||
the ``bindgen`` tool.
|
||||
|
||||
Install it via (note that this will download and build the tool from source)::
|
||||
Install it, for instance, via (note that this will download and build the tool
|
||||
from source)::
|
||||
|
||||
cargo install --locked --version $(scripts/min-tool-version.sh bindgen) bindgen-cli
|
||||
cargo install --locked bindgen-cli
|
||||
|
||||
``bindgen`` needs to find a suitable ``libclang`` in order to work. If it is
|
||||
not found (or a different ``libclang`` than the one found should be used),
|
||||
the process can be tweaked using the environment variables understood by
|
||||
``clang-sys`` (the Rust bindings crate that ``bindgen`` uses to access
|
||||
``libclang``):
|
||||
``bindgen`` uses the ``clang-sys`` crate to find a suitable ``libclang`` (which
|
||||
may be linked statically, dynamically or loaded at runtime). By default, the
|
||||
``cargo`` command above will produce a ``bindgen`` binary that will load
|
||||
``libclang`` at runtime. If it is not found (or a different ``libclang`` than
|
||||
the one found should be used), the process can be tweaked, e.g. by using the
|
||||
``LIBCLANG_PATH`` environment variable. For details, please see ``clang-sys``'s
|
||||
documentation at:
|
||||
|
||||
* ``LLVM_CONFIG_PATH`` can be pointed to an ``llvm-config`` executable.
|
||||
|
||||
* Or ``LIBCLANG_PATH`` can be pointed to a ``libclang`` shared library
|
||||
or to the directory containing it.
|
||||
|
||||
* Or ``CLANG_PATH`` can be pointed to a ``clang`` executable.
|
||||
|
||||
For details, please see ``clang-sys``'s documentation at:
|
||||
https://github.com/KyleMayes/clang-sys#linking
|
||||
|
||||
https://github.com/KyleMayes/clang-sys#environment-variables
|
||||
|
||||
@ -164,20 +235,6 @@ can be installed manually::
|
||||
The standalone installers also come with ``clippy``.
|
||||
|
||||
|
||||
cargo
|
||||
*****
|
||||
|
||||
``cargo`` is the Rust native build system. It is currently required to run
|
||||
the tests since it is used to build a custom standard library that contains
|
||||
the facilities provided by the custom ``alloc`` in the kernel. The tests can
|
||||
be run using the ``rusttest`` Make target.
|
||||
|
||||
If ``rustup`` is being used, all the profiles already install the tool,
|
||||
thus nothing needs to be done.
|
||||
|
||||
The standalone installers also come with ``cargo``.
|
||||
|
||||
|
||||
rustdoc
|
||||
*******
|
||||
|
||||
|
@ -131,9 +131,8 @@ Additionally, there are the ``#[test]`` tests. These can be run using the
|
||||
|
||||
make LLVM=1 rusttest
|
||||
|
||||
This requires the kernel ``.config`` and downloads external repositories. It
|
||||
runs the ``#[test]`` tests on the host (currently) and thus is fairly limited in
|
||||
what these tests can test.
|
||||
This requires the kernel ``.config``. It runs the ``#[test]`` tests on the host
|
||||
(currently) and thus is fairly limited in what these tests can test.
|
||||
|
||||
The Kselftests
|
||||
--------------
|
||||
|
@ -2196,7 +2196,7 @@ N: digicolor
|
||||
ARM/CORESIGHT FRAMEWORK AND DRIVERS
|
||||
M: Suzuki K Poulose <suzuki.poulose@arm.com>
|
||||
R: Mike Leach <mike.leach@linaro.org>
|
||||
R: James Clark <james.clark@arm.com>
|
||||
R: James Clark <james.clark@linaro.org>
|
||||
L: coresight@lists.linaro.org (moderated for non-subscribers)
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
@ -5613,6 +5613,7 @@ M: Ira Weiny <ira.weiny@intel.com>
|
||||
M: Dan Williams <dan.j.williams@intel.com>
|
||||
L: linux-cxl@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/driver-api/cxl
|
||||
F: drivers/cxl/
|
||||
F: include/linux/einj-cxl.h
|
||||
F: include/linux/cxl-event.h
|
||||
@ -10655,6 +10656,7 @@ F: Documentation/ABI/testing/sysfs-bus-i3c
|
||||
F: Documentation/devicetree/bindings/i3c/
|
||||
F: Documentation/driver-api/i3c
|
||||
F: drivers/i3c/
|
||||
F: include/dt-bindings/i3c/
|
||||
F: include/linux/i3c/
|
||||
|
||||
IBM Operation Panel Input Driver
|
||||
@ -15934,6 +15936,7 @@ F: include/linux/in.h
|
||||
F: include/linux/indirect_call_wrapper.h
|
||||
F: include/linux/net.h
|
||||
F: include/linux/netdevice.h
|
||||
F: include/linux/skbuff.h
|
||||
F: include/net/
|
||||
F: include/uapi/linux/in.h
|
||||
F: include/uapi/linux/net.h
|
||||
@ -17894,7 +17897,7 @@ F: tools/perf/
|
||||
PERFORMANCE EVENTS TOOLING ARM64
|
||||
R: John Garry <john.g.garry@oracle.com>
|
||||
R: Will Deacon <will@kernel.org>
|
||||
R: James Clark <james.clark@arm.com>
|
||||
R: James Clark <james.clark@linaro.org>
|
||||
R: Mike Leach <mike.leach@linaro.org>
|
||||
R: Leo Yan <leo.yan@linux.dev>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
@ -18554,7 +18557,7 @@ F: drivers/usb/misc/qcom_eud.c
|
||||
QCOM IPA DRIVER
|
||||
M: Alex Elder <elder@kernel.org>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
S: Maintained
|
||||
F: drivers/net/ipa/
|
||||
|
||||
QEMU MACHINE EMULATOR AND VIRTUALIZER SUPPORT
|
||||
|
34
Makefile
34
Makefile
@ -1,8 +1,8 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 10
|
||||
PATCHLEVEL = 11
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION =
|
||||
EXTRAVERSION = -rc1
|
||||
NAME = Baby Opossum Posse
|
||||
|
||||
# *DOCUMENTATION*
|
||||
@ -445,17 +445,17 @@ KBUILD_USERLDFLAGS := $(USERLDFLAGS)
|
||||
# host programs.
|
||||
export rust_common_flags := --edition=2021 \
|
||||
-Zbinary_dep_depinfo=y \
|
||||
-Dunsafe_op_in_unsafe_fn -Drust_2018_idioms \
|
||||
-Dunreachable_pub -Dnon_ascii_idents \
|
||||
-Dunsafe_op_in_unsafe_fn \
|
||||
-Dnon_ascii_idents \
|
||||
-Wrust_2018_idioms \
|
||||
-Wunreachable_pub \
|
||||
-Wmissing_docs \
|
||||
-Drustdoc::missing_crate_level_docs \
|
||||
-Dclippy::correctness -Dclippy::style \
|
||||
-Dclippy::suspicious -Dclippy::complexity \
|
||||
-Dclippy::perf \
|
||||
-Dclippy::let_unit_value -Dclippy::mut_mut \
|
||||
-Dclippy::needless_bitwise_bool \
|
||||
-Dclippy::needless_continue \
|
||||
-Dclippy::no_mangle_with_rust_abi \
|
||||
-Wrustdoc::missing_crate_level_docs \
|
||||
-Wclippy::all \
|
||||
-Wclippy::mut_mut \
|
||||
-Wclippy::needless_bitwise_bool \
|
||||
-Wclippy::needless_continue \
|
||||
-Wclippy::no_mangle_with_rust_abi \
|
||||
-Wclippy::dbg_macro
|
||||
|
||||
KBUILD_HOSTCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) \
|
||||
@ -493,7 +493,6 @@ RUSTDOC = rustdoc
|
||||
RUSTFMT = rustfmt
|
||||
CLIPPY_DRIVER = clippy-driver
|
||||
BINDGEN = bindgen
|
||||
CARGO = cargo
|
||||
PAHOLE = pahole
|
||||
RESOLVE_BTFIDS = $(objtree)/tools/bpf/resolve_btfids/resolve_btfids
|
||||
LEX = flex
|
||||
@ -559,7 +558,7 @@ KBUILD_RUSTFLAGS := $(rust_common_flags) \
|
||||
-Csymbol-mangling-version=v0 \
|
||||
-Crelocation-model=static \
|
||||
-Zfunction-sections=n \
|
||||
-Dclippy::float_arithmetic
|
||||
-Wclippy::float_arithmetic
|
||||
|
||||
KBUILD_AFLAGS_KERNEL :=
|
||||
KBUILD_CFLAGS_KERNEL :=
|
||||
@ -587,7 +586,7 @@ endif
|
||||
export RUSTC_BOOTSTRAP := 1
|
||||
|
||||
export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC HOSTPKG_CONFIG
|
||||
export RUSTC RUSTDOC RUSTFMT RUSTC_OR_CLIPPY_QUIET RUSTC_OR_CLIPPY BINDGEN CARGO
|
||||
export RUSTC RUSTDOC RUSTFMT RUSTC_OR_CLIPPY_QUIET RUSTC_OR_CLIPPY BINDGEN
|
||||
export HOSTRUSTC KBUILD_HOSTRUSTFLAGS
|
||||
export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL
|
||||
export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX
|
||||
@ -1959,9 +1958,12 @@ quiet_cmd_tags = GEN $@
|
||||
tags TAGS cscope gtags: FORCE
|
||||
$(call cmd,tags)
|
||||
|
||||
# IDE support targets
|
||||
# Generate rust-project.json (a file that describes the structure of non-Cargo
|
||||
# Rust projects) for rust-analyzer (an implementation of the Language Server
|
||||
# Protocol).
|
||||
PHONY += rust-analyzer
|
||||
rust-analyzer:
|
||||
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh
|
||||
$(Q)$(MAKE) $(build)=rust $@
|
||||
|
||||
# Script to generate missing namespace dependencies
|
||||
|
@ -87,6 +87,7 @@ config ARM
|
||||
select HAVE_ARCH_PFN_VALID
|
||||
select HAVE_ARCH_SECCOMP
|
||||
select HAVE_ARCH_SECCOMP_FILTER if AEABI && !OABI_COMPAT
|
||||
select HAVE_ARCH_STACKLEAK
|
||||
select HAVE_ARCH_THREAD_STRUCT_WHITELIST
|
||||
select HAVE_ARCH_TRACEHOOK
|
||||
select HAVE_ARCH_TRANSPARENT_HUGEPAGE if ARM_LPAE
|
||||
@ -116,6 +117,7 @@ config ARM
|
||||
select HAVE_KERNEL_XZ
|
||||
select HAVE_KPROBES if !XIP_KERNEL && !CPU_ENDIAN_BE32 && !CPU_V7M
|
||||
select HAVE_KRETPROBES if HAVE_KPROBES
|
||||
select HAVE_LD_DEAD_CODE_DATA_ELIMINATION
|
||||
select HAVE_MOD_ARCH_SPECIFIC
|
||||
select HAVE_NMI
|
||||
select HAVE_OPTPROBES if !THUMB2_KERNEL
|
||||
@ -736,7 +738,7 @@ config ARM_ERRATA_764319
|
||||
bool "ARM errata: Read to DBGPRSR and DBGOSLSR may generate Undefined instruction"
|
||||
depends on CPU_V7
|
||||
help
|
||||
This option enables the workaround for the 764319 Cortex A-9 erratum.
|
||||
This option enables the workaround for the 764319 Cortex-A9 erratum.
|
||||
CP14 read accesses to the DBGPRSR and DBGOSLSR registers generate an
|
||||
unexpected Undefined Instruction exception when the DBGSWENABLE
|
||||
external pin is set to 0, even when the CP14 accesses are performed
|
||||
|
@ -9,6 +9,7 @@ OBJS =
|
||||
|
||||
HEAD = head.o
|
||||
OBJS += misc.o decompress.o
|
||||
CFLAGS_decompress.o += $(DISABLE_STACKLEAK_PLUGIN)
|
||||
ifeq ($(CONFIG_DEBUG_UNCOMPRESS),y)
|
||||
OBJS += debug.o
|
||||
AFLAGS_head.o += -DDEBUG
|
||||
|
@ -125,7 +125,7 @@ SECTIONS
|
||||
|
||||
. = BSS_START;
|
||||
__bss_start = .;
|
||||
.bss : { *(.bss) }
|
||||
.bss : { *(.bss .bss.*) }
|
||||
_end = .;
|
||||
|
||||
. = ALIGN(8); /* the stack must be 64-bit aligned */
|
||||
|
@ -26,6 +26,13 @@ struct stackframe {
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline bool on_thread_stack(void)
|
||||
{
|
||||
unsigned long delta = current_stack_pointer ^ (unsigned long)current->stack;
|
||||
|
||||
return delta < THREAD_SIZE;
|
||||
}
|
||||
|
||||
static __always_inline
|
||||
void arm_get_current_stackframe(struct pt_regs *regs, struct stackframe *frame)
|
||||
{
|
||||
|
@ -42,7 +42,7 @@
|
||||
#define PROC_INFO \
|
||||
. = ALIGN(4); \
|
||||
__proc_info_begin = .; \
|
||||
*(.proc.info.init) \
|
||||
KEEP(*(.proc.info.init)) \
|
||||
__proc_info_end = .;
|
||||
|
||||
#define IDMAP_TEXT \
|
||||
|
@ -1065,6 +1065,7 @@ vector_addrexcptn:
|
||||
.globl vector_fiq
|
||||
|
||||
.section .vectors, "ax", %progbits
|
||||
.reloc .text, R_ARM_NONE, .
|
||||
W(b) vector_rst
|
||||
W(b) vector_und
|
||||
ARM( .reloc ., R_ARM_LDR_PC_G0, .L__vector_swi )
|
||||
@ -1078,6 +1079,7 @@ THUMB( .reloc ., R_ARM_THM_PC12, .L__vector_swi )
|
||||
|
||||
#ifdef CONFIG_HARDEN_BRANCH_HISTORY
|
||||
.section .vectors.bhb.loop8, "ax", %progbits
|
||||
.reloc .text, R_ARM_NONE, .
|
||||
W(b) vector_rst
|
||||
W(b) vector_bhb_loop8_und
|
||||
ARM( .reloc ., R_ARM_LDR_PC_G0, .L__vector_bhb_loop8_swi )
|
||||
@ -1090,6 +1092,7 @@ THUMB( .reloc ., R_ARM_THM_PC12, .L__vector_bhb_loop8_swi )
|
||||
W(b) vector_bhb_loop8_fiq
|
||||
|
||||
.section .vectors.bhb.bpiall, "ax", %progbits
|
||||
.reloc .text, R_ARM_NONE, .
|
||||
W(b) vector_rst
|
||||
W(b) vector_bhb_bpiall_und
|
||||
ARM( .reloc ., R_ARM_LDR_PC_G0, .L__vector_bhb_bpiall_swi )
|
||||
|
@ -119,6 +119,9 @@ no_work_pending:
|
||||
|
||||
ct_user_enter save = 0
|
||||
|
||||
#ifdef CONFIG_GCC_PLUGIN_STACKLEAK
|
||||
bl stackleak_erase_on_task_stack
|
||||
#endif
|
||||
restore_user_regs fast = 0, offset = 0
|
||||
ENDPROC(ret_to_user_from_irq)
|
||||
ENDPROC(ret_to_user)
|
||||
|
@ -395,11 +395,6 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct mod_unwind_map {
|
||||
const Elf_Shdr *unw_sec;
|
||||
const Elf_Shdr *txt_sec;
|
||||
};
|
||||
|
||||
static const Elf_Shdr *find_mod_section(const Elf32_Ehdr *hdr,
|
||||
const Elf_Shdr *sechdrs, const char *name)
|
||||
{
|
||||
|
@ -85,8 +85,7 @@ static bool
|
||||
callchain_trace(void *data, unsigned long pc)
|
||||
{
|
||||
struct perf_callchain_entry_ctx *entry = data;
|
||||
perf_callchain_store(entry, pc);
|
||||
return true;
|
||||
return perf_callchain_store(entry, pc) == 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -63,7 +63,7 @@ SECTIONS
|
||||
. = ALIGN(4);
|
||||
__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
|
||||
__start___ex_table = .;
|
||||
ARM_MMU_KEEP(*(__ex_table))
|
||||
ARM_MMU_KEEP(KEEP(*(__ex_table)))
|
||||
__stop___ex_table = .;
|
||||
}
|
||||
|
||||
@ -83,7 +83,7 @@ SECTIONS
|
||||
}
|
||||
.init.arch.info : {
|
||||
__arch_info_begin = .;
|
||||
*(.arch.info.init)
|
||||
KEEP(*(.arch.info.init))
|
||||
__arch_info_end = .;
|
||||
}
|
||||
.init.tagtable : {
|
||||
|
@ -74,7 +74,7 @@ SECTIONS
|
||||
. = ALIGN(4);
|
||||
__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
|
||||
__start___ex_table = .;
|
||||
ARM_MMU_KEEP(*(__ex_table))
|
||||
ARM_MMU_KEEP(KEEP(*(__ex_table)))
|
||||
__stop___ex_table = .;
|
||||
}
|
||||
|
||||
@ -99,7 +99,7 @@ SECTIONS
|
||||
}
|
||||
.init.arch.info : {
|
||||
__arch_info_begin = .;
|
||||
*(.arch.info.init)
|
||||
KEEP(*(.arch.info.init))
|
||||
__arch_info_end = .;
|
||||
}
|
||||
.init.tagtable : {
|
||||
@ -116,7 +116,7 @@ SECTIONS
|
||||
#endif
|
||||
.init.pv_table : {
|
||||
__pv_table_begin = .;
|
||||
*(.pv_table)
|
||||
KEEP(*(.pv_table))
|
||||
__pv_table_end = .;
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ int alpine_cpu_wakeup(unsigned int phys_cpu, uint32_t phys_resume_addr)
|
||||
/*
|
||||
* Set CPU resume address -
|
||||
* secure firmware running on boot will jump to this address
|
||||
* after setting proper CPU mode, and initialiing e.g. secure
|
||||
* after setting proper CPU mode, and initializing e.g. secure
|
||||
* regs (the same mode all CPUs are booted to - usually HYP)
|
||||
*/
|
||||
writel(phys_resume_addr,
|
||||
|
@ -17,7 +17,7 @@ void cpu_arm7tdmi_proc_init(void);
|
||||
__ADDRESSABLE(cpu_arm7tdmi_proc_init);
|
||||
void cpu_arm7tdmi_proc_fin(void);
|
||||
__ADDRESSABLE(cpu_arm7tdmi_proc_fin);
|
||||
void cpu_arm7tdmi_reset(void);
|
||||
void cpu_arm7tdmi_reset(unsigned long addr, bool hvc);
|
||||
__ADDRESSABLE(cpu_arm7tdmi_reset);
|
||||
int cpu_arm7tdmi_do_idle(void);
|
||||
__ADDRESSABLE(cpu_arm7tdmi_do_idle);
|
||||
@ -32,7 +32,7 @@ void cpu_arm720_proc_init(void);
|
||||
__ADDRESSABLE(cpu_arm720_proc_init);
|
||||
void cpu_arm720_proc_fin(void);
|
||||
__ADDRESSABLE(cpu_arm720_proc_fin);
|
||||
void cpu_arm720_reset(void);
|
||||
void cpu_arm720_reset(unsigned long addr, bool hvc);
|
||||
__ADDRESSABLE(cpu_arm720_reset);
|
||||
int cpu_arm720_do_idle(void);
|
||||
__ADDRESSABLE(cpu_arm720_do_idle);
|
||||
@ -49,7 +49,7 @@ void cpu_arm740_proc_init(void);
|
||||
__ADDRESSABLE(cpu_arm740_proc_init);
|
||||
void cpu_arm740_proc_fin(void);
|
||||
__ADDRESSABLE(cpu_arm740_proc_fin);
|
||||
void cpu_arm740_reset(void);
|
||||
void cpu_arm740_reset(unsigned long addr, bool hvc);
|
||||
__ADDRESSABLE(cpu_arm740_reset);
|
||||
int cpu_arm740_do_idle(void);
|
||||
__ADDRESSABLE(cpu_arm740_do_idle);
|
||||
@ -64,7 +64,7 @@ void cpu_arm9tdmi_proc_init(void);
|
||||
__ADDRESSABLE(cpu_arm9tdmi_proc_init);
|
||||
void cpu_arm9tdmi_proc_fin(void);
|
||||
__ADDRESSABLE(cpu_arm9tdmi_proc_fin);
|
||||
void cpu_arm9tdmi_reset(void);
|
||||
void cpu_arm9tdmi_reset(unsigned long addr, bool hvc);
|
||||
__ADDRESSABLE(cpu_arm9tdmi_reset);
|
||||
int cpu_arm9tdmi_do_idle(void);
|
||||
__ADDRESSABLE(cpu_arm9tdmi_do_idle);
|
||||
@ -79,7 +79,7 @@ void cpu_arm920_proc_init(void);
|
||||
__ADDRESSABLE(cpu_arm920_proc_init);
|
||||
void cpu_arm920_proc_fin(void);
|
||||
__ADDRESSABLE(cpu_arm920_proc_fin);
|
||||
void cpu_arm920_reset(void);
|
||||
void cpu_arm920_reset(unsigned long addr, bool hvc);
|
||||
__ADDRESSABLE(cpu_arm920_reset);
|
||||
int cpu_arm920_do_idle(void);
|
||||
__ADDRESSABLE(cpu_arm920_do_idle);
|
||||
@ -102,7 +102,7 @@ void cpu_arm922_proc_init(void);
|
||||
__ADDRESSABLE(cpu_arm922_proc_init);
|
||||
void cpu_arm922_proc_fin(void);
|
||||
__ADDRESSABLE(cpu_arm922_proc_fin);
|
||||
void cpu_arm922_reset(void);
|
||||
void cpu_arm922_reset(unsigned long addr, bool hvc);
|
||||
__ADDRESSABLE(cpu_arm922_reset);
|
||||
int cpu_arm922_do_idle(void);
|
||||
__ADDRESSABLE(cpu_arm922_do_idle);
|
||||
@ -119,7 +119,7 @@ void cpu_arm925_proc_init(void);
|
||||
__ADDRESSABLE(cpu_arm925_proc_init);
|
||||
void cpu_arm925_proc_fin(void);
|
||||
__ADDRESSABLE(cpu_arm925_proc_fin);
|
||||
void cpu_arm925_reset(void);
|
||||
void cpu_arm925_reset(unsigned long addr, bool hvc);
|
||||
__ADDRESSABLE(cpu_arm925_reset);
|
||||
int cpu_arm925_do_idle(void);
|
||||
__ADDRESSABLE(cpu_arm925_do_idle);
|
||||
@ -159,7 +159,7 @@ void cpu_arm940_proc_init(void);
|
||||
__ADDRESSABLE(cpu_arm940_proc_init);
|
||||
void cpu_arm940_proc_fin(void);
|
||||
__ADDRESSABLE(cpu_arm940_proc_fin);
|
||||
void cpu_arm940_reset(void);
|
||||
void cpu_arm940_reset(unsigned long addr, bool hvc);
|
||||
__ADDRESSABLE(cpu_arm940_reset);
|
||||
int cpu_arm940_do_idle(void);
|
||||
__ADDRESSABLE(cpu_arm940_do_idle);
|
||||
@ -174,7 +174,7 @@ void cpu_arm946_proc_init(void);
|
||||
__ADDRESSABLE(cpu_arm946_proc_init);
|
||||
void cpu_arm946_proc_fin(void);
|
||||
__ADDRESSABLE(cpu_arm946_proc_fin);
|
||||
void cpu_arm946_reset(void);
|
||||
void cpu_arm946_reset(unsigned long addr, bool hvc);
|
||||
__ADDRESSABLE(cpu_arm946_reset);
|
||||
int cpu_arm946_do_idle(void);
|
||||
__ADDRESSABLE(cpu_arm946_do_idle);
|
||||
@ -429,7 +429,7 @@ void cpu_v7_proc_init(void);
|
||||
__ADDRESSABLE(cpu_v7_proc_init);
|
||||
void cpu_v7_proc_fin(void);
|
||||
__ADDRESSABLE(cpu_v7_proc_fin);
|
||||
void cpu_v7_reset(void);
|
||||
void cpu_v7_reset(unsigned long addr, bool hvc);
|
||||
__ADDRESSABLE(cpu_v7_reset);
|
||||
int cpu_v7_do_idle(void);
|
||||
__ADDRESSABLE(cpu_v7_do_idle);
|
||||
|
@ -168,9 +168,9 @@ config ARM64
|
||||
select HAVE_ARCH_JUMP_LABEL
|
||||
select HAVE_ARCH_JUMP_LABEL_RELATIVE
|
||||
select HAVE_ARCH_KASAN
|
||||
select HAVE_ARCH_KASAN_VMALLOC if HAVE_ARCH_KASAN
|
||||
select HAVE_ARCH_KASAN_SW_TAGS if HAVE_ARCH_KASAN
|
||||
select HAVE_ARCH_KASAN_HW_TAGS if (HAVE_ARCH_KASAN && ARM64_MTE)
|
||||
select HAVE_ARCH_KASAN_VMALLOC
|
||||
select HAVE_ARCH_KASAN_SW_TAGS
|
||||
select HAVE_ARCH_KASAN_HW_TAGS if ARM64_MTE
|
||||
# Some instrumentation may be unsound, hence EXPERT
|
||||
select HAVE_ARCH_KCSAN if EXPERT
|
||||
select HAVE_ARCH_KFENCE
|
||||
@ -211,8 +211,8 @@ config ARM64
|
||||
select HAVE_FTRACE_MCOUNT_RECORD
|
||||
select HAVE_FUNCTION_TRACER
|
||||
select HAVE_FUNCTION_ERROR_INJECTION
|
||||
select HAVE_FUNCTION_GRAPH_RETVAL if HAVE_FUNCTION_GRAPH_TRACER
|
||||
select HAVE_FUNCTION_GRAPH_TRACER
|
||||
select HAVE_FUNCTION_GRAPH_RETVAL
|
||||
select HAVE_GCC_PLUGINS
|
||||
select HAVE_HARDLOCKUP_DETECTOR_PERF if PERF_EVENTS && \
|
||||
HW_PERF_EVENTS && HAVE_PERF_EVENTS_NMI
|
||||
@ -1471,7 +1471,6 @@ config HOTPLUG_CPU
|
||||
config NUMA
|
||||
bool "NUMA Memory Allocation and Scheduler Support"
|
||||
select GENERIC_ARCH_NUMA
|
||||
select ACPI_NUMA if ACPI
|
||||
select OF_NUMA
|
||||
select HAVE_SETUP_PER_CPU_AREA
|
||||
select NEED_PER_CPU_EMBED_FIRST_CHUNK
|
||||
@ -2337,6 +2336,17 @@ config EFI
|
||||
allow the kernel to be booted as an EFI application. This
|
||||
is only useful on systems that have UEFI firmware.
|
||||
|
||||
config COMPRESSED_INSTALL
|
||||
bool "Install compressed image by default"
|
||||
help
|
||||
This makes the regular "make install" install the compressed
|
||||
image we built, not the legacy uncompressed one.
|
||||
|
||||
You can check that a compressed image works for you by doing
|
||||
"make zinstall" first, and verifying that everything is fine
|
||||
in your environment before making "make install" do this for
|
||||
you.
|
||||
|
||||
config DMI
|
||||
bool "Enable support for SMBIOS (DMI) tables"
|
||||
depends on EFI
|
||||
|
@ -182,7 +182,13 @@ $(BOOT_TARGETS): vmlinux
|
||||
Image.%: Image
|
||||
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
|
||||
|
||||
install: KBUILD_IMAGE := $(boot)/Image
|
||||
ifeq ($(CONFIG_COMPRESSED_INSTALL),y)
|
||||
DEFAULT_KBUILD_IMAGE = $(KBUILD_IMAGE)
|
||||
else
|
||||
DEFAULT_KBUILD_IMAGE = $(boot)/Image
|
||||
endif
|
||||
|
||||
install: KBUILD_IMAGE := $(DEFAULT_KBUILD_IMAGE)
|
||||
install zinstall:
|
||||
$(call cmd,install)
|
||||
|
||||
@ -229,7 +235,7 @@ define archhelp
|
||||
echo '* Image.gz - Compressed kernel image (arch/$(ARCH)/boot/Image.gz)'
|
||||
echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
|
||||
echo ' image.fit - Flat Image Tree (arch/$(ARCH)/boot/image.fit)'
|
||||
echo ' install - Install uncompressed kernel'
|
||||
echo ' install - Install kernel (compressed if COMPRESSED_INSTALL set)'
|
||||
echo ' zinstall - Install compressed kernel'
|
||||
echo ' Install using (your) ~/bin/installkernel or'
|
||||
echo ' (distribution) /sbin/installkernel or'
|
||||
|
@ -1065,6 +1065,28 @@ static inline bool pgtable_l5_enabled(void) { return false; }
|
||||
|
||||
#define p4d_offset_kimg(dir,addr) ((p4d_t *)dir)
|
||||
|
||||
static inline
|
||||
p4d_t *p4d_offset_lockless_folded(pgd_t *pgdp, pgd_t pgd, unsigned long addr)
|
||||
{
|
||||
/*
|
||||
* With runtime folding of the pud, pud_offset_lockless() passes
|
||||
* the 'pgd_t *' we return here to p4d_to_folded_pud(), which
|
||||
* will offset the pointer assuming that it points into
|
||||
* a page-table page. However, the fast GUP path passes us a
|
||||
* pgd_t allocated on the stack and so we must use the original
|
||||
* pointer in 'pgdp' to construct the p4d pointer instead of
|
||||
* using the generic p4d_offset_lockless() implementation.
|
||||
*
|
||||
* Note: reusing the original pointer means that we may
|
||||
* dereference the same (live) page-table entry multiple times.
|
||||
* This is safe because it is still only loaded once in the
|
||||
* context of each level and the CPU guarantees same-address
|
||||
* read-after-read ordering.
|
||||
*/
|
||||
return p4d_offset(pgdp, addr);
|
||||
}
|
||||
#define p4d_offset_lockless p4d_offset_lockless_folded
|
||||
|
||||
#endif /* CONFIG_PGTABLE_LEVELS > 4 */
|
||||
|
||||
#define pgd_ERROR(e) \
|
||||
|
@ -21,7 +21,7 @@ btildflags-$(CONFIG_ARM64_BTI_KERNEL) += -z force-bti
|
||||
# potential future proofing if we end up with internal calls to the exported
|
||||
# routines, as x86 does (see 6f121e548f83 ("x86, vdso: Reimplement vdso.so
|
||||
# preparation in build-time C")).
|
||||
ldflags-y := -shared -soname=linux-vdso.so.1 --hash-style=sysv \
|
||||
ldflags-y := -shared -soname=linux-vdso.so.1 \
|
||||
-Bsymbolic --build-id=sha1 -n $(btildflags-y)
|
||||
|
||||
ifdef CONFIG_LD_ORPHAN_WARN
|
||||
|
@ -98,7 +98,7 @@ VDSO_AFLAGS += -D__ASSEMBLY__
|
||||
# From arm vDSO Makefile
|
||||
VDSO_LDFLAGS += -Bsymbolic --no-undefined -soname=linux-vdso.so.1
|
||||
VDSO_LDFLAGS += -z max-page-size=4096 -z common-page-size=4096
|
||||
VDSO_LDFLAGS += -shared --hash-style=sysv --build-id=sha1
|
||||
VDSO_LDFLAGS += -shared --build-id=sha1
|
||||
VDSO_LDFLAGS += --orphan-handling=$(CONFIG_LD_ORPHAN_WARN_LEVEL)
|
||||
|
||||
|
||||
|
@ -149,7 +149,7 @@ Res0 63:32
|
||||
UnsignedEnum 31:28 GIC
|
||||
0b0000 NI
|
||||
0b0001 GICv3
|
||||
0b0010 GICv4p1
|
||||
0b0011 GICv4p1
|
||||
EndEnum
|
||||
UnsignedEnum 27:24 Virt_frac
|
||||
0b0000 NI
|
||||
@ -903,7 +903,7 @@ EndEnum
|
||||
UnsignedEnum 27:24 GIC
|
||||
0b0000 NI
|
||||
0b0001 IMP
|
||||
0b0010 V4P1
|
||||
0b0011 V4P1
|
||||
EndEnum
|
||||
SignedEnum 23:20 AdvSIMD
|
||||
0b0000 IMP
|
||||
|
@ -476,7 +476,6 @@ config NR_CPUS
|
||||
config NUMA
|
||||
bool "NUMA Support"
|
||||
select SMP
|
||||
select ACPI_NUMA if ACPI
|
||||
help
|
||||
Say Y to compile the kernel with NUMA (Non-Uniform Memory Access)
|
||||
support. This option improves performance on systems with more
|
||||
|
@ -1984,8 +1984,10 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
|
||||
break;
|
||||
|
||||
r = -ENXIO;
|
||||
if (!xive_enabled())
|
||||
if (!xive_enabled()) {
|
||||
fdput(f);
|
||||
break;
|
||||
}
|
||||
|
||||
r = -EPERM;
|
||||
dev = kvm_device_from_filp(f.file);
|
||||
|
@ -559,9 +559,7 @@ bool __init xive_native_init(void)
|
||||
struct device_node *np;
|
||||
struct resource r;
|
||||
void __iomem *tima;
|
||||
struct property *prop;
|
||||
u8 max_prio = 7;
|
||||
const __be32 *p;
|
||||
u32 val, cpu;
|
||||
s64 rc;
|
||||
|
||||
@ -592,7 +590,7 @@ bool __init xive_native_init(void)
|
||||
max_prio = val - 1;
|
||||
|
||||
/* Iterate the EQ sizes and pick one */
|
||||
of_property_for_each_u32(np, "ibm,xive-eq-sizes", prop, p, val) {
|
||||
of_property_for_each_u32(np, "ibm,xive-eq-sizes", val) {
|
||||
xive_queue_shift = val;
|
||||
if (val == PAGE_SHIFT)
|
||||
break;
|
||||
|
@ -814,7 +814,6 @@ bool __init xive_spapr_init(void)
|
||||
struct device_node *np;
|
||||
struct resource r;
|
||||
void __iomem *tima;
|
||||
struct property *prop;
|
||||
u8 max_prio;
|
||||
u32 val;
|
||||
u32 len;
|
||||
@ -866,7 +865,7 @@ bool __init xive_spapr_init(void)
|
||||
}
|
||||
|
||||
/* Iterate the EQ sizes and pick one */
|
||||
of_property_for_each_u32(np, "ibm,xive-eq-sizes", prop, reg, val) {
|
||||
of_property_for_each_u32(np, "ibm,xive-eq-sizes", val) {
|
||||
xive_queue_shift = val;
|
||||
if (val == PAGE_SHIFT)
|
||||
break;
|
||||
|
@ -13,7 +13,9 @@ config 32BIT
|
||||
config RISCV
|
||||
def_bool y
|
||||
select ACPI_GENERIC_GSI if ACPI
|
||||
select ACPI_PPTT if ACPI
|
||||
select ACPI_REDUCED_HARDWARE_ONLY if ACPI
|
||||
select ACPI_SPCR_TABLE if ACPI
|
||||
select ARCH_DMA_DEFAULT_COHERENT
|
||||
select ARCH_ENABLE_HUGEPAGE_MIGRATION if HUGETLB_PAGE && MIGRATION
|
||||
select ARCH_ENABLE_MEMORY_HOTPLUG if SPARSEMEM_VMEMMAP
|
||||
@ -123,6 +125,7 @@ config RISCV
|
||||
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
|
||||
select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
|
||||
select HAVE_ARCH_SECCOMP_FILTER
|
||||
select HAVE_ARCH_STACKLEAK
|
||||
select HAVE_ARCH_THREAD_STRUCT_WHITELIST
|
||||
select HAVE_ARCH_TRACEHOOK
|
||||
select HAVE_ARCH_TRANSPARENT_HUGEPAGE if 64BIT && MMU
|
||||
@ -154,7 +157,6 @@ config RISCV
|
||||
select HAVE_KERNEL_UNCOMPRESSED if !XIP_KERNEL && !EFI_ZBOOT
|
||||
select HAVE_KERNEL_ZSTD if !XIP_KERNEL && !EFI_ZBOOT
|
||||
select HAVE_KPROBES if !XIP_KERNEL
|
||||
select HAVE_KPROBES_ON_FTRACE if !XIP_KERNEL
|
||||
select HAVE_KRETPROBES if !XIP_KERNEL
|
||||
# https://github.com/ClangBuiltLinux/linux/issues/1881
|
||||
select HAVE_LD_DEAD_CODE_DATA_ELIMINATION if !LD_IS_LLD
|
||||
@ -820,6 +822,8 @@ config RISCV_EFFICIENT_UNALIGNED_ACCESS
|
||||
|
||||
endchoice
|
||||
|
||||
source "arch/riscv/Kconfig.vendor"
|
||||
|
||||
endmenu # "Platform type"
|
||||
|
||||
menu "Kernel features"
|
||||
|
19
arch/riscv/Kconfig.vendor
Normal file
19
arch/riscv/Kconfig.vendor
Normal file
@ -0,0 +1,19 @@
|
||||
menu "Vendor extensions"
|
||||
|
||||
config RISCV_ISA_VENDOR_EXT
|
||||
bool
|
||||
|
||||
menu "Andes"
|
||||
config RISCV_ISA_VENDOR_EXT_ANDES
|
||||
bool "Andes vendor extension support"
|
||||
select RISCV_ISA_VENDOR_EXT
|
||||
default y
|
||||
help
|
||||
Say N here if you want to disable all Andes vendor extension
|
||||
support. This will cause any Andes vendor extensions that are
|
||||
requested by hardware probing to be ignored.
|
||||
|
||||
If you don't know what to do here, say Y.
|
||||
endmenu
|
||||
|
||||
endmenu
|
@ -18,7 +18,6 @@ OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
|
||||
OBJCOPYFLAGS_loader.bin :=-O binary
|
||||
OBJCOPYFLAGS_xipImage :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
|
||||
|
||||
targets := Image Image.* loader loader.o loader.lds loader.bin
|
||||
targets := Image Image.* loader loader.o loader.lds loader.bin xipImage
|
||||
|
||||
ifeq ($(CONFIG_XIP_KERNEL),y)
|
||||
|
@ -7,6 +7,7 @@ CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_CGROUPS=y
|
||||
CONFIG_MEMCG=y
|
||||
CONFIG_BLK_CGROUP=y
|
||||
CONFIG_CGROUP_SCHED=y
|
||||
CONFIG_CFS_BANDWIDTH=y
|
||||
CONFIG_RT_GROUP_SCHED=y
|
||||
@ -35,9 +36,6 @@ CONFIG_ARCH_THEAD=y
|
||||
CONFIG_ARCH_VIRT=y
|
||||
CONFIG_ARCH_CANAAN=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_HOTPLUG_CPU=y
|
||||
CONFIG_PM=y
|
||||
CONFIG_CPU_IDLE=y
|
||||
CONFIG_CPU_FREQ=y
|
||||
CONFIG_CPU_FREQ_STAT=y
|
||||
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
|
||||
@ -52,13 +50,11 @@ CONFIG_ACPI=y
|
||||
CONFIG_JUMP_LABEL=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_SPARSEMEM_MANUAL=y
|
||||
CONFIG_BLK_DEV_THROTTLING=y
|
||||
CONFIG_SPARSEMEM_MANUAL=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_XFRM_USER=m
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_IP_ADVANCED_ROUTER=y
|
||||
CONFIG_IP_PNP=y
|
||||
@ -102,9 +98,9 @@ CONFIG_NET_SCHED=y
|
||||
CONFIG_NET_CLS_CGROUP=m
|
||||
CONFIG_NETLINK_DIAG=y
|
||||
CONFIG_CGROUP_NET_PRIO=y
|
||||
CONFIG_CAN=m
|
||||
CONFIG_NET_9P=y
|
||||
CONFIG_NET_9P_VIRTIO=y
|
||||
CONFIG_CAN=m
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCIEPORTBUS=y
|
||||
CONFIG_PCI_HOST_GENERIC=y
|
||||
@ -153,8 +149,8 @@ CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
CONFIG_SERIAL_8250_DW=y
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
CONFIG_SERIAL_SH_SCI=y
|
||||
CONFIG_SERIAL_EARLYCON_RISCV_SBI=y
|
||||
CONFIG_SERIAL_SH_SCI=y
|
||||
CONFIG_VIRTIO_CONSOLE=y
|
||||
CONFIG_HW_RANDOM=y
|
||||
CONFIG_HW_RANDOM_VIRTIO=y
|
||||
@ -179,7 +175,6 @@ CONFIG_DEVFREQ_THERMAL=y
|
||||
CONFIG_RZG2L_THERMAL=y
|
||||
CONFIG_WATCHDOG=y
|
||||
CONFIG_SUNXI_WATCHDOG=y
|
||||
CONFIG_RENESAS_RZG2LWDT=y
|
||||
CONFIG_MFD_AXP20X_I2C=y
|
||||
CONFIG_REGULATOR=y
|
||||
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
||||
@ -193,11 +188,9 @@ CONFIG_DRM_NOUVEAU=m
|
||||
CONFIG_DRM_SUN4I=m
|
||||
CONFIG_DRM_VIRTIO_GPU=m
|
||||
CONFIG_FB=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_SOUND=y
|
||||
CONFIG_SND=y
|
||||
CONFIG_SND_SOC=y
|
||||
CONFIG_SND_SOC_RZ=m
|
||||
CONFIG_SND_DESIGNWARE_I2S=m
|
||||
CONFIG_SND_SOC_STARFIVE=m
|
||||
CONFIG_SND_SOC_JH7110_PWMDAC=m
|
||||
@ -239,34 +232,31 @@ CONFIG_USB_CONFIGFS_F_FS=y
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
CONFIG_MMC_SDHCI_CADENCE=y
|
||||
CONFIG_MMC_SDHCI_OF_DWCMSHC=y
|
||||
CONFIG_MMC_SDHCI_CADENCE=y
|
||||
CONFIG_MMC_SPI=y
|
||||
CONFIG_MMC_SDHI=y
|
||||
CONFIG_MMC_DW=y
|
||||
CONFIG_MMC_DW_STARFIVE=y
|
||||
CONFIG_MMC_SDHI=y
|
||||
CONFIG_MMC_SUNXI=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_SUN6I=y
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_DMA_SUN6I=m
|
||||
CONFIG_DW_AXI_DMAC=y
|
||||
CONFIG_RZ_DMAC=y
|
||||
CONFIG_VIRTIO_PCI=y
|
||||
CONFIG_VIRTIO_BALLOON=y
|
||||
CONFIG_VIRTIO_INPUT=y
|
||||
CONFIG_VIRTIO_MMIO=y
|
||||
CONFIG_RENESAS_OSTM=y
|
||||
CONFIG_CLK_SOPHGO_CV1800=y
|
||||
CONFIG_SUN8I_DE2_CCU=m
|
||||
CONFIG_RENESAS_OSTM=y
|
||||
CONFIG_SUN50I_IOMMU=y
|
||||
CONFIG_RPMSG_CHAR=y
|
||||
CONFIG_RPMSG_CTRL=y
|
||||
CONFIG_RPMSG_VIRTIO=y
|
||||
CONFIG_ARCH_R9A07G043=y
|
||||
CONFIG_PM_DEVFREQ=y
|
||||
CONFIG_IIO=y
|
||||
CONFIG_RZG2L_ADC=m
|
||||
CONFIG_RESET_RZG2L_USBPHY_CTRL=y
|
||||
CONFIG_PHY_SUN4I_USB=m
|
||||
CONFIG_PHY_RCAR_GEN3_USB2=y
|
||||
CONFIG_PHY_STARFIVE_JH7110_DPHY_RX=m
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <asm/processor.h>
|
||||
#include <asm/sbi.h>
|
||||
#include <asm/vendorid_list.h>
|
||||
#include <asm/vendor_extensions.h>
|
||||
|
||||
#define ANDES_AX45MP_MARCHID 0x8000000000008a45UL
|
||||
#define ANDES_AX45MP_MIMPID 0x500UL
|
||||
@ -65,6 +66,8 @@ void __init_or_module andes_errata_patch_func(struct alt_entry *begin, struct al
|
||||
unsigned long archid, unsigned long impid,
|
||||
unsigned int stage)
|
||||
{
|
||||
BUILD_BUG_ON(ERRATA_ANDES_NUMBER >= RISCV_VENDOR_EXT_ALTERNATIVES_BASE);
|
||||
|
||||
if (stage == RISCV_ALTERNATIVES_BOOT)
|
||||
errata_probe_iocp(stage, archid, impid);
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <asm/alternative.h>
|
||||
#include <asm/vendorid_list.h>
|
||||
#include <asm/errata_list.h>
|
||||
#include <asm/vendor_extensions.h>
|
||||
|
||||
struct errata_info_t {
|
||||
char name[32];
|
||||
@ -96,6 +97,8 @@ void sifive_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
|
||||
u32 cpu_apply_errata = 0;
|
||||
u32 tmp;
|
||||
|
||||
BUILD_BUG_ON(ERRATA_SIFIVE_NUMBER >= RISCV_VENDOR_EXT_ALTERNATIVES_BASE);
|
||||
|
||||
if (stage == RISCV_ALTERNATIVES_EARLY_BOOT)
|
||||
return;
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <asm/io.h>
|
||||
#include <asm/patch.h>
|
||||
#include <asm/vendorid_list.h>
|
||||
#include <asm/vendor_extensions.h>
|
||||
|
||||
#define CSR_TH_SXSTATUS 0x5c0
|
||||
#define SXSTATUS_MAEE _AC(0x200000, UL)
|
||||
@ -166,6 +167,8 @@ void thead_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
|
||||
u32 tmp;
|
||||
void *oldptr, *altptr;
|
||||
|
||||
BUILD_BUG_ON(ERRATA_THEAD_NUMBER >= RISCV_VENDOR_EXT_ALTERNATIVES_BASE);
|
||||
|
||||
for (alt = begin; alt < end; alt++) {
|
||||
if (alt->vendor_id != THEAD_VENDOR_ID)
|
||||
continue;
|
||||
|
@ -61,11 +61,14 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
|
||||
|
||||
void acpi_init_rintc_map(void);
|
||||
struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu);
|
||||
u32 get_acpi_id_for_cpu(int cpu);
|
||||
static inline u32 get_acpi_id_for_cpu(int cpu)
|
||||
{
|
||||
return acpi_cpu_get_madt_rintc(cpu)->uid;
|
||||
}
|
||||
|
||||
int acpi_get_riscv_isa(struct acpi_table_header *table,
|
||||
unsigned int cpu, const char **isa);
|
||||
|
||||
static inline int acpi_numa_get_nid(unsigned int cpu) { return NUMA_NO_NODE; }
|
||||
void acpi_get_cbo_block_size(struct acpi_table_header *table, u32 *cbom_size,
|
||||
u32 *cboz_size, u32 *cbop_size);
|
||||
#else
|
||||
@ -87,4 +90,12 @@ static inline void acpi_get_cbo_block_size(struct acpi_table_header *table,
|
||||
|
||||
#endif /* CONFIG_ACPI */
|
||||
|
||||
#ifdef CONFIG_ACPI_NUMA
|
||||
int acpi_numa_get_nid(unsigned int cpu);
|
||||
void acpi_map_cpus_to_nodes(void);
|
||||
#else
|
||||
static inline int acpi_numa_get_nid(unsigned int cpu) { return NUMA_NO_NODE; }
|
||||
static inline void acpi_map_cpus_to_nodes(void) { }
|
||||
#endif /* CONFIG_ACPI_NUMA */
|
||||
|
||||
#endif /*_ASM_ACPI_H*/
|
||||
|
@ -170,7 +170,7 @@ static __always_inline int variable_fls(unsigned int x)
|
||||
({ \
|
||||
typeof(x) x_ = (x); \
|
||||
__builtin_constant_p(x_) ? \
|
||||
(int)((x_ != 0) ? (32 - __builtin_clz(x_)) : 0) \
|
||||
((x_ != 0) ? (32 - __builtin_clz(x_)) : 0) \
|
||||
: \
|
||||
variable_fls(x_); \
|
||||
})
|
||||
|
@ -33,6 +33,31 @@ extern struct riscv_isainfo hart_isa[NR_CPUS];
|
||||
|
||||
void riscv_user_isa_enable(void);
|
||||
|
||||
#define _RISCV_ISA_EXT_DATA(_name, _id, _subset_exts, _subset_exts_size, _validate) { \
|
||||
.name = #_name, \
|
||||
.property = #_name, \
|
||||
.id = _id, \
|
||||
.subset_ext_ids = _subset_exts, \
|
||||
.subset_ext_size = _subset_exts_size, \
|
||||
.validate = _validate \
|
||||
}
|
||||
|
||||
#define __RISCV_ISA_EXT_DATA(_name, _id) _RISCV_ISA_EXT_DATA(_name, _id, NULL, 0, NULL)
|
||||
|
||||
#define __RISCV_ISA_EXT_DATA_VALIDATE(_name, _id, _validate) \
|
||||
_RISCV_ISA_EXT_DATA(_name, _id, NULL, 0, _validate)
|
||||
|
||||
/* Used to declare pure "lasso" extension (Zk for instance) */
|
||||
#define __RISCV_ISA_EXT_BUNDLE(_name, _bundled_exts) \
|
||||
_RISCV_ISA_EXT_DATA(_name, RISCV_ISA_EXT_INVALID, _bundled_exts, \
|
||||
ARRAY_SIZE(_bundled_exts), NULL)
|
||||
|
||||
/* Used to declare extensions that are a superset of other extensions (Zvbb for instance) */
|
||||
#define __RISCV_ISA_EXT_SUPERSET(_name, _id, _sub_exts) \
|
||||
_RISCV_ISA_EXT_DATA(_name, _id, _sub_exts, ARRAY_SIZE(_sub_exts), NULL)
|
||||
#define __RISCV_ISA_EXT_SUPERSET_VALIDATE(_name, _id, _sub_exts, _validate) \
|
||||
_RISCV_ISA_EXT_DATA(_name, _id, _sub_exts, ARRAY_SIZE(_sub_exts), _validate)
|
||||
|
||||
#if defined(CONFIG_RISCV_MISALIGNED)
|
||||
bool check_unaligned_access_emulated_all_cpus(void);
|
||||
void unaligned_emulation_finish(void);
|
||||
@ -79,59 +104,66 @@ extern bool riscv_isa_fallback;
|
||||
|
||||
unsigned long riscv_isa_extension_base(const unsigned long *isa_bitmap);
|
||||
|
||||
#define STANDARD_EXT 0
|
||||
|
||||
bool __riscv_isa_extension_available(const unsigned long *isa_bitmap, unsigned int bit);
|
||||
#define riscv_isa_extension_available(isa_bitmap, ext) \
|
||||
__riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_##ext)
|
||||
|
||||
static __always_inline bool
|
||||
riscv_has_extension_likely(const unsigned long ext)
|
||||
static __always_inline bool __riscv_has_extension_likely(const unsigned long vendor,
|
||||
const unsigned long ext)
|
||||
{
|
||||
compiletime_assert(ext < RISCV_ISA_EXT_MAX,
|
||||
"ext must be < RISCV_ISA_EXT_MAX");
|
||||
|
||||
if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE)) {
|
||||
asm goto(
|
||||
ALTERNATIVE("j %l[l_no]", "nop", 0, %[ext], 1)
|
||||
:
|
||||
: [ext] "i" (ext)
|
||||
:
|
||||
: l_no);
|
||||
} else {
|
||||
if (!__riscv_isa_extension_available(NULL, ext))
|
||||
goto l_no;
|
||||
}
|
||||
asm goto(ALTERNATIVE("j %l[l_no]", "nop", %[vendor], %[ext], 1)
|
||||
:
|
||||
: [vendor] "i" (vendor), [ext] "i" (ext)
|
||||
:
|
||||
: l_no);
|
||||
|
||||
return true;
|
||||
l_no:
|
||||
return false;
|
||||
}
|
||||
|
||||
static __always_inline bool
|
||||
riscv_has_extension_unlikely(const unsigned long ext)
|
||||
static __always_inline bool __riscv_has_extension_unlikely(const unsigned long vendor,
|
||||
const unsigned long ext)
|
||||
{
|
||||
compiletime_assert(ext < RISCV_ISA_EXT_MAX,
|
||||
"ext must be < RISCV_ISA_EXT_MAX");
|
||||
|
||||
if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE)) {
|
||||
asm goto(
|
||||
ALTERNATIVE("nop", "j %l[l_yes]", 0, %[ext], 1)
|
||||
:
|
||||
: [ext] "i" (ext)
|
||||
:
|
||||
: l_yes);
|
||||
} else {
|
||||
if (__riscv_isa_extension_available(NULL, ext))
|
||||
goto l_yes;
|
||||
}
|
||||
asm goto(ALTERNATIVE("nop", "j %l[l_yes]", %[vendor], %[ext], 1)
|
||||
:
|
||||
: [vendor] "i" (vendor), [ext] "i" (ext)
|
||||
:
|
||||
: l_yes);
|
||||
|
||||
return false;
|
||||
l_yes:
|
||||
return true;
|
||||
}
|
||||
|
||||
static __always_inline bool riscv_has_extension_unlikely(const unsigned long ext)
|
||||
{
|
||||
compiletime_assert(ext < RISCV_ISA_EXT_MAX, "ext must be < RISCV_ISA_EXT_MAX");
|
||||
|
||||
if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE))
|
||||
return __riscv_has_extension_unlikely(STANDARD_EXT, ext);
|
||||
|
||||
return __riscv_isa_extension_available(NULL, ext);
|
||||
}
|
||||
|
||||
static __always_inline bool riscv_has_extension_likely(const unsigned long ext)
|
||||
{
|
||||
compiletime_assert(ext < RISCV_ISA_EXT_MAX, "ext must be < RISCV_ISA_EXT_MAX");
|
||||
|
||||
if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE))
|
||||
return __riscv_has_extension_likely(STANDARD_EXT, ext);
|
||||
|
||||
return __riscv_isa_extension_available(NULL, ext);
|
||||
}
|
||||
|
||||
static __always_inline bool riscv_cpu_has_extension_likely(int cpu, const unsigned long ext)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE) && riscv_has_extension_likely(ext))
|
||||
compiletime_assert(ext < RISCV_ISA_EXT_MAX, "ext must be < RISCV_ISA_EXT_MAX");
|
||||
|
||||
if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE) &&
|
||||
__riscv_has_extension_likely(STANDARD_EXT, ext))
|
||||
return true;
|
||||
|
||||
return __riscv_isa_extension_available(hart_isa[cpu].isa, ext);
|
||||
@ -139,7 +171,10 @@ static __always_inline bool riscv_cpu_has_extension_likely(int cpu, const unsign
|
||||
|
||||
static __always_inline bool riscv_cpu_has_extension_unlikely(int cpu, const unsigned long ext)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE) && riscv_has_extension_unlikely(ext))
|
||||
compiletime_assert(ext < RISCV_ISA_EXT_MAX, "ext must be < RISCV_ISA_EXT_MAX");
|
||||
|
||||
if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE) &&
|
||||
__riscv_has_extension_unlikely(STANDARD_EXT, ext))
|
||||
return true;
|
||||
|
||||
return __riscv_isa_extension_available(hart_isa[cpu].isa, ext);
|
||||
|
@ -80,19 +80,18 @@
|
||||
#define RISCV_ISA_EXT_ZFA 71
|
||||
#define RISCV_ISA_EXT_ZTSO 72
|
||||
#define RISCV_ISA_EXT_ZACAS 73
|
||||
#define RISCV_ISA_EXT_XANDESPMU 74
|
||||
#define RISCV_ISA_EXT_ZVE32X 75
|
||||
#define RISCV_ISA_EXT_ZVE32F 76
|
||||
#define RISCV_ISA_EXT_ZVE64X 77
|
||||
#define RISCV_ISA_EXT_ZVE64F 78
|
||||
#define RISCV_ISA_EXT_ZVE64D 79
|
||||
#define RISCV_ISA_EXT_ZIMOP 80
|
||||
#define RISCV_ISA_EXT_ZCA 81
|
||||
#define RISCV_ISA_EXT_ZCB 82
|
||||
#define RISCV_ISA_EXT_ZCD 83
|
||||
#define RISCV_ISA_EXT_ZCF 84
|
||||
#define RISCV_ISA_EXT_ZCMOP 85
|
||||
#define RISCV_ISA_EXT_ZAWRS 86
|
||||
#define RISCV_ISA_EXT_ZVE32X 74
|
||||
#define RISCV_ISA_EXT_ZVE32F 75
|
||||
#define RISCV_ISA_EXT_ZVE64X 76
|
||||
#define RISCV_ISA_EXT_ZVE64F 77
|
||||
#define RISCV_ISA_EXT_ZVE64D 78
|
||||
#define RISCV_ISA_EXT_ZIMOP 79
|
||||
#define RISCV_ISA_EXT_ZCA 80
|
||||
#define RISCV_ISA_EXT_ZCB 81
|
||||
#define RISCV_ISA_EXT_ZCD 82
|
||||
#define RISCV_ISA_EXT_ZCF 83
|
||||
#define RISCV_ISA_EXT_ZCMOP 84
|
||||
#define RISCV_ISA_EXT_ZAWRS 85
|
||||
|
||||
#define RISCV_ISA_EXT_XLINUXENVCFG 127
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include <uapi/asm/hwprobe.h>
|
||||
|
||||
#define RISCV_HWPROBE_MAX_KEY 7
|
||||
#define RISCV_HWPROBE_MAX_KEY 8
|
||||
|
||||
static inline bool riscv_hwprobe_key_is_valid(__s64 key)
|
||||
{
|
||||
|
@ -37,7 +37,7 @@
|
||||
* define the PAGE_OFFSET value for SV48 and SV39.
|
||||
*/
|
||||
#define PAGE_OFFSET_L4 _AC(0xffffaf8000000000, UL)
|
||||
#define PAGE_OFFSET_L3 _AC(0xffffffd800000000, UL)
|
||||
#define PAGE_OFFSET_L3 _AC(0xffffffd600000000, UL)
|
||||
#else
|
||||
#define PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL)
|
||||
#endif /* CONFIG_64BIT */
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <linux/const.h>
|
||||
#include <linux/sizes.h>
|
||||
|
||||
/* thread information allocation */
|
||||
#define THREAD_SIZE_ORDER CONFIG_THREAD_SIZE_ORDER
|
||||
|
104
arch/riscv/include/asm/vendor_extensions.h
Normal file
104
arch/riscv/include/asm/vendor_extensions.h
Normal file
@ -0,0 +1,104 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright 2024 Rivos, Inc
|
||||
*/
|
||||
|
||||
#ifndef _ASM_VENDOR_EXTENSIONS_H
|
||||
#define _ASM_VENDOR_EXTENSIONS_H
|
||||
|
||||
#include <asm/cpufeature.h>
|
||||
|
||||
#include <linux/array_size.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
/*
|
||||
* The extension keys of each vendor must be strictly less than this value.
|
||||
*/
|
||||
#define RISCV_ISA_VENDOR_EXT_MAX 32
|
||||
|
||||
struct riscv_isavendorinfo {
|
||||
DECLARE_BITMAP(isa, RISCV_ISA_VENDOR_EXT_MAX);
|
||||
};
|
||||
|
||||
struct riscv_isa_vendor_ext_data_list {
|
||||
bool is_initialized;
|
||||
const size_t ext_data_count;
|
||||
const struct riscv_isa_ext_data *ext_data;
|
||||
struct riscv_isavendorinfo per_hart_isa_bitmap[NR_CPUS];
|
||||
struct riscv_isavendorinfo all_harts_isa_bitmap;
|
||||
};
|
||||
|
||||
extern struct riscv_isa_vendor_ext_data_list *riscv_isa_vendor_ext_list[];
|
||||
|
||||
extern const size_t riscv_isa_vendor_ext_list_size;
|
||||
|
||||
/*
|
||||
* The alternatives need some way of distinguishing between vendor extensions
|
||||
* and errata. Incrementing all of the vendor extension keys so they are at
|
||||
* least 0x8000 accomplishes that.
|
||||
*/
|
||||
#define RISCV_VENDOR_EXT_ALTERNATIVES_BASE 0x8000
|
||||
|
||||
#define VENDOR_EXT_ALL_CPUS -1
|
||||
|
||||
bool __riscv_isa_vendor_extension_available(int cpu, unsigned long vendor, unsigned int bit);
|
||||
#define riscv_cpu_isa_vendor_extension_available(cpu, vendor, ext) \
|
||||
__riscv_isa_vendor_extension_available(cpu, vendor, RISCV_ISA_VENDOR_EXT_##ext)
|
||||
#define riscv_isa_vendor_extension_available(vendor, ext) \
|
||||
__riscv_isa_vendor_extension_available(VENDOR_EXT_ALL_CPUS, vendor, \
|
||||
RISCV_ISA_VENDOR_EXT_##ext)
|
||||
|
||||
static __always_inline bool riscv_has_vendor_extension_likely(const unsigned long vendor,
|
||||
const unsigned long ext)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_RISCV_ISA_VENDOR_EXT))
|
||||
return false;
|
||||
|
||||
if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE))
|
||||
return __riscv_has_extension_likely(vendor,
|
||||
ext + RISCV_VENDOR_EXT_ALTERNATIVES_BASE);
|
||||
|
||||
return __riscv_isa_vendor_extension_available(VENDOR_EXT_ALL_CPUS, vendor, ext);
|
||||
}
|
||||
|
||||
static __always_inline bool riscv_has_vendor_extension_unlikely(const unsigned long vendor,
|
||||
const unsigned long ext)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_RISCV_ISA_VENDOR_EXT))
|
||||
return false;
|
||||
|
||||
if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE))
|
||||
return __riscv_has_extension_unlikely(vendor,
|
||||
ext + RISCV_VENDOR_EXT_ALTERNATIVES_BASE);
|
||||
|
||||
return __riscv_isa_vendor_extension_available(VENDOR_EXT_ALL_CPUS, vendor, ext);
|
||||
}
|
||||
|
||||
static __always_inline bool riscv_cpu_has_vendor_extension_likely(const unsigned long vendor,
|
||||
int cpu, const unsigned long ext)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_RISCV_ISA_VENDOR_EXT))
|
||||
return false;
|
||||
|
||||
if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE) &&
|
||||
__riscv_has_extension_likely(vendor, ext + RISCV_VENDOR_EXT_ALTERNATIVES_BASE))
|
||||
return true;
|
||||
|
||||
return __riscv_isa_vendor_extension_available(cpu, vendor, ext);
|
||||
}
|
||||
|
||||
static __always_inline bool riscv_cpu_has_vendor_extension_unlikely(const unsigned long vendor,
|
||||
int cpu,
|
||||
const unsigned long ext)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_RISCV_ISA_VENDOR_EXT))
|
||||
return false;
|
||||
|
||||
if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE) &&
|
||||
__riscv_has_extension_unlikely(vendor, ext + RISCV_VENDOR_EXT_ALTERNATIVES_BASE))
|
||||
return true;
|
||||
|
||||
return __riscv_isa_vendor_extension_available(cpu, vendor, ext);
|
||||
}
|
||||
|
||||
#endif /* _ASM_VENDOR_EXTENSIONS_H */
|
19
arch/riscv/include/asm/vendor_extensions/andes.h
Normal file
19
arch/riscv/include/asm/vendor_extensions/andes.h
Normal file
@ -0,0 +1,19 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_RISCV_VENDOR_EXTENSIONS_ANDES_H
|
||||
#define _ASM_RISCV_VENDOR_EXTENSIONS_ANDES_H
|
||||
|
||||
#include <asm/vendor_extensions.h>
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define RISCV_ISA_VENDOR_EXT_XANDESPMU 0
|
||||
|
||||
/*
|
||||
* Extension keys should be strictly less than max.
|
||||
* It is safe to increment this when necessary.
|
||||
*/
|
||||
#define RISCV_ISA_VENDOR_EXT_MAX_ANDES 32
|
||||
|
||||
extern struct riscv_isa_vendor_ext_data_list riscv_isa_vendor_ext_list_andes;
|
||||
|
||||
#endif
|
@ -81,6 +81,7 @@ struct riscv_hwprobe {
|
||||
#define RISCV_HWPROBE_MISALIGNED_MASK (7 << 0)
|
||||
#define RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE 6
|
||||
#define RISCV_HWPROBE_KEY_HIGHEST_VIRT_ADDRESS 7
|
||||
#define RISCV_HWPROBE_KEY_TIME_CSR_FREQ 8
|
||||
/* Increase RISCV_HWPROBE_MAX_KEY when adding items. */
|
||||
|
||||
/* Flags */
|
||||
|
@ -58,6 +58,8 @@ obj-y += riscv_ksyms.o
|
||||
obj-y += stacktrace.o
|
||||
obj-y += cacheinfo.o
|
||||
obj-y += patch.o
|
||||
obj-y += vendor_extensions.o
|
||||
obj-y += vendor_extensions/
|
||||
obj-y += probes/
|
||||
obj-y += tests/
|
||||
obj-$(CONFIG_MMU) += vdso.o vdso/
|
||||
@ -110,3 +112,4 @@ obj-$(CONFIG_COMPAT) += compat_vdso/
|
||||
|
||||
obj-$(CONFIG_64BIT) += pi/
|
||||
obj-$(CONFIG_ACPI) += acpi.o
|
||||
obj-$(CONFIG_ACPI_NUMA) += acpi_numa.o
|
||||
|
@ -17,7 +17,9 @@
|
||||
#include <linux/efi.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/serial_core.h>
|
||||
|
||||
int acpi_noirq = 1; /* skip ACPI IRQ initialization */
|
||||
int acpi_disabled = 1;
|
||||
@ -131,7 +133,7 @@ void __init acpi_boot_table_init(void)
|
||||
if (param_acpi_off ||
|
||||
(!param_acpi_on && !param_acpi_force &&
|
||||
efi.acpi20 == EFI_INVALID_TABLE_ADDR))
|
||||
return;
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* ACPI is disabled at this point. Enable it in order to parse
|
||||
@ -151,6 +153,14 @@ void __init acpi_boot_table_init(void)
|
||||
if (!param_acpi_force)
|
||||
disable_acpi();
|
||||
}
|
||||
|
||||
done:
|
||||
if (acpi_disabled) {
|
||||
if (earlycon_acpi_spcr_enable)
|
||||
early_init_dt_scan_chosen_stdout();
|
||||
} else {
|
||||
acpi_parse_spcr(earlycon_acpi_spcr_enable, true);
|
||||
}
|
||||
}
|
||||
|
||||
static int acpi_parse_madt_rintc(union acpi_subtable_headers *header, const unsigned long end)
|
||||
@ -191,11 +201,6 @@ struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu)
|
||||
return &cpu_madt_rintc[cpu];
|
||||
}
|
||||
|
||||
u32 get_acpi_id_for_cpu(int cpu)
|
||||
{
|
||||
return acpi_cpu_get_madt_rintc(cpu)->uid;
|
||||
}
|
||||
|
||||
/*
|
||||
* __acpi_map_table() will be called before paging_init(), so early_ioremap()
|
||||
* or early_memremap() should be called here to for ACPI table mapping.
|
||||
|
131
arch/riscv/kernel/acpi_numa.c
Normal file
131
arch/riscv/kernel/acpi_numa.c
Normal file
@ -0,0 +1,131 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* ACPI 6.6 based NUMA setup for RISCV
|
||||
* Lots of code was borrowed from arch/arm64/kernel/acpi_numa.c
|
||||
*
|
||||
* Copyright 2004 Andi Kleen, SuSE Labs.
|
||||
* Copyright (C) 2013-2016, Linaro Ltd.
|
||||
* Author: Hanjun Guo <hanjun.guo@linaro.org>
|
||||
* Copyright (C) 2024 Intel Corporation.
|
||||
*
|
||||
* Reads the ACPI SRAT table to figure out what memory belongs to which CPUs.
|
||||
*
|
||||
* Called from acpi_numa_init while reading the SRAT and SLIT tables.
|
||||
* Assumes all memory regions belonging to a single proximity domain
|
||||
* are in one chunk. Holes between them will be included in the node.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "ACPI: NUMA: " fmt
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/bitmap.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/mmzone.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/topology.h>
|
||||
|
||||
#include <asm/numa.h>
|
||||
|
||||
static int acpi_early_node_map[NR_CPUS] __initdata = { NUMA_NO_NODE };
|
||||
|
||||
int __init acpi_numa_get_nid(unsigned int cpu)
|
||||
{
|
||||
return acpi_early_node_map[cpu];
|
||||
}
|
||||
|
||||
static inline int get_cpu_for_acpi_id(u32 uid)
|
||||
{
|
||||
int cpu;
|
||||
|
||||
for (cpu = 0; cpu < nr_cpu_ids; cpu++)
|
||||
if (uid == get_acpi_id_for_cpu(cpu))
|
||||
return cpu;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int __init acpi_parse_rintc_pxm(union acpi_subtable_headers *header,
|
||||
const unsigned long end)
|
||||
{
|
||||
struct acpi_srat_rintc_affinity *pa;
|
||||
int cpu, pxm, node;
|
||||
|
||||
if (srat_disabled())
|
||||
return -EINVAL;
|
||||
|
||||
pa = (struct acpi_srat_rintc_affinity *)header;
|
||||
if (!pa)
|
||||
return -EINVAL;
|
||||
|
||||
if (!(pa->flags & ACPI_SRAT_RINTC_ENABLED))
|
||||
return 0;
|
||||
|
||||
pxm = pa->proximity_domain;
|
||||
node = pxm_to_node(pxm);
|
||||
|
||||
/*
|
||||
* If we can't map the UID to a logical cpu this
|
||||
* means that the UID is not part of possible cpus
|
||||
* so we do not need a NUMA mapping for it, skip
|
||||
* the SRAT entry and keep parsing.
|
||||
*/
|
||||
cpu = get_cpu_for_acpi_id(pa->acpi_processor_uid);
|
||||
if (cpu < 0)
|
||||
return 0;
|
||||
|
||||
acpi_early_node_map[cpu] = node;
|
||||
pr_info("SRAT: PXM %d -> HARTID 0x%lx -> Node %d\n", pxm,
|
||||
cpuid_to_hartid_map(cpu), node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __init acpi_map_cpus_to_nodes(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* In ACPI, SMP and CPU NUMA information is provided in separate
|
||||
* static tables, namely the MADT and the SRAT.
|
||||
*
|
||||
* Thus, it is simpler to first create the cpu logical map through
|
||||
* an MADT walk and then map the logical cpus to their node ids
|
||||
* as separate steps.
|
||||
*/
|
||||
acpi_table_parse_entries(ACPI_SIG_SRAT, sizeof(struct acpi_table_srat),
|
||||
ACPI_SRAT_TYPE_RINTC_AFFINITY, acpi_parse_rintc_pxm, 0);
|
||||
|
||||
for (i = 0; i < nr_cpu_ids; i++)
|
||||
early_map_cpu_to_node(i, acpi_numa_get_nid(i));
|
||||
}
|
||||
|
||||
/* Callback for Proximity Domain -> logical node ID mapping */
|
||||
void __init acpi_numa_rintc_affinity_init(struct acpi_srat_rintc_affinity *pa)
|
||||
{
|
||||
int pxm, node;
|
||||
|
||||
if (srat_disabled())
|
||||
return;
|
||||
|
||||
if (pa->header.length < sizeof(struct acpi_srat_rintc_affinity)) {
|
||||
pr_err("SRAT: Invalid SRAT header length: %d\n", pa->header.length);
|
||||
bad_srat();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(pa->flags & ACPI_SRAT_RINTC_ENABLED))
|
||||
return;
|
||||
|
||||
pxm = pa->proximity_domain;
|
||||
node = acpi_map_pxm_to_node(pxm);
|
||||
|
||||
if (node == NUMA_NO_NODE) {
|
||||
pr_err("SRAT: Too many proximity domains %d\n", pxm);
|
||||
bad_srat();
|
||||
return;
|
||||
}
|
||||
|
||||
node_set(node, numa_nodes_parsed);
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
* Copyright (C) 2017 SiFive
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/of.h>
|
||||
#include <asm/cacheinfo.h>
|
||||
@ -64,7 +65,6 @@ uintptr_t get_cache_geometry(u32 level, enum cache_type type)
|
||||
}
|
||||
|
||||
static void ci_leaf_init(struct cacheinfo *this_leaf,
|
||||
struct device_node *node,
|
||||
enum cache_type type, unsigned int level)
|
||||
{
|
||||
this_leaf->level = level;
|
||||
@ -79,12 +79,33 @@ int populate_cache_leaves(unsigned int cpu)
|
||||
struct device_node *prev = NULL;
|
||||
int levels = 1, level = 1;
|
||||
|
||||
if (!acpi_disabled) {
|
||||
int ret, fw_levels, split_levels;
|
||||
|
||||
ret = acpi_get_cache_info(cpu, &fw_levels, &split_levels);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
BUG_ON((split_levels > fw_levels) ||
|
||||
(split_levels + fw_levels > this_cpu_ci->num_leaves));
|
||||
|
||||
for (; level <= this_cpu_ci->num_levels; level++) {
|
||||
if (level <= split_levels) {
|
||||
ci_leaf_init(this_leaf++, CACHE_TYPE_DATA, level);
|
||||
ci_leaf_init(this_leaf++, CACHE_TYPE_INST, level);
|
||||
} else {
|
||||
ci_leaf_init(this_leaf++, CACHE_TYPE_UNIFIED, level);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (of_property_read_bool(np, "cache-size"))
|
||||
ci_leaf_init(this_leaf++, np, CACHE_TYPE_UNIFIED, level);
|
||||
ci_leaf_init(this_leaf++, CACHE_TYPE_UNIFIED, level);
|
||||
if (of_property_read_bool(np, "i-cache-size"))
|
||||
ci_leaf_init(this_leaf++, np, CACHE_TYPE_INST, level);
|
||||
ci_leaf_init(this_leaf++, CACHE_TYPE_INST, level);
|
||||
if (of_property_read_bool(np, "d-cache-size"))
|
||||
ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level);
|
||||
ci_leaf_init(this_leaf++, CACHE_TYPE_DATA, level);
|
||||
|
||||
prev = np;
|
||||
while ((np = of_find_next_cache_node(np))) {
|
||||
@ -97,11 +118,11 @@ int populate_cache_leaves(unsigned int cpu)
|
||||
if (level <= levels)
|
||||
break;
|
||||
if (of_property_read_bool(np, "cache-size"))
|
||||
ci_leaf_init(this_leaf++, np, CACHE_TYPE_UNIFIED, level);
|
||||
ci_leaf_init(this_leaf++, CACHE_TYPE_UNIFIED, level);
|
||||
if (of_property_read_bool(np, "i-cache-size"))
|
||||
ci_leaf_init(this_leaf++, np, CACHE_TYPE_INST, level);
|
||||
ci_leaf_init(this_leaf++, CACHE_TYPE_INST, level);
|
||||
if (of_property_read_bool(np, "d-cache-size"))
|
||||
ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level);
|
||||
ci_leaf_init(this_leaf++, CACHE_TYPE_DATA, level);
|
||||
levels = level;
|
||||
}
|
||||
of_node_put(np);
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <asm/sbi.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/vendor_extensions.h>
|
||||
|
||||
bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
|
||||
{
|
||||
@ -235,7 +236,33 @@ arch_initcall(riscv_cpuinfo_init);
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
|
||||
static void print_isa(struct seq_file *f, const unsigned long *isa_bitmap)
|
||||
#define ALL_CPUS -1
|
||||
|
||||
static void print_vendor_isa(struct seq_file *f, int cpu)
|
||||
{
|
||||
struct riscv_isavendorinfo *vendor_bitmap;
|
||||
struct riscv_isa_vendor_ext_data_list *ext_list;
|
||||
const struct riscv_isa_ext_data *ext_data;
|
||||
|
||||
for (int i = 0; i < riscv_isa_vendor_ext_list_size; i++) {
|
||||
ext_list = riscv_isa_vendor_ext_list[i];
|
||||
ext_data = riscv_isa_vendor_ext_list[i]->ext_data;
|
||||
|
||||
if (cpu == ALL_CPUS)
|
||||
vendor_bitmap = &ext_list->all_harts_isa_bitmap;
|
||||
else
|
||||
vendor_bitmap = &ext_list->per_hart_isa_bitmap[cpu];
|
||||
|
||||
for (int j = 0; j < ext_list->ext_data_count; j++) {
|
||||
if (!__riscv_isa_extension_available(vendor_bitmap->isa, ext_data[j].id))
|
||||
continue;
|
||||
|
||||
seq_printf(f, "_%s", ext_data[j].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void print_isa(struct seq_file *f, const unsigned long *isa_bitmap, int cpu)
|
||||
{
|
||||
|
||||
if (IS_ENABLED(CONFIG_32BIT))
|
||||
@ -254,6 +281,8 @@ static void print_isa(struct seq_file *f, const unsigned long *isa_bitmap)
|
||||
seq_printf(f, "%s", riscv_isa_ext[i].name);
|
||||
}
|
||||
|
||||
print_vendor_isa(f, cpu);
|
||||
|
||||
seq_puts(f, "\n");
|
||||
}
|
||||
|
||||
@ -316,7 +345,7 @@ static int c_show(struct seq_file *m, void *v)
|
||||
* line.
|
||||
*/
|
||||
seq_puts(m, "isa\t\t: ");
|
||||
print_isa(m, NULL);
|
||||
print_isa(m, NULL, ALL_CPUS);
|
||||
print_mmu(m);
|
||||
|
||||
if (acpi_disabled) {
|
||||
@ -338,7 +367,7 @@ static int c_show(struct seq_file *m, void *v)
|
||||
* additional extensions not present across all harts.
|
||||
*/
|
||||
seq_puts(m, "hart isa\t: ");
|
||||
print_isa(m, hart_isa[cpu_id].isa);
|
||||
print_isa(m, hart_isa[cpu_id].isa, cpu_id);
|
||||
seq_puts(m, "\n");
|
||||
|
||||
return 0;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <asm/processor.h>
|
||||
#include <asm/sbi.h>
|
||||
#include <asm/vector.h>
|
||||
#include <asm/vendor_extensions.h>
|
||||
|
||||
#define NUM_ALPHA_EXTS ('z' - 'a' + 1)
|
||||
|
||||
@ -100,31 +101,6 @@ static int riscv_ext_zicboz_validate(const struct riscv_isa_ext_data *data,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define _RISCV_ISA_EXT_DATA(_name, _id, _subset_exts, _subset_exts_size, _validate) { \
|
||||
.name = #_name, \
|
||||
.property = #_name, \
|
||||
.id = _id, \
|
||||
.subset_ext_ids = _subset_exts, \
|
||||
.subset_ext_size = _subset_exts_size, \
|
||||
.validate = _validate \
|
||||
}
|
||||
|
||||
#define __RISCV_ISA_EXT_DATA(_name, _id) _RISCV_ISA_EXT_DATA(_name, _id, NULL, 0, NULL)
|
||||
|
||||
#define __RISCV_ISA_EXT_DATA_VALIDATE(_name, _id, _validate) \
|
||||
_RISCV_ISA_EXT_DATA(_name, _id, NULL, 0, _validate)
|
||||
|
||||
/* Used to declare pure "lasso" extension (Zk for instance) */
|
||||
#define __RISCV_ISA_EXT_BUNDLE(_name, _bundled_exts) \
|
||||
_RISCV_ISA_EXT_DATA(_name, RISCV_ISA_EXT_INVALID, _bundled_exts, \
|
||||
ARRAY_SIZE(_bundled_exts), NULL)
|
||||
|
||||
/* Used to declare extensions that are a superset of other extensions (Zvbb for instance) */
|
||||
#define __RISCV_ISA_EXT_SUPERSET(_name, _id, _sub_exts) \
|
||||
_RISCV_ISA_EXT_DATA(_name, _id, _sub_exts, ARRAY_SIZE(_sub_exts), NULL)
|
||||
#define __RISCV_ISA_EXT_SUPERSET_VALIDATE(_name, _id, _sub_exts, _validate) \
|
||||
_RISCV_ISA_EXT_DATA(_name, _id, _sub_exts, ARRAY_SIZE(_sub_exts), _validate)
|
||||
|
||||
static int riscv_ext_zca_depends(const struct riscv_isa_ext_data *data,
|
||||
const unsigned long *isa_bitmap)
|
||||
{
|
||||
@ -405,7 +381,6 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
|
||||
__RISCV_ISA_EXT_DATA(svinval, RISCV_ISA_EXT_SVINVAL),
|
||||
__RISCV_ISA_EXT_DATA(svnapot, RISCV_ISA_EXT_SVNAPOT),
|
||||
__RISCV_ISA_EXT_DATA(svpbmt, RISCV_ISA_EXT_SVPBMT),
|
||||
__RISCV_ISA_EXT_DATA(xandespmu, RISCV_ISA_EXT_XANDESPMU),
|
||||
};
|
||||
|
||||
const size_t riscv_isa_ext_count = ARRAY_SIZE(riscv_isa_ext);
|
||||
@ -512,6 +487,21 @@ static void __init riscv_parse_isa_string(const char *isa, unsigned long *bitmap
|
||||
bool ext_err = false;
|
||||
|
||||
switch (*ext) {
|
||||
case 'x':
|
||||
case 'X':
|
||||
if (acpi_disabled)
|
||||
pr_warn_once("Vendor extensions are ignored in riscv,isa. Use riscv,isa-extensions instead.");
|
||||
/*
|
||||
* To skip an extension, we find its end.
|
||||
* As multi-letter extensions must be split from other multi-letter
|
||||
* extensions with an "_", the end of a multi-letter extension will
|
||||
* either be the null character or the "_" at the start of the next
|
||||
* multi-letter extension.
|
||||
*/
|
||||
for (; *isa && *isa != '_'; ++isa)
|
||||
;
|
||||
ext_err = true;
|
||||
break;
|
||||
case 's':
|
||||
/*
|
||||
* Workaround for invalid single-letter 's' & 'u' (QEMU).
|
||||
@ -527,8 +517,6 @@ static void __init riscv_parse_isa_string(const char *isa, unsigned long *bitmap
|
||||
}
|
||||
fallthrough;
|
||||
case 'S':
|
||||
case 'x':
|
||||
case 'X':
|
||||
case 'z':
|
||||
case 'Z':
|
||||
/*
|
||||
@ -728,6 +716,61 @@ static void __init riscv_fill_hwcap_from_isa_string(unsigned long *isa2hwcap)
|
||||
acpi_put_table((struct acpi_table_header *)rhct);
|
||||
}
|
||||
|
||||
static void __init riscv_fill_cpu_vendor_ext(struct device_node *cpu_node, int cpu)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_RISCV_ISA_VENDOR_EXT))
|
||||
return;
|
||||
|
||||
for (int i = 0; i < riscv_isa_vendor_ext_list_size; i++) {
|
||||
struct riscv_isa_vendor_ext_data_list *ext_list = riscv_isa_vendor_ext_list[i];
|
||||
|
||||
for (int j = 0; j < ext_list->ext_data_count; j++) {
|
||||
const struct riscv_isa_ext_data ext = ext_list->ext_data[j];
|
||||
struct riscv_isavendorinfo *isavendorinfo = &ext_list->per_hart_isa_bitmap[cpu];
|
||||
|
||||
if (of_property_match_string(cpu_node, "riscv,isa-extensions",
|
||||
ext.property) < 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Assume that subset extensions are all members of the
|
||||
* same vendor.
|
||||
*/
|
||||
if (ext.subset_ext_size)
|
||||
for (int k = 0; k < ext.subset_ext_size; k++)
|
||||
set_bit(ext.subset_ext_ids[k], isavendorinfo->isa);
|
||||
|
||||
set_bit(ext.id, isavendorinfo->isa);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Populate all_harts_isa_bitmap for each vendor with all of the extensions that
|
||||
* are shared across CPUs for that vendor.
|
||||
*/
|
||||
static void __init riscv_fill_vendor_ext_list(int cpu)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_RISCV_ISA_VENDOR_EXT))
|
||||
return;
|
||||
|
||||
for (int i = 0; i < riscv_isa_vendor_ext_list_size; i++) {
|
||||
struct riscv_isa_vendor_ext_data_list *ext_list = riscv_isa_vendor_ext_list[i];
|
||||
|
||||
if (!ext_list->is_initialized) {
|
||||
bitmap_copy(ext_list->all_harts_isa_bitmap.isa,
|
||||
ext_list->per_hart_isa_bitmap[cpu].isa,
|
||||
RISCV_ISA_VENDOR_EXT_MAX);
|
||||
ext_list->is_initialized = true;
|
||||
} else {
|
||||
bitmap_and(ext_list->all_harts_isa_bitmap.isa,
|
||||
ext_list->all_harts_isa_bitmap.isa,
|
||||
ext_list->per_hart_isa_bitmap[cpu].isa,
|
||||
RISCV_ISA_VENDOR_EXT_MAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int __init riscv_fill_hwcap_from_ext_list(unsigned long *isa2hwcap)
|
||||
{
|
||||
unsigned int cpu;
|
||||
@ -760,6 +803,7 @@ static int __init riscv_fill_hwcap_from_ext_list(unsigned long *isa2hwcap)
|
||||
}
|
||||
|
||||
riscv_resolve_isa(source_isa, isainfo->isa, &this_hwcap, isa2hwcap);
|
||||
riscv_fill_cpu_vendor_ext(cpu_node, cpu);
|
||||
|
||||
of_node_put(cpu_node);
|
||||
|
||||
@ -776,6 +820,8 @@ static int __init riscv_fill_hwcap_from_ext_list(unsigned long *isa2hwcap)
|
||||
bitmap_copy(riscv_isa, isainfo->isa, RISCV_ISA_EXT_MAX);
|
||||
else
|
||||
bitmap_and(riscv_isa, riscv_isa, isainfo->isa, RISCV_ISA_EXT_MAX);
|
||||
|
||||
riscv_fill_vendor_ext_list(cpu);
|
||||
}
|
||||
|
||||
if (bitmap_empty(riscv_isa, RISCV_ISA_EXT_MAX))
|
||||
@ -918,29 +964,46 @@ void __init_or_module riscv_cpufeature_patch_func(struct alt_entry *begin,
|
||||
{
|
||||
struct alt_entry *alt;
|
||||
void *oldptr, *altptr;
|
||||
u16 id, value;
|
||||
u16 id, value, vendor;
|
||||
|
||||
if (stage == RISCV_ALTERNATIVES_EARLY_BOOT)
|
||||
return;
|
||||
|
||||
for (alt = begin; alt < end; alt++) {
|
||||
if (alt->vendor_id != 0)
|
||||
continue;
|
||||
|
||||
id = PATCH_ID_CPUFEATURE_ID(alt->patch_id);
|
||||
vendor = PATCH_ID_CPUFEATURE_ID(alt->vendor_id);
|
||||
|
||||
if (id >= RISCV_ISA_EXT_MAX) {
|
||||
/*
|
||||
* Any alternative with a patch_id that is less than
|
||||
* RISCV_ISA_EXT_MAX is interpreted as a standard extension.
|
||||
*
|
||||
* Any alternative with patch_id that is greater than or equal
|
||||
* to RISCV_VENDOR_EXT_ALTERNATIVES_BASE is interpreted as a
|
||||
* vendor extension.
|
||||
*/
|
||||
if (id < RISCV_ISA_EXT_MAX) {
|
||||
/*
|
||||
* This patch should be treated as errata so skip
|
||||
* processing here.
|
||||
*/
|
||||
if (alt->vendor_id != 0)
|
||||
continue;
|
||||
|
||||
if (!__riscv_isa_extension_available(NULL, id))
|
||||
continue;
|
||||
|
||||
value = PATCH_ID_CPUFEATURE_VALUE(alt->patch_id);
|
||||
if (!riscv_cpufeature_patch_check(id, value))
|
||||
continue;
|
||||
} else if (id >= RISCV_VENDOR_EXT_ALTERNATIVES_BASE) {
|
||||
if (!__riscv_isa_vendor_extension_available(VENDOR_EXT_ALL_CPUS, vendor,
|
||||
id - RISCV_VENDOR_EXT_ALTERNATIVES_BASE))
|
||||
continue;
|
||||
} else {
|
||||
WARN(1, "This extension id:%d is not in ISA extension list", id);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!__riscv_isa_extension_available(NULL, id))
|
||||
continue;
|
||||
|
||||
value = PATCH_ID_CPUFEATURE_VALUE(alt->patch_id);
|
||||
if (!riscv_cpufeature_patch_check(id, value))
|
||||
continue;
|
||||
|
||||
oldptr = ALT_OLD_PTR(alt);
|
||||
altptr = ALT_ALT_PTR(alt);
|
||||
|
||||
|
@ -88,7 +88,6 @@ SYM_CODE_START(handle_exception)
|
||||
call riscv_v_context_nesting_start
|
||||
#endif
|
||||
move a0, sp /* pt_regs */
|
||||
la ra, ret_from_exception
|
||||
|
||||
/*
|
||||
* MSB of cause differentiates between
|
||||
@ -97,7 +96,8 @@ SYM_CODE_START(handle_exception)
|
||||
bge s4, zero, 1f
|
||||
|
||||
/* Handle interrupts */
|
||||
tail do_irq
|
||||
call do_irq
|
||||
j ret_from_exception
|
||||
1:
|
||||
/* Handle other exceptions */
|
||||
slli t0, s4, RISCV_LGPTR
|
||||
@ -105,11 +105,14 @@ SYM_CODE_START(handle_exception)
|
||||
la t2, excp_vect_table_end
|
||||
add t0, t1, t0
|
||||
/* Check if exception code lies within bounds */
|
||||
bgeu t0, t2, 1f
|
||||
REG_L t0, 0(t0)
|
||||
jr t0
|
||||
1:
|
||||
tail do_trap_unknown
|
||||
bgeu t0, t2, 3f
|
||||
REG_L t1, 0(t0)
|
||||
2: jalr t1
|
||||
j ret_from_exception
|
||||
3:
|
||||
|
||||
la t1, do_trap_unknown
|
||||
j 2b
|
||||
SYM_CODE_END(handle_exception)
|
||||
ASM_NOKPROBE(handle_exception)
|
||||
|
||||
@ -130,6 +133,10 @@ SYM_CODE_START_NOALIGN(ret_from_exception)
|
||||
#endif
|
||||
bnez s0, 1f
|
||||
|
||||
#ifdef CONFIG_GCC_PLUGIN_STACKLEAK
|
||||
call stackleak_erase_on_task_stack
|
||||
#endif
|
||||
|
||||
/* Save unwound kernel stack pointer in thread_info */
|
||||
addi s0, sp, PT_SIZE_ON_STACK
|
||||
REG_S s0, TASK_TI_KERNEL_SP(tp)
|
||||
|
@ -1,7 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-$(CONFIG_KPROBES) += kprobes.o decode-insn.o simulate-insn.o
|
||||
obj-$(CONFIG_RETHOOK) += rethook.o rethook_trampoline.o
|
||||
obj-$(CONFIG_KPROBES_ON_FTRACE) += ftrace.o
|
||||
obj-$(CONFIG_UPROBES) += uprobes.o decode-insn.o simulate-insn.o
|
||||
CFLAGS_REMOVE_simulate-insn.o = $(CC_FLAGS_FTRACE)
|
||||
CFLAGS_REMOVE_rethook.o = $(CC_FLAGS_FTRACE)
|
||||
|
@ -1,65 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <linux/kprobes.h>
|
||||
|
||||
/* Ftrace callback handler for kprobes -- called under preepmt disabled */
|
||||
void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
|
||||
struct ftrace_ops *ops, struct ftrace_regs *fregs)
|
||||
{
|
||||
struct kprobe *p;
|
||||
struct pt_regs *regs;
|
||||
struct kprobe_ctlblk *kcb;
|
||||
int bit;
|
||||
|
||||
if (unlikely(kprobe_ftrace_disabled))
|
||||
return;
|
||||
|
||||
bit = ftrace_test_recursion_trylock(ip, parent_ip);
|
||||
if (bit < 0)
|
||||
return;
|
||||
|
||||
p = get_kprobe((kprobe_opcode_t *)ip);
|
||||
if (unlikely(!p) || kprobe_disabled(p))
|
||||
goto out;
|
||||
|
||||
regs = ftrace_get_regs(fregs);
|
||||
kcb = get_kprobe_ctlblk();
|
||||
if (kprobe_running()) {
|
||||
kprobes_inc_nmissed_count(p);
|
||||
} else {
|
||||
unsigned long orig_ip = instruction_pointer(regs);
|
||||
|
||||
instruction_pointer_set(regs, ip);
|
||||
|
||||
__this_cpu_write(current_kprobe, p);
|
||||
kcb->kprobe_status = KPROBE_HIT_ACTIVE;
|
||||
if (!p->pre_handler || !p->pre_handler(p, regs)) {
|
||||
/*
|
||||
* Emulate singlestep (and also recover regs->pc)
|
||||
* as if there is a nop
|
||||
*/
|
||||
instruction_pointer_set(regs,
|
||||
(unsigned long)p->addr + MCOUNT_INSN_SIZE);
|
||||
if (unlikely(p->post_handler)) {
|
||||
kcb->kprobe_status = KPROBE_HIT_SSDONE;
|
||||
p->post_handler(p, regs, 0);
|
||||
}
|
||||
instruction_pointer_set(regs, orig_ip);
|
||||
}
|
||||
|
||||
/*
|
||||
* If pre_handler returns !0, it changes regs->pc. We have to
|
||||
* skip emulating post_handler.
|
||||
*/
|
||||
__this_cpu_write(current_kprobe, NULL);
|
||||
}
|
||||
out:
|
||||
ftrace_test_recursion_unlock(bit);
|
||||
}
|
||||
NOKPROBE_SYMBOL(kprobe_ftrace_handler);
|
||||
|
||||
int arch_prepare_kprobe_ftrace(struct kprobe *p)
|
||||
{
|
||||
p->ainsn.api.insn = NULL;
|
||||
return 0;
|
||||
}
|
@ -281,8 +281,10 @@ void __init setup_arch(char **cmdline_p)
|
||||
setup_smp();
|
||||
#endif
|
||||
|
||||
if (!acpi_disabled)
|
||||
if (!acpi_disabled) {
|
||||
acpi_init_rintc_map();
|
||||
acpi_map_cpus_to_nodes();
|
||||
}
|
||||
|
||||
riscv_init_cbo_blocksizes();
|
||||
riscv_fill_hwcap();
|
||||
|
@ -84,7 +84,7 @@ static long save_v_state(struct pt_regs *regs, void __user **sc_vec)
|
||||
datap = state + 1;
|
||||
|
||||
/* datap is designed to be 16 byte aligned for better performance */
|
||||
WARN_ON(unlikely(!IS_ALIGNED((unsigned long)datap, 16)));
|
||||
WARN_ON(!IS_ALIGNED((unsigned long)datap, 16));
|
||||
|
||||
get_cpu_vector_context();
|
||||
riscv_v_vstate_save(¤t->thread.vstate, regs);
|
||||
|
@ -96,7 +96,6 @@ static int __init acpi_parse_rintc(union acpi_subtable_headers *header, const un
|
||||
if (hart == cpuid_to_hartid_map(0)) {
|
||||
BUG_ON(found_boot_cpu);
|
||||
found_boot_cpu = true;
|
||||
early_map_cpu_to_node(0, acpi_numa_get_nid(cpu_count));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -106,7 +105,6 @@ static int __init acpi_parse_rintc(union acpi_subtable_headers *header, const un
|
||||
}
|
||||
|
||||
cpuid_to_hartid_map(cpu_count) = hart;
|
||||
early_map_cpu_to_node(cpu_count, acpi_numa_get_nid(cpu_count));
|
||||
cpu_count++;
|
||||
|
||||
return 0;
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
#ifdef CONFIG_FRAME_POINTER
|
||||
|
||||
extern asmlinkage void ret_from_exception(void);
|
||||
extern asmlinkage void handle_exception(void);
|
||||
|
||||
static inline int fp_is_valid(unsigned long fp, unsigned long sp)
|
||||
{
|
||||
@ -71,7 +71,7 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
|
||||
fp = frame->fp;
|
||||
pc = ftrace_graph_ret_addr(current, &graph_idx, frame->ra,
|
||||
&frame->ra);
|
||||
if (pc == (unsigned long)ret_from_exception) {
|
||||
if (pc == (unsigned long)handle_exception) {
|
||||
if (unlikely(!__kernel_text_address(pc) || !fn(arg, pc)))
|
||||
break;
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <asm/cpufeature.h>
|
||||
#include <asm/hwprobe.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/delay.h>
|
||||
#include <asm/sbi.h>
|
||||
#include <asm/switch_to.h>
|
||||
#include <asm/uaccess.h>
|
||||
@ -93,44 +94,45 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
|
||||
* regardless of the kernel's configuration, as no other checks, besides
|
||||
* presence in the hart_isa bitmap, are made.
|
||||
*/
|
||||
EXT_KEY(ZACAS);
|
||||
EXT_KEY(ZAWRS);
|
||||
EXT_KEY(ZBA);
|
||||
EXT_KEY(ZBB);
|
||||
EXT_KEY(ZBS);
|
||||
EXT_KEY(ZICBOZ);
|
||||
EXT_KEY(ZBC);
|
||||
|
||||
EXT_KEY(ZBKB);
|
||||
EXT_KEY(ZBKC);
|
||||
EXT_KEY(ZBKX);
|
||||
EXT_KEY(ZBS);
|
||||
EXT_KEY(ZCA);
|
||||
EXT_KEY(ZCB);
|
||||
EXT_KEY(ZCMOP);
|
||||
EXT_KEY(ZICBOZ);
|
||||
EXT_KEY(ZICOND);
|
||||
EXT_KEY(ZIHINTNTL);
|
||||
EXT_KEY(ZIHINTPAUSE);
|
||||
EXT_KEY(ZIMOP);
|
||||
EXT_KEY(ZKND);
|
||||
EXT_KEY(ZKNE);
|
||||
EXT_KEY(ZKNH);
|
||||
EXT_KEY(ZKSED);
|
||||
EXT_KEY(ZKSH);
|
||||
EXT_KEY(ZKT);
|
||||
EXT_KEY(ZIHINTNTL);
|
||||
EXT_KEY(ZTSO);
|
||||
EXT_KEY(ZACAS);
|
||||
EXT_KEY(ZICOND);
|
||||
EXT_KEY(ZIHINTPAUSE);
|
||||
EXT_KEY(ZIMOP);
|
||||
EXT_KEY(ZCA);
|
||||
EXT_KEY(ZCB);
|
||||
EXT_KEY(ZCMOP);
|
||||
EXT_KEY(ZAWRS);
|
||||
|
||||
/*
|
||||
* All the following extensions must depend on the kernel
|
||||
* support of V.
|
||||
*/
|
||||
if (has_vector()) {
|
||||
EXT_KEY(ZVE32X);
|
||||
EXT_KEY(ZVE32F);
|
||||
EXT_KEY(ZVE64X);
|
||||
EXT_KEY(ZVE64F);
|
||||
EXT_KEY(ZVE64D);
|
||||
EXT_KEY(ZVBB);
|
||||
EXT_KEY(ZVBC);
|
||||
EXT_KEY(ZVE32F);
|
||||
EXT_KEY(ZVE32X);
|
||||
EXT_KEY(ZVE64D);
|
||||
EXT_KEY(ZVE64F);
|
||||
EXT_KEY(ZVE64X);
|
||||
EXT_KEY(ZVFH);
|
||||
EXT_KEY(ZVFHMIN);
|
||||
EXT_KEY(ZVKB);
|
||||
EXT_KEY(ZVKG);
|
||||
EXT_KEY(ZVKNED);
|
||||
@ -139,16 +141,14 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
|
||||
EXT_KEY(ZVKSED);
|
||||
EXT_KEY(ZVKSH);
|
||||
EXT_KEY(ZVKT);
|
||||
EXT_KEY(ZVFH);
|
||||
EXT_KEY(ZVFHMIN);
|
||||
}
|
||||
|
||||
if (has_fpu()) {
|
||||
EXT_KEY(ZFH);
|
||||
EXT_KEY(ZFHMIN);
|
||||
EXT_KEY(ZFA);
|
||||
EXT_KEY(ZCD);
|
||||
EXT_KEY(ZCF);
|
||||
EXT_KEY(ZFA);
|
||||
EXT_KEY(ZFH);
|
||||
EXT_KEY(ZFHMIN);
|
||||
}
|
||||
#undef EXT_KEY
|
||||
}
|
||||
@ -237,6 +237,10 @@ static void hwprobe_one_pair(struct riscv_hwprobe *pair,
|
||||
pair->value = user_max_virt_addr();
|
||||
break;
|
||||
|
||||
case RISCV_HWPROBE_KEY_TIME_CSR_FREQ:
|
||||
pair->value = riscv_timebase;
|
||||
break;
|
||||
|
||||
/*
|
||||
* For forward compatibility, unknown keys don't fail the whole
|
||||
* call, but get their element key set to -1 and value set to 0
|
||||
|
56
arch/riscv/kernel/vendor_extensions.c
Normal file
56
arch/riscv/kernel/vendor_extensions.c
Normal file
@ -0,0 +1,56 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright 2024 Rivos, Inc
|
||||
*/
|
||||
|
||||
#include <asm/vendorid_list.h>
|
||||
#include <asm/vendor_extensions.h>
|
||||
#include <asm/vendor_extensions/andes.h>
|
||||
|
||||
#include <linux/array_size.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
struct riscv_isa_vendor_ext_data_list *riscv_isa_vendor_ext_list[] = {
|
||||
#ifdef CONFIG_RISCV_ISA_VENDOR_EXT_ANDES
|
||||
&riscv_isa_vendor_ext_list_andes,
|
||||
#endif
|
||||
};
|
||||
|
||||
const size_t riscv_isa_vendor_ext_list_size = ARRAY_SIZE(riscv_isa_vendor_ext_list);
|
||||
|
||||
/**
|
||||
* __riscv_isa_vendor_extension_available() - Check whether given vendor
|
||||
* extension is available or not.
|
||||
*
|
||||
* @cpu: check if extension is available on this cpu
|
||||
* @vendor: vendor that the extension is a member of
|
||||
* @bit: bit position of the desired extension
|
||||
* Return: true or false
|
||||
*
|
||||
* NOTE: When cpu is -1, will check if extension is available on all cpus
|
||||
*/
|
||||
bool __riscv_isa_vendor_extension_available(int cpu, unsigned long vendor, unsigned int bit)
|
||||
{
|
||||
struct riscv_isavendorinfo *bmap;
|
||||
struct riscv_isavendorinfo *cpu_bmap;
|
||||
|
||||
switch (vendor) {
|
||||
#ifdef CONFIG_RISCV_ISA_VENDOR_EXT_ANDES
|
||||
case ANDES_VENDOR_ID:
|
||||
bmap = &riscv_isa_vendor_ext_list_andes.all_harts_isa_bitmap;
|
||||
cpu_bmap = &riscv_isa_vendor_ext_list_andes.per_hart_isa_bitmap[cpu];
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cpu != -1)
|
||||
bmap = &cpu_bmap[cpu];
|
||||
|
||||
if (bit >= RISCV_ISA_VENDOR_EXT_MAX)
|
||||
return false;
|
||||
|
||||
return test_bit(bit, bmap->isa) ? true : false;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__riscv_isa_vendor_extension_available);
|
3
arch/riscv/kernel/vendor_extensions/Makefile
Normal file
3
arch/riscv/kernel/vendor_extensions/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
obj-$(CONFIG_RISCV_ISA_VENDOR_EXT_ANDES) += andes.o
|
18
arch/riscv/kernel/vendor_extensions/andes.c
Normal file
18
arch/riscv/kernel/vendor_extensions/andes.c
Normal file
@ -0,0 +1,18 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#include <asm/cpufeature.h>
|
||||
#include <asm/vendor_extensions.h>
|
||||
#include <asm/vendor_extensions/andes.h>
|
||||
|
||||
#include <linux/array_size.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
/* All Andes vendor extensions supported in Linux */
|
||||
const struct riscv_isa_ext_data riscv_isa_vendor_ext_andes[] = {
|
||||
__RISCV_ISA_EXT_DATA(xandespmu, RISCV_ISA_VENDOR_EXT_XANDESPMU),
|
||||
};
|
||||
|
||||
struct riscv_isa_vendor_ext_data_list riscv_isa_vendor_ext_list_andes = {
|
||||
.ext_data_count = ARRAY_SIZE(riscv_isa_vendor_ext_andes),
|
||||
.ext_data = riscv_isa_vendor_ext_andes,
|
||||
};
|
@ -799,17 +799,6 @@ config HAVE_PNETID
|
||||
|
||||
menu "Virtualization"
|
||||
|
||||
config PROTECTED_VIRTUALIZATION_GUEST
|
||||
def_bool n
|
||||
prompt "Protected virtualization guest support"
|
||||
help
|
||||
Select this option, if you want to be able to run this
|
||||
kernel as a protected virtualization KVM guest.
|
||||
Protected virtualization capable machines have a mini hypervisor
|
||||
located at machine level (an ultravisor). With help of the
|
||||
Ultravisor, KVM will be able to run "protected" VMs, special
|
||||
VMs whose memory and management data are unavailable to KVM.
|
||||
|
||||
config PFAULT
|
||||
def_bool y
|
||||
prompt "Pseudo page fault support"
|
||||
|
@ -39,8 +39,7 @@ CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char
|
||||
|
||||
obj-y := head.o als.o startup.o physmem_info.o ipl_parm.o ipl_report.o vmem.o
|
||||
obj-y += string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o
|
||||
obj-y += version.o pgm_check_info.o ctype.o ipl_data.o relocs.o
|
||||
obj-$(findstring y, $(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) $(CONFIG_PGSTE)) += uv.o
|
||||
obj-y += version.o pgm_check_info.o ctype.o ipl_data.o relocs.o alternative.o uv.o
|
||||
obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
|
||||
obj-y += $(if $(CONFIG_KERNEL_UNCOMPRESSED),,decompressor.o) info.o
|
||||
obj-$(CONFIG_KERNEL_ZSTD) += clz_ctz.o
|
||||
|
3
arch/s390/boot/alternative.c
Normal file
3
arch/s390/boot/alternative.c
Normal file
@ -0,0 +1,3 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include "../kernel/alternative.c"
|
@ -30,6 +30,8 @@ struct vmlinux_info {
|
||||
unsigned long init_mm_off;
|
||||
unsigned long swapper_pg_dir_off;
|
||||
unsigned long invalid_pg_dir_off;
|
||||
unsigned long alt_instructions;
|
||||
unsigned long alt_instructions_end;
|
||||
#ifdef CONFIG_KASAN
|
||||
unsigned long kasan_early_shadow_page_off;
|
||||
unsigned long kasan_early_shadow_pte_off;
|
||||
@ -89,8 +91,10 @@ extern char _end[], _decompressor_end[];
|
||||
extern unsigned char _compressed_start[];
|
||||
extern unsigned char _compressed_end[];
|
||||
extern struct vmlinux_info _vmlinux_info;
|
||||
|
||||
#define vmlinux _vmlinux_info
|
||||
|
||||
#define __lowcore_pa(x) ((unsigned long)(x) % sizeof(struct lowcore))
|
||||
#define __abs_lowcore_pa(x) (((unsigned long)(x) - __abs_lowcore) % sizeof(struct lowcore))
|
||||
#define __kernel_va(x) ((void *)((unsigned long)(x) - __kaslr_offset_phys + __kaslr_offset))
|
||||
#define __kernel_pa(x) ((unsigned long)(x) - __kaslr_offset + __kaslr_offset_phys)
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/pgtable.h>
|
||||
#include <asm/abs_lowcore.h>
|
||||
#include <asm/page-states.h>
|
||||
#include <asm/ebcdic.h>
|
||||
#include <asm/sclp.h>
|
||||
@ -310,5 +311,7 @@ void parse_boot_command_line(void)
|
||||
prot_virt_host = 1;
|
||||
}
|
||||
#endif
|
||||
if (!strcmp(param, "relocate_lowcore") && test_facility(193))
|
||||
relocate_lowcore = 1;
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ unsigned long __bootdata_preserved(vmemmap_size);
|
||||
unsigned long __bootdata_preserved(MODULES_VADDR);
|
||||
unsigned long __bootdata_preserved(MODULES_END);
|
||||
unsigned long __bootdata_preserved(max_mappable);
|
||||
int __bootdata_preserved(relocate_lowcore);
|
||||
|
||||
u64 __bootdata_preserved(stfle_fac_list[16]);
|
||||
struct oldmem_data __bootdata_preserved(oldmem_data);
|
||||
@ -376,6 +377,8 @@ static void kaslr_adjust_vmlinux_info(long offset)
|
||||
vmlinux.init_mm_off += offset;
|
||||
vmlinux.swapper_pg_dir_off += offset;
|
||||
vmlinux.invalid_pg_dir_off += offset;
|
||||
vmlinux.alt_instructions += offset;
|
||||
vmlinux.alt_instructions_end += offset;
|
||||
#ifdef CONFIG_KASAN
|
||||
vmlinux.kasan_early_shadow_page_off += offset;
|
||||
vmlinux.kasan_early_shadow_pte_off += offset;
|
||||
@ -478,8 +481,12 @@ void startup_kernel(void)
|
||||
* before the kernel started. Therefore, in case the two sections
|
||||
* overlap there is no risk of corrupting any data.
|
||||
*/
|
||||
if (kaslr_enabled())
|
||||
amode31_lma = randomize_within_range(vmlinux.amode31_size, PAGE_SIZE, 0, SZ_2G);
|
||||
if (kaslr_enabled()) {
|
||||
unsigned long amode31_min;
|
||||
|
||||
amode31_min = (unsigned long)_decompressor_end;
|
||||
amode31_lma = randomize_within_range(vmlinux.amode31_size, PAGE_SIZE, amode31_min, SZ_2G);
|
||||
}
|
||||
if (!amode31_lma)
|
||||
amode31_lma = __kaslr_offset_phys - vmlinux.amode31_size;
|
||||
physmem_reserve(RR_AMODE31, amode31_lma, vmlinux.amode31_size);
|
||||
@ -503,6 +510,9 @@ void startup_kernel(void)
|
||||
kaslr_adjust_got(__kaslr_offset);
|
||||
setup_vmem(__kaslr_offset, __kaslr_offset + kernel_size, asce_limit);
|
||||
copy_bootdata();
|
||||
__apply_alternatives((struct alt_instr *)_vmlinux_info.alt_instructions,
|
||||
(struct alt_instr *)_vmlinux_info.alt_instructions_end,
|
||||
ALT_CTX_EARLY);
|
||||
|
||||
/*
|
||||
* Save KASLR offset for early dumps, before vmcore_info is set.
|
||||
|
@ -8,12 +8,8 @@
|
||||
#include "uv.h"
|
||||
|
||||
/* will be used in arch/s390/kernel/uv.c */
|
||||
#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
|
||||
int __bootdata_preserved(prot_virt_guest);
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_KVM)
|
||||
int __bootdata_preserved(prot_virt_host);
|
||||
#endif
|
||||
struct uv_info __bootdata_preserved(uv_info);
|
||||
|
||||
void uv_query_info(void)
|
||||
@ -53,14 +49,11 @@ void uv_query_info(void)
|
||||
uv_info.max_secrets = uvcb.max_secrets;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
|
||||
if (test_bit_inv(BIT_UVC_CMD_SET_SHARED_ACCESS, (unsigned long *)uvcb.inst_calls_list) &&
|
||||
test_bit_inv(BIT_UVC_CMD_REMOVE_SHARED_ACCESS, (unsigned long *)uvcb.inst_calls_list))
|
||||
prot_virt_guest = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_KVM)
|
||||
unsigned long adjust_to_uv_max(unsigned long limit)
|
||||
{
|
||||
if (is_prot_virt_host() && uv_info.max_sec_stor_addr)
|
||||
@ -92,4 +85,3 @@ void sanitize_prot_virt_host(void)
|
||||
{
|
||||
prot_virt_host = is_prot_virt_host_capable();
|
||||
}
|
||||
#endif
|
||||
|
@ -2,21 +2,8 @@
|
||||
#ifndef BOOT_UV_H
|
||||
#define BOOT_UV_H
|
||||
|
||||
#if IS_ENABLED(CONFIG_KVM)
|
||||
unsigned long adjust_to_uv_max(unsigned long limit);
|
||||
void sanitize_prot_virt_host(void);
|
||||
#else
|
||||
static inline unsigned long adjust_to_uv_max(unsigned long limit)
|
||||
{
|
||||
return limit;
|
||||
}
|
||||
static inline void sanitize_prot_virt_host(void) {}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) || IS_ENABLED(CONFIG_KVM)
|
||||
void uv_query_info(void);
|
||||
#else
|
||||
static inline void uv_query_info(void) {}
|
||||
#endif
|
||||
|
||||
#endif /* BOOT_UV_H */
|
||||
|
@ -26,6 +26,7 @@ atomic_long_t __bootdata_preserved(direct_pages_count[PG_DIRECT_MAP_MAX]);
|
||||
enum populate_mode {
|
||||
POPULATE_NONE,
|
||||
POPULATE_DIRECT,
|
||||
POPULATE_LOWCORE,
|
||||
POPULATE_ABS_LOWCORE,
|
||||
POPULATE_IDENTITY,
|
||||
POPULATE_KERNEL,
|
||||
@ -242,6 +243,8 @@ static unsigned long _pa(unsigned long addr, unsigned long size, enum populate_m
|
||||
return -1;
|
||||
case POPULATE_DIRECT:
|
||||
return addr;
|
||||
case POPULATE_LOWCORE:
|
||||
return __lowcore_pa(addr);
|
||||
case POPULATE_ABS_LOWCORE:
|
||||
return __abs_lowcore_pa(addr);
|
||||
case POPULATE_KERNEL:
|
||||
@ -418,6 +421,7 @@ static void pgtable_populate(unsigned long addr, unsigned long end, enum populat
|
||||
|
||||
void setup_vmem(unsigned long kernel_start, unsigned long kernel_end, unsigned long asce_limit)
|
||||
{
|
||||
unsigned long lowcore_address = 0;
|
||||
unsigned long start, end;
|
||||
unsigned long asce_type;
|
||||
unsigned long asce_bits;
|
||||
@ -455,12 +459,17 @@ void setup_vmem(unsigned long kernel_start, unsigned long kernel_end, unsigned l
|
||||
__arch_set_page_dat((void *)swapper_pg_dir, 1UL << CRST_ALLOC_ORDER);
|
||||
__arch_set_page_dat((void *)invalid_pg_dir, 1UL << CRST_ALLOC_ORDER);
|
||||
|
||||
if (relocate_lowcore)
|
||||
lowcore_address = LOWCORE_ALT_ADDRESS;
|
||||
|
||||
/*
|
||||
* To allow prefixing the lowcore must be mapped with 4KB pages.
|
||||
* To prevent creation of a large page at address 0 first map
|
||||
* the lowcore and create the identity mapping only afterwards.
|
||||
*/
|
||||
pgtable_populate(0, sizeof(struct lowcore), POPULATE_DIRECT);
|
||||
pgtable_populate(lowcore_address,
|
||||
lowcore_address + sizeof(struct lowcore),
|
||||
POPULATE_LOWCORE);
|
||||
for_each_physmem_usable_range(i, &start, &end) {
|
||||
pgtable_populate((unsigned long)__identity_va(start),
|
||||
(unsigned long)__identity_va(end),
|
||||
|
@ -55,7 +55,6 @@ CONFIG_EXPOLINE_AUTO=y
|
||||
CONFIG_CHSC_SCH=y
|
||||
CONFIG_VFIO_CCW=m
|
||||
CONFIG_VFIO_AP=m
|
||||
CONFIG_PROTECTED_VIRTUALIZATION_GUEST=y
|
||||
CONFIG_CMM=m
|
||||
CONFIG_APPLDATA_BASE=y
|
||||
CONFIG_S390_HYPFS_FS=y
|
||||
|
@ -53,7 +53,6 @@ CONFIG_EXPOLINE_AUTO=y
|
||||
CONFIG_CHSC_SCH=y
|
||||
CONFIG_VFIO_CCW=m
|
||||
CONFIG_VFIO_AP=m
|
||||
CONFIG_PROTECTED_VIRTUALIZATION_GUEST=y
|
||||
CONFIG_CMM=m
|
||||
CONFIG_APPLDATA_BASE=y
|
||||
CONFIG_S390_HYPFS_FS=y
|
||||
|
@ -2,6 +2,7 @@
|
||||
#ifndef _ASM_S390_ABS_LOWCORE_H
|
||||
#define _ASM_S390_ABS_LOWCORE_H
|
||||
|
||||
#include <asm/sections.h>
|
||||
#include <asm/lowcore.h>
|
||||
|
||||
#define ABS_LOWCORE_MAP_SIZE (NR_CPUS * sizeof(struct lowcore))
|
||||
@ -24,4 +25,11 @@ static inline void put_abs_lowcore(struct lowcore *lc)
|
||||
put_cpu();
|
||||
}
|
||||
|
||||
extern int __bootdata_preserved(relocate_lowcore);
|
||||
|
||||
static inline int have_relocated_lowcore(void)
|
||||
{
|
||||
return relocate_lowcore;
|
||||
}
|
||||
|
||||
#endif /* _ASM_S390_ABS_LOWCORE_H */
|
||||
|
@ -1,57 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_S390_ALTERNATIVE_ASM_H
|
||||
#define _ASM_S390_ALTERNATIVE_ASM_H
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
|
||||
/*
|
||||
* Issue one struct alt_instr descriptor entry (need to put it into
|
||||
* the section .altinstructions, see below). This entry contains
|
||||
* enough information for the alternatives patching code to patch an
|
||||
* instruction. See apply_alternatives().
|
||||
*/
|
||||
.macro alt_entry orig_start, orig_end, alt_start, alt_end, feature
|
||||
.long \orig_start - .
|
||||
.long \alt_start - .
|
||||
.word \feature
|
||||
.byte \orig_end - \orig_start
|
||||
.org . - ( \orig_end - \orig_start ) & 1
|
||||
.org . - ( \orig_end - \orig_start ) + ( \alt_end - \alt_start )
|
||||
.org . - ( \alt_end - \alt_start ) + ( \orig_end - \orig_start )
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Define an alternative between two instructions. If @feature is
|
||||
* present, early code in apply_alternatives() replaces @oldinstr with
|
||||
* @newinstr.
|
||||
*/
|
||||
.macro ALTERNATIVE oldinstr, newinstr, feature
|
||||
.pushsection .altinstr_replacement,"ax"
|
||||
770: \newinstr
|
||||
771: .popsection
|
||||
772: \oldinstr
|
||||
773: .pushsection .altinstructions,"a"
|
||||
alt_entry 772b, 773b, 770b, 771b, \feature
|
||||
.popsection
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Define an alternative between two instructions. If @feature is
|
||||
* present, early code in apply_alternatives() replaces @oldinstr with
|
||||
* @newinstr.
|
||||
*/
|
||||
.macro ALTERNATIVE_2 oldinstr, newinstr1, feature1, newinstr2, feature2
|
||||
.pushsection .altinstr_replacement,"ax"
|
||||
770: \newinstr1
|
||||
771: \newinstr2
|
||||
772: .popsection
|
||||
773: \oldinstr
|
||||
774: .pushsection .altinstructions,"a"
|
||||
alt_entry 773b, 774b, 770b, 771b,\feature1
|
||||
alt_entry 773b, 774b, 771b, 772b,\feature2
|
||||
.popsection
|
||||
.endm
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_S390_ALTERNATIVE_ASM_H */
|
@ -2,6 +2,58 @@
|
||||
#ifndef _ASM_S390_ALTERNATIVE_H
|
||||
#define _ASM_S390_ALTERNATIVE_H
|
||||
|
||||
/*
|
||||
* Each alternative comes with a 32 bit feature field:
|
||||
* union {
|
||||
* u32 feature;
|
||||
* struct {
|
||||
* u32 ctx : 4;
|
||||
* u32 type : 8;
|
||||
* u32 data : 20;
|
||||
* };
|
||||
* }
|
||||
*
|
||||
* @ctx is a bitfield, where only one bit must be set. Each bit defines
|
||||
* in which context an alternative is supposed to be applied to the
|
||||
* kernel image:
|
||||
*
|
||||
* - from the decompressor before the kernel itself is executed
|
||||
* - from early kernel code from within the kernel
|
||||
*
|
||||
* @type is a number which defines the type and with that the type
|
||||
* specific alternative patching.
|
||||
*
|
||||
* @data is additional type specific information which defines if an
|
||||
* alternative should be applied.
|
||||
*/
|
||||
|
||||
#define ALT_CTX_EARLY 1
|
||||
#define ALT_CTX_LATE 2
|
||||
#define ALT_CTX_ALL (ALT_CTX_EARLY | ALT_CTX_LATE)
|
||||
|
||||
#define ALT_TYPE_FACILITY 0
|
||||
#define ALT_TYPE_SPEC 1
|
||||
#define ALT_TYPE_LOWCORE 2
|
||||
|
||||
#define ALT_DATA_SHIFT 0
|
||||
#define ALT_TYPE_SHIFT 20
|
||||
#define ALT_CTX_SHIFT 28
|
||||
|
||||
#define ALT_FACILITY_EARLY(facility) (ALT_CTX_EARLY << ALT_CTX_SHIFT | \
|
||||
ALT_TYPE_FACILITY << ALT_TYPE_SHIFT | \
|
||||
(facility) << ALT_DATA_SHIFT)
|
||||
|
||||
#define ALT_FACILITY(facility) (ALT_CTX_LATE << ALT_CTX_SHIFT | \
|
||||
ALT_TYPE_FACILITY << ALT_TYPE_SHIFT | \
|
||||
(facility) << ALT_DATA_SHIFT)
|
||||
|
||||
#define ALT_SPEC(facility) (ALT_CTX_LATE << ALT_CTX_SHIFT | \
|
||||
ALT_TYPE_SPEC << ALT_TYPE_SHIFT | \
|
||||
(facility) << ALT_DATA_SHIFT)
|
||||
|
||||
#define ALT_LOWCORE (ALT_CTX_EARLY << ALT_CTX_SHIFT | \
|
||||
ALT_TYPE_LOWCORE << ALT_TYPE_SHIFT)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/types.h>
|
||||
@ -11,12 +63,30 @@
|
||||
struct alt_instr {
|
||||
s32 instr_offset; /* original instruction */
|
||||
s32 repl_offset; /* offset to replacement instruction */
|
||||
u16 facility; /* facility bit set for replacement */
|
||||
union {
|
||||
u32 feature; /* feature required for replacement */
|
||||
struct {
|
||||
u32 ctx : 4; /* context */
|
||||
u32 type : 8; /* type of alternative */
|
||||
u32 data : 20; /* patching information */
|
||||
};
|
||||
};
|
||||
u8 instrlen; /* length of original instruction */
|
||||
} __packed;
|
||||
|
||||
void apply_alternative_instructions(void);
|
||||
void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
|
||||
extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
|
||||
|
||||
void __apply_alternatives(struct alt_instr *start, struct alt_instr *end, unsigned int ctx);
|
||||
|
||||
static inline void apply_alternative_instructions(void)
|
||||
{
|
||||
__apply_alternatives(__alt_instructions, __alt_instructions_end, ALT_CTX_LATE);
|
||||
}
|
||||
|
||||
static inline void apply_alternatives(struct alt_instr *start, struct alt_instr *end)
|
||||
{
|
||||
__apply_alternatives(start, end, ALT_CTX_ALL);
|
||||
}
|
||||
|
||||
/*
|
||||
* +---------------------------------+
|
||||
@ -48,10 +118,10 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
|
||||
#define OLDINSTR(oldinstr) \
|
||||
"661:\n\t" oldinstr "\n662:\n"
|
||||
|
||||
#define ALTINSTR_ENTRY(facility, num) \
|
||||
#define ALTINSTR_ENTRY(feature, num) \
|
||||
"\t.long 661b - .\n" /* old instruction */ \
|
||||
"\t.long " b_altinstr(num)"b - .\n" /* alt instruction */ \
|
||||
"\t.word " __stringify(facility) "\n" /* facility bit */ \
|
||||
"\t.long " __stringify(feature) "\n" /* feature */ \
|
||||
"\t.byte " oldinstr_len "\n" /* instruction len */ \
|
||||
"\t.org . - (" oldinstr_len ") & 1\n" \
|
||||
"\t.org . - (" oldinstr_len ") + (" altinstr_len(num) ")\n" \
|
||||
@ -61,24 +131,24 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
|
||||
b_altinstr(num)":\n\t" altinstr "\n" e_altinstr(num) ":\n"
|
||||
|
||||
/* alternative assembly primitive: */
|
||||
#define ALTERNATIVE(oldinstr, altinstr, facility) \
|
||||
#define ALTERNATIVE(oldinstr, altinstr, feature) \
|
||||
".pushsection .altinstr_replacement, \"ax\"\n" \
|
||||
ALTINSTR_REPLACEMENT(altinstr, 1) \
|
||||
".popsection\n" \
|
||||
OLDINSTR(oldinstr) \
|
||||
".pushsection .altinstructions,\"a\"\n" \
|
||||
ALTINSTR_ENTRY(facility, 1) \
|
||||
ALTINSTR_ENTRY(feature, 1) \
|
||||
".popsection\n"
|
||||
|
||||
#define ALTERNATIVE_2(oldinstr, altinstr1, facility1, altinstr2, facility2)\
|
||||
#define ALTERNATIVE_2(oldinstr, altinstr1, feature1, altinstr2, feature2)\
|
||||
".pushsection .altinstr_replacement, \"ax\"\n" \
|
||||
ALTINSTR_REPLACEMENT(altinstr1, 1) \
|
||||
ALTINSTR_REPLACEMENT(altinstr2, 2) \
|
||||
".popsection\n" \
|
||||
OLDINSTR(oldinstr) \
|
||||
".pushsection .altinstructions,\"a\"\n" \
|
||||
ALTINSTR_ENTRY(facility1, 1) \
|
||||
ALTINSTR_ENTRY(facility2, 2) \
|
||||
ALTINSTR_ENTRY(feature1, 1) \
|
||||
ALTINSTR_ENTRY(feature2, 2) \
|
||||
".popsection\n"
|
||||
|
||||
/*
|
||||
@ -93,12 +163,12 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
|
||||
* For non barrier like inlines please define new variants
|
||||
* without volatile and memory clobber.
|
||||
*/
|
||||
#define alternative(oldinstr, altinstr, facility) \
|
||||
asm_inline volatile(ALTERNATIVE(oldinstr, altinstr, facility) : : : "memory")
|
||||
#define alternative(oldinstr, altinstr, feature) \
|
||||
asm_inline volatile(ALTERNATIVE(oldinstr, altinstr, feature) : : : "memory")
|
||||
|
||||
#define alternative_2(oldinstr, altinstr1, facility1, altinstr2, facility2) \
|
||||
asm_inline volatile(ALTERNATIVE_2(oldinstr, altinstr1, facility1, \
|
||||
altinstr2, facility2) ::: "memory")
|
||||
#define alternative_2(oldinstr, altinstr1, feature1, altinstr2, feature2) \
|
||||
asm_inline volatile(ALTERNATIVE_2(oldinstr, altinstr1, feature1, \
|
||||
altinstr2, feature2) ::: "memory")
|
||||
|
||||
/* Alternative inline assembly with input. */
|
||||
#define alternative_input(oldinstr, newinstr, feature, input...) \
|
||||
@ -106,8 +176,8 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
|
||||
: : input)
|
||||
|
||||
/* Like alternative_input, but with a single output argument */
|
||||
#define alternative_io(oldinstr, altinstr, facility, output, input...) \
|
||||
asm_inline volatile(ALTERNATIVE(oldinstr, altinstr, facility) \
|
||||
#define alternative_io(oldinstr, altinstr, feature, output, input...) \
|
||||
asm_inline volatile(ALTERNATIVE(oldinstr, altinstr, feature) \
|
||||
: output : input)
|
||||
|
||||
/* Use this macro if more than one output parameter is needed. */
|
||||
@ -116,6 +186,56 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
|
||||
/* Use this macro if clobbers are needed without inputs. */
|
||||
#define ASM_NO_INPUT_CLOBBER(clobber...) : clobber
|
||||
|
||||
#else /* __ASSEMBLY__ */
|
||||
|
||||
/*
|
||||
* Issue one struct alt_instr descriptor entry (need to put it into
|
||||
* the section .altinstructions, see below). This entry contains
|
||||
* enough information for the alternatives patching code to patch an
|
||||
* instruction. See apply_alternatives().
|
||||
*/
|
||||
.macro alt_entry orig_start, orig_end, alt_start, alt_end, feature
|
||||
.long \orig_start - .
|
||||
.long \alt_start - .
|
||||
.long \feature
|
||||
.byte \orig_end - \orig_start
|
||||
.org . - ( \orig_end - \orig_start ) & 1
|
||||
.org . - ( \orig_end - \orig_start ) + ( \alt_end - \alt_start )
|
||||
.org . - ( \alt_end - \alt_start ) + ( \orig_end - \orig_start )
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Define an alternative between two instructions. If @feature is
|
||||
* present, early code in apply_alternatives() replaces @oldinstr with
|
||||
* @newinstr.
|
||||
*/
|
||||
.macro ALTERNATIVE oldinstr, newinstr, feature
|
||||
.pushsection .altinstr_replacement,"ax"
|
||||
770: \newinstr
|
||||
771: .popsection
|
||||
772: \oldinstr
|
||||
773: .pushsection .altinstructions,"a"
|
||||
alt_entry 772b, 773b, 770b, 771b, \feature
|
||||
.popsection
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Define an alternative between two instructions. If @feature is
|
||||
* present, early code in apply_alternatives() replaces @oldinstr with
|
||||
* @newinstr.
|
||||
*/
|
||||
.macro ALTERNATIVE_2 oldinstr, newinstr1, feature1, newinstr2, feature2
|
||||
.pushsection .altinstr_replacement,"ax"
|
||||
770: \newinstr1
|
||||
771: \newinstr2
|
||||
772: .popsection
|
||||
773: \oldinstr
|
||||
774: .pushsection .altinstructions,"a"
|
||||
alt_entry 773b, 774b, 770b, 771b,\feature1
|
||||
alt_entry 773b, 774b, 771b, 772b,\feature2
|
||||
.popsection
|
||||
.endm
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_S390_ALTERNATIVE_H */
|
||||
|
@ -188,7 +188,8 @@ static __always_inline long __atomic64_cmpxchg(long *ptr, long old, long new)
|
||||
return old;
|
||||
}
|
||||
|
||||
#ifdef __GCC_ASM_FLAG_OUTPUTS__
|
||||
/* GCC versions before 14.2.0 may die with an ICE in some configurations. */
|
||||
#if defined(__GCC_ASM_FLAG_OUTPUTS__) && !(IS_ENABLED(CONFIG_CC_IS_GCC) && (GCC_VERSION < 140200))
|
||||
|
||||
static __always_inline bool __atomic_cmpxchg_bool(int *ptr, int old, int new)
|
||||
{
|
||||
|
@ -20,7 +20,6 @@
|
||||
#define MAX_FACILITY_BIT (sizeof(stfle_fac_list) * 8)
|
||||
|
||||
extern u64 stfle_fac_list[16];
|
||||
extern u64 alt_stfle_fac_list[16];
|
||||
|
||||
static inline void __set_facility(unsigned long nr, void *facilities)
|
||||
{
|
||||
|
@ -12,8 +12,8 @@
|
||||
|
||||
static inline bool is_lowcore_addr(void *addr)
|
||||
{
|
||||
return addr >= (void *)&S390_lowcore &&
|
||||
addr < (void *)(&S390_lowcore + 1);
|
||||
return addr >= (void *)get_lowcore() &&
|
||||
addr < (void *)(get_lowcore() + 1);
|
||||
}
|
||||
|
||||
static inline void *arch_kmsan_get_meta_or_null(void *addr, bool is_origin)
|
||||
@ -25,7 +25,7 @@ static inline void *arch_kmsan_get_meta_or_null(void *addr, bool is_origin)
|
||||
* order to get a distinct struct page.
|
||||
*/
|
||||
addr += (void *)lowcore_ptr[raw_smp_processor_id()] -
|
||||
(void *)&S390_lowcore;
|
||||
(void *)get_lowcore();
|
||||
if (KMSAN_WARN_ON(is_lowcore_addr(addr)))
|
||||
return NULL;
|
||||
return kmsan_get_metadata(addr, is_origin);
|
||||
|
@ -14,10 +14,15 @@
|
||||
#include <asm/ctlreg.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/types.h>
|
||||
#include <asm/alternative.h>
|
||||
|
||||
#define LC_ORDER 1
|
||||
#define LC_PAGES 2
|
||||
|
||||
#define LOWCORE_ALT_ADDRESS _AC(0x70000, UL)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
struct pgm_tdb {
|
||||
u64 data[32];
|
||||
};
|
||||
@ -97,8 +102,7 @@ struct lowcore {
|
||||
__u64 save_area_async[8]; /* 0x0240 */
|
||||
__u64 save_area_restart[1]; /* 0x0280 */
|
||||
|
||||
/* CPU flags. */
|
||||
__u64 cpu_flags; /* 0x0288 */
|
||||
__u64 pcpu; /* 0x0288 */
|
||||
|
||||
/* Return psws. */
|
||||
psw_t return_psw; /* 0x0290 */
|
||||
@ -215,7 +219,14 @@ struct lowcore {
|
||||
|
||||
static __always_inline struct lowcore *get_lowcore(void)
|
||||
{
|
||||
return NULL;
|
||||
struct lowcore *lc;
|
||||
|
||||
if (__is_defined(__DECOMPRESSOR))
|
||||
return NULL;
|
||||
asm(ALTERNATIVE("llilh %[lc],0", "llilh %[lc],%[alt]", ALT_LOWCORE)
|
||||
: [lc] "=d" (lc)
|
||||
: [alt] "i" (LOWCORE_ALT_ADDRESS >> 16));
|
||||
return lc;
|
||||
}
|
||||
|
||||
extern struct lowcore *lowcore_ptr[];
|
||||
@ -225,4 +236,19 @@ static inline void set_prefix(__u32 address)
|
||||
asm volatile("spx %0" : : "Q" (address) : "memory");
|
||||
}
|
||||
|
||||
#else /* __ASSEMBLY__ */
|
||||
|
||||
.macro GET_LC reg
|
||||
ALTERNATIVE "llilh \reg,0", \
|
||||
__stringify(llilh \reg, LOWCORE_ALT_ADDRESS >> 16), \
|
||||
ALT_LOWCORE
|
||||
.endm
|
||||
|
||||
.macro STMG_LC start, end, savearea
|
||||
ALTERNATIVE "stmg \start, \end, \savearea", \
|
||||
__stringify(stmg \start, \end, LOWCORE_ALT_ADDRESS + \savearea), \
|
||||
ALT_LOWCORE
|
||||
.endm
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* _ASM_S390_LOWCORE_H */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user