mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 04:18:39 +08:00
Merge tag 'loongarch-kvm-6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson into HEAD
LoongArch KVM changes for v6.12 1. Revert qspinlock to test-and-set simple lock on VM. 2. Add Loongson Binary Translation extension support. 3. Add PMU support for guest. 4. Enable paravirt feature control from VMM. 5. Implement function kvm_para_has_feature().
This commit is contained in:
commit
1a371190a3
5
.mailmap
5
.mailmap
@ -60,6 +60,7 @@ Amit Nischal <quic_anischal@quicinc.com> <anischal@codeaurora.org>
|
||||
Andi Kleen <ak@linux.intel.com> <ak@suse.de>
|
||||
Andi Shyti <andi@etezian.org> <andi.shyti@samsung.com>
|
||||
Andreas Herrmann <aherrman@de.ibm.com>
|
||||
Andreas Hindborg <a.hindborg@kernel.org> <a.hindborg@samsung.com>
|
||||
Andrej Shadura <andrew.shadura@collabora.co.uk>
|
||||
Andrej Shadura <andrew@shadura.me> <andrew@beldisplaytech.com>
|
||||
Andrew Morton <akpm@linux-foundation.org>
|
||||
@ -269,6 +270,7 @@ James Ketrenos <jketreno@io.(none)>
|
||||
Jan Glauber <jan.glauber@gmail.com> <jang@de.ibm.com>
|
||||
Jan Glauber <jan.glauber@gmail.com> <jang@linux.vnet.ibm.com>
|
||||
Jan Glauber <jan.glauber@gmail.com> <jglauber@cavium.com>
|
||||
Jan Kuliga <jtkuliga.kdev@gmail.com> <jankul@alatek.krakow.pl>
|
||||
Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@linux.intel.com>
|
||||
Jarkko Sakkinen <jarkko@kernel.org> <jarkko@profian.com>
|
||||
Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@tuni.fi>
|
||||
@ -354,6 +356,8 @@ Kenneth Westfield <quic_kwestfie@quicinc.com> <kwestfie@codeaurora.org>
|
||||
Kiran Gunda <quic_kgunda@quicinc.com> <kgunda@codeaurora.org>
|
||||
Kirill Tkhai <tkhai@ya.ru> <ktkhai@virtuozzo.com>
|
||||
Kishon Vijay Abraham I <kishon@kernel.org> <kishon@ti.com>
|
||||
Konrad Dybcio <konradybcio@kernel.org> <konrad.dybcio@linaro.org>
|
||||
Konrad Dybcio <konradybcio@kernel.org> <konrad.dybcio@somainline.org>
|
||||
Konstantin Khlebnikov <koct9i@gmail.com> <khlebnikov@yandex-team.ru>
|
||||
Konstantin Khlebnikov <koct9i@gmail.com> <k.khlebnikov@samsung.com>
|
||||
Koushik <raghavendra.koushik@neterion.com>
|
||||
@ -614,6 +618,7 @@ Simon Kelley <simon@thekelleys.org.uk>
|
||||
Sricharan Ramabadhran <quic_srichara@quicinc.com> <sricharan@codeaurora.org>
|
||||
Srinivas Ramana <quic_sramana@quicinc.com> <sramana@codeaurora.org>
|
||||
Sriram R <quic_srirrama@quicinc.com> <srirrama@codeaurora.org>
|
||||
Sriram Yagnaraman <sriram.yagnaraman@ericsson.com> <sriram.yagnaraman@est.tech>
|
||||
Stanislav Fomichev <sdf@fomichev.me> <sdf@google.com>
|
||||
Stefan Wahren <wahrenst@gmx.net> <stefan.wahren@i2se.com>
|
||||
Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr>
|
||||
|
@ -258,24 +258,29 @@ Description: (RW) When retrieving the PHC with the PTP SYS_OFFSET_EXTENDED
|
||||
the estimated point where the FPGA latches the PHC time. This
|
||||
value may be changed by writing an unsigned integer.
|
||||
|
||||
What: /sys/class/timecard/ocpN/ttyGNSS
|
||||
What: /sys/class/timecard/ocpN/ttyGNSS2
|
||||
Date: September 2021
|
||||
Contact: Jonathan Lemon <jonathan.lemon@gmail.com>
|
||||
Description: These optional attributes link to the TTY serial ports
|
||||
associated with the GNSS devices.
|
||||
What: /sys/class/timecard/ocpN/tty
|
||||
Date: August 2024
|
||||
Contact: Vadim Fedorenko <vadim.fedorenko@linux.dev>
|
||||
Description: (RO) Directory containing the sysfs nodes for TTY attributes
|
||||
|
||||
What: /sys/class/timecard/ocpN/ttyMAC
|
||||
Date: September 2021
|
||||
What: /sys/class/timecard/ocpN/tty/ttyGNSS
|
||||
What: /sys/class/timecard/ocpN/tty/ttyGNSS2
|
||||
Date: August 2024
|
||||
Contact: Jonathan Lemon <jonathan.lemon@gmail.com>
|
||||
Description: This optional attribute links to the TTY serial port
|
||||
associated with the Miniature Atomic Clock.
|
||||
Description: (RO) These optional attributes contain names of the TTY serial
|
||||
ports associated with the GNSS devices.
|
||||
|
||||
What: /sys/class/timecard/ocpN/ttyNMEA
|
||||
Date: September 2021
|
||||
What: /sys/class/timecard/ocpN/tty/ttyMAC
|
||||
Date: August 2024
|
||||
Contact: Jonathan Lemon <jonathan.lemon@gmail.com>
|
||||
Description: This optional attribute links to the TTY serial port
|
||||
which outputs the PHC time in NMEA ZDA format.
|
||||
Description: (RO) This optional attribute contains name of the TTY serial
|
||||
port associated with the Miniature Atomic Clock.
|
||||
|
||||
What: /sys/class/timecard/ocpN/tty/ttyNMEA
|
||||
Date: August 2024
|
||||
Contact: Jonathan Lemon <jonathan.lemon@gmail.com>
|
||||
Description: (RO) This optional attribute contains name of the TTY serial
|
||||
port which outputs the PHC time in NMEA ZDA format.
|
||||
|
||||
What: /sys/class/timecard/ocpN/utc_tai_offset
|
||||
Date: September 2021
|
||||
|
@ -1717,9 +1717,10 @@ The following nested keys are defined.
|
||||
entries fault back in or are written out to disk.
|
||||
|
||||
memory.zswap.writeback
|
||||
A read-write single value file. The default value is "1". The
|
||||
initial value of the root cgroup is 1, and when a new cgroup is
|
||||
created, it inherits the current value of its parent.
|
||||
A read-write single value file. The default value is "1".
|
||||
Note that this setting is hierarchical, i.e. the writeback would be
|
||||
implicitly disabled for child cgroups if the upper hierarchy
|
||||
does so.
|
||||
|
||||
When this is set to 0, all swapping attempts to swapping devices
|
||||
are disabled. This included both zswap writebacks, and swapping due
|
||||
|
@ -134,19 +134,3 @@ RISC-V Linux Kernel SV57
|
||||
ffffffff00000000 | -4 GB | ffffffff7fffffff | 2 GB | modules, BPF
|
||||
ffffffff80000000 | -2 GB | ffffffffffffffff | 2 GB | kernel
|
||||
__________________|____________|__________________|_________|____________________________________________________________
|
||||
|
||||
|
||||
Userspace VAs
|
||||
--------------------
|
||||
To maintain compatibility with software that relies on the VA space with a
|
||||
maximum of 48 bits the kernel will, by default, return virtual addresses to
|
||||
userspace from a 48-bit range (sv48). This default behavior is achieved by
|
||||
passing 0 into the hint address parameter of mmap. On CPUs with an address space
|
||||
smaller than sv48, the CPU maximum supported address space will be the default.
|
||||
|
||||
Software can "opt-in" to receiving VAs from another VA space by providing
|
||||
a hint address to mmap. When a hint address is passed to mmap, the returned
|
||||
address will never use more bits than the hint address. For example, if a hint
|
||||
address of `1 << 40` is passed to mmap, a valid returned address will never use
|
||||
bits 41 through 63. If no mappable addresses are available in that range, mmap
|
||||
will return `MAP_FAILED`.
|
||||
|
@ -1,10 +1,10 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/panel/wl-355608-a8.yaml#
|
||||
$id: http://devicetree.org/schemas/display/panel/anbernic,rg35xx-plus-panel.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: WL-355608-A8 3.5" (640x480 pixels) 24-bit IPS LCD panel
|
||||
title: Anbernic RG35XX series (WL-355608-A8) 3.5" 640x480 24-bit IPS LCD panel
|
||||
|
||||
maintainers:
|
||||
- Ryan Walklin <ryan@testtoast.com>
|
||||
@ -15,7 +15,14 @@ allOf:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: wl-355608-a8
|
||||
oneOf:
|
||||
- const: anbernic,rg35xx-plus-panel
|
||||
- items:
|
||||
- enum:
|
||||
- anbernic,rg35xx-2024-panel
|
||||
- anbernic,rg35xx-h-panel
|
||||
- anbernic,rg35xx-sp-panel
|
||||
- const: anbernic,rg35xx-plus-panel
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@ -40,7 +47,7 @@ examples:
|
||||
#size-cells = <0>;
|
||||
|
||||
panel@0 {
|
||||
compatible = "wl-355608-a8";
|
||||
compatible = "anbernic,rg35xx-plus-panel";
|
||||
reg = <0>;
|
||||
|
||||
spi-3wire;
|
@ -28,7 +28,7 @@ unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
nvmem {
|
||||
soc-nvmem {
|
||||
compatible = "xlnx,zynqmp-nvmem-fw";
|
||||
nvmem-layout {
|
||||
compatible = "fixed-layout";
|
||||
|
@ -10,7 +10,7 @@ maintainers:
|
||||
- Fabio Estevam <festevam@gmail.com>
|
||||
|
||||
allOf:
|
||||
- $ref: usb-hcd.yaml#
|
||||
- $ref: usb-device.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
@ -36,6 +36,13 @@ required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
patternProperties:
|
||||
"^.*@[0-9a-f]{1,2}$":
|
||||
description: The hard wired USB devices
|
||||
type: object
|
||||
$ref: /schemas/usb/usb-device.yaml
|
||||
additionalProperties: true
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
|
@ -629,18 +629,6 @@ The preferred style for long (multi-line) comments is:
|
||||
* with beginning and ending almost-blank lines.
|
||||
*/
|
||||
|
||||
For files in net/ and drivers/net/ the preferred style for long (multi-line)
|
||||
comments is a little different.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/* The preferred comment style for files in net/ and drivers/net
|
||||
* looks like this.
|
||||
*
|
||||
* It is nearly the same as the generally preferred comment style,
|
||||
* but there is no initial almost-blank line.
|
||||
*/
|
||||
|
||||
It's also important to comment data, whether they are basic types or derived
|
||||
types. To this end, use just one data declaration per line (no commas for
|
||||
multiple data declarations). This leaves you room for a small comment on each
|
||||
|
@ -355,23 +355,6 @@ just do it. As a result, a sequence of smaller series gets merged quicker and
|
||||
with better review coverage. Re-posting large series also increases the mailing
|
||||
list traffic.
|
||||
|
||||
Multi-line comments
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Comment style convention is slightly different for networking and most of
|
||||
the tree. Instead of this::
|
||||
|
||||
/*
|
||||
* foobar blah blah blah
|
||||
* another line of text
|
||||
*/
|
||||
|
||||
it is requested that you make it look like this::
|
||||
|
||||
/* foobar blah blah blah
|
||||
* another line of text
|
||||
*/
|
||||
|
||||
Local variable ordering ("reverse xmas tree", "RCS")
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -392,6 +375,22 @@ When working in existing code which uses nonstandard formatting make
|
||||
your code follow the most recent guidelines, so that eventually all code
|
||||
in the domain of netdev is in the preferred format.
|
||||
|
||||
Using device-managed and cleanup.h constructs
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Netdev remains skeptical about promises of all "auto-cleanup" APIs,
|
||||
including even ``devm_`` helpers, historically. They are not the preferred
|
||||
style of implementation, merely an acceptable one.
|
||||
|
||||
Use of ``guard()`` is discouraged within any function longer than 20 lines,
|
||||
``scoped_guard()`` is considered more readable. Using normal lock/unlock is
|
||||
still (weakly) preferred.
|
||||
|
||||
Low level cleanup constructs (such as ``__free()``) can be used when building
|
||||
APIs and helpers, especially scoped iterators. However, direct use of
|
||||
``__free()`` within networking core and drivers is discouraged.
|
||||
Similar guidance applies to declaring variables mid-function.
|
||||
|
||||
Resending after review
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -145,32 +145,32 @@ This is how a well-documented Rust function may look like:
|
||||
This example showcases a few ``rustdoc`` features and some conventions followed
|
||||
in the kernel:
|
||||
|
||||
- The first paragraph must be a single sentence briefly describing what
|
||||
the documented item does. Further explanations must go in extra paragraphs.
|
||||
- The first paragraph must be a single sentence briefly describing what
|
||||
the documented item does. Further explanations must go in extra paragraphs.
|
||||
|
||||
- Unsafe functions must document their safety preconditions under
|
||||
a ``# Safety`` section.
|
||||
- Unsafe functions must document their safety preconditions under
|
||||
a ``# Safety`` section.
|
||||
|
||||
- While not shown here, if a function may panic, the conditions under which
|
||||
that happens must be described under a ``# Panics`` section.
|
||||
- While not shown here, if a function may panic, the conditions under which
|
||||
that happens must be described under a ``# Panics`` section.
|
||||
|
||||
Please note that panicking should be very rare and used only with a good
|
||||
reason. In almost all cases, a fallible approach should be used, typically
|
||||
returning a ``Result``.
|
||||
Please note that panicking should be very rare and used only with a good
|
||||
reason. In almost all cases, a fallible approach should be used, typically
|
||||
returning a ``Result``.
|
||||
|
||||
- If providing examples of usage would help readers, they must be written in
|
||||
a section called ``# Examples``.
|
||||
- If providing examples of usage would help readers, they must be written in
|
||||
a section called ``# Examples``.
|
||||
|
||||
- Rust items (functions, types, constants...) must be linked appropriately
|
||||
(``rustdoc`` will create a link automatically).
|
||||
- Rust items (functions, types, constants...) must be linked appropriately
|
||||
(``rustdoc`` will create a link automatically).
|
||||
|
||||
- Any ``unsafe`` block must be preceded by a ``// SAFETY:`` comment
|
||||
describing why the code inside is sound.
|
||||
- Any ``unsafe`` block must be preceded by a ``// SAFETY:`` comment
|
||||
describing why the code inside is sound.
|
||||
|
||||
While sometimes the reason might look trivial and therefore unneeded,
|
||||
writing these comments is not just a good way of documenting what has been
|
||||
taken into account, but most importantly, it provides a way to know that
|
||||
there are no *extra* implicit constraints.
|
||||
While sometimes the reason might look trivial and therefore unneeded,
|
||||
writing these comments is not just a good way of documenting what has been
|
||||
taken into account, but most importantly, it provides a way to know that
|
||||
there are no *extra* implicit constraints.
|
||||
|
||||
To learn more about how to write documentation for Rust and extra features,
|
||||
please take a look at the ``rustdoc`` book at:
|
||||
|
@ -305,7 +305,7 @@ If GDB/Binutils is used and Rust symbols are not getting demangled, the reason
|
||||
is the toolchain does not support Rust's new v0 mangling scheme yet.
|
||||
There are a few ways out:
|
||||
|
||||
- Install a newer release (GDB >= 10.2, Binutils >= 2.36).
|
||||
- Install a newer release (GDB >= 10.2, Binutils >= 2.36).
|
||||
|
||||
- Some versions of GDB (e.g. vanilla GDB 10.1) are able to use
|
||||
the pre-demangled names embedded in the debug info (``CONFIG_DEBUG_INFO``).
|
||||
- Some versions of GDB (e.g. vanilla GDB 10.1) are able to use
|
||||
the pre-demangled names embedded in the debug info (``CONFIG_DEBUG_INFO``).
|
||||
|
46
MAINTAINERS
46
MAINTAINERS
@ -1880,6 +1880,10 @@ F: Documentation/devicetree/bindings/iommu/arm,smmu*
|
||||
F: drivers/iommu/arm/
|
||||
F: drivers/iommu/io-pgtable-arm*
|
||||
|
||||
ARM SMMU SVA SUPPORT
|
||||
R: Jean-Philippe Brucker <jean-philippe@linaro.org>
|
||||
F: drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
|
||||
|
||||
ARM SUB-ARCHITECTURES
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
@ -2535,8 +2539,7 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Supported
|
||||
W: http://www.linux4sam.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux.git
|
||||
F: arch/arm/boot/dts/microchip/at91*
|
||||
F: arch/arm/boot/dts/microchip/sama*
|
||||
F: arch/arm/boot/dts/microchip/
|
||||
F: arch/arm/include/debug/at91.S
|
||||
F: arch/arm/mach-at91/
|
||||
F: drivers/memory/atmel*
|
||||
@ -2745,7 +2748,7 @@ F: include/linux/soc/qcom/
|
||||
|
||||
ARM/QUALCOMM SUPPORT
|
||||
M: Bjorn Andersson <andersson@kernel.org>
|
||||
M: Konrad Dybcio <konrad.dybcio@linaro.org>
|
||||
M: Konrad Dybcio <konradybcio@kernel.org>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git
|
||||
@ -3865,7 +3868,7 @@ F: kernel/trace/blktrace.c
|
||||
F: lib/sbitmap.c
|
||||
|
||||
BLOCK LAYER DEVICE DRIVER API [RUST]
|
||||
M: Andreas Hindborg <a.hindborg@samsung.com>
|
||||
M: Andreas Hindborg <a.hindborg@kernel.org>
|
||||
R: Boqun Feng <boqun.feng@gmail.com>
|
||||
L: linux-block@vger.kernel.org
|
||||
L: rust-for-linux@vger.kernel.org
|
||||
@ -5953,6 +5956,7 @@ F: Documentation/process/cve.rst
|
||||
CW1200 WLAN driver
|
||||
S: Orphan
|
||||
F: drivers/net/wireless/st/cw1200/
|
||||
F: include/linux/platform_data/net-cw1200.h
|
||||
|
||||
CX18 VIDEO4LINUX DRIVER
|
||||
M: Andy Walls <awalls@md.metrocast.net>
|
||||
@ -7108,7 +7112,7 @@ F: drivers/gpu/drm/tiny/panel-mipi-dbi.c
|
||||
DRM DRIVER for Qualcomm Adreno GPUs
|
||||
M: Rob Clark <robdclark@gmail.com>
|
||||
R: Sean Paul <sean@poorly.run>
|
||||
R: Konrad Dybcio <konrad.dybcio@linaro.org>
|
||||
R: Konrad Dybcio <konradybcio@kernel.org>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
L: freedreno@lists.freedesktop.org
|
||||
@ -7454,8 +7458,8 @@ S: Maintained
|
||||
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
|
||||
F: Documentation/devicetree/bindings/display/bridge/
|
||||
F: drivers/gpu/drm/bridge/
|
||||
F: drivers/gpu/drm/display/drm_bridge_connector.c
|
||||
F: drivers/gpu/drm/drm_bridge.c
|
||||
F: drivers/gpu/drm/drm_bridge_connector.c
|
||||
F: include/drm/drm_bridge.h
|
||||
F: include/drm/drm_bridge_connector.h
|
||||
|
||||
@ -8861,6 +8865,7 @@ F: drivers/dma/fsldma.*
|
||||
FREESCALE DSPI DRIVER
|
||||
M: Vladimir Oltean <olteanv@gmail.com>
|
||||
L: linux-spi@vger.kernel.org
|
||||
L: imx@lists.linux.dev
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/spi/fsl,dspi*.yaml
|
||||
F: drivers/spi/spi-fsl-dspi.c
|
||||
@ -8945,6 +8950,14 @@ S: Maintained
|
||||
F: Documentation/devicetree/bindings/i2c/i2c-imx-lpi2c.yaml
|
||||
F: drivers/i2c/busses/i2c-imx-lpi2c.c
|
||||
|
||||
FREESCALE IMX LPSPI DRIVER
|
||||
M: Frank Li <Frank.Li@nxp.com>
|
||||
L: linux-spi@vger.kernel.org
|
||||
L: imx@lists.linux.dev
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/spi/spi-fsl-lpspi.yaml
|
||||
F: drivers/spi/spi-fsl-lpspi.c
|
||||
|
||||
FREESCALE MPC I2C DRIVER
|
||||
M: Chris Packham <chris.packham@alliedtelesis.co.nz>
|
||||
L: linux-i2c@vger.kernel.org
|
||||
@ -8981,6 +8994,7 @@ F: include/linux/fsl/ptp_qoriq.h
|
||||
FREESCALE QUAD SPI DRIVER
|
||||
M: Han Xu <han.xu@nxp.com>
|
||||
L: linux-spi@vger.kernel.org
|
||||
L: imx@lists.linux.dev
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/spi/fsl,spi-fsl-qspi.yaml
|
||||
F: drivers/spi/spi-fsl-qspi.c
|
||||
@ -12167,7 +12181,7 @@ KERNEL NFSD, SUNRPC, AND LOCKD SERVERS
|
||||
M: Chuck Lever <chuck.lever@oracle.com>
|
||||
M: Jeff Layton <jlayton@kernel.org>
|
||||
R: Neil Brown <neilb@suse.de>
|
||||
R: Olga Kornievskaia <kolga@netapp.com>
|
||||
R: Olga Kornievskaia <okorniev@redhat.com>
|
||||
R: Dai Ngo <Dai.Ngo@oracle.com>
|
||||
R: Tom Talpey <tom@talpey.com>
|
||||
L: linux-nfs@vger.kernel.org
|
||||
@ -15892,6 +15906,8 @@ F: include/uapi/linux/ethtool_netlink.h
|
||||
F: include/uapi/linux/if_*
|
||||
F: include/uapi/linux/netdev*
|
||||
F: tools/testing/selftests/drivers/net/
|
||||
X: Documentation/devicetree/bindings/net/bluetooth/
|
||||
X: Documentation/devicetree/bindings/net/wireless/
|
||||
X: drivers/net/wireless/
|
||||
|
||||
NETWORKING DRIVERS (WIRELESS)
|
||||
@ -16405,6 +16421,7 @@ M: Han Xu <han.xu@nxp.com>
|
||||
M: Haibo Chen <haibo.chen@nxp.com>
|
||||
R: Yogesh Gaur <yogeshgaur.83@gmail.com>
|
||||
L: linux-spi@vger.kernel.org
|
||||
L: imx@lists.linux.dev
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/spi/spi-nxp-fspi.yaml
|
||||
F: drivers/spi/spi-nxp-fspi.c
|
||||
@ -17116,7 +17133,7 @@ F: include/dt-bindings/
|
||||
|
||||
OPENCOMPUTE PTP CLOCK DRIVER
|
||||
M: Jonathan Lemon <jonathan.lemon@gmail.com>
|
||||
M: Vadim Fedorenko <vadfed@linux.dev>
|
||||
M: Vadim Fedorenko <vadim.fedorenko@linux.dev>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/ptp/ptp_ocp.c
|
||||
@ -17435,6 +17452,7 @@ M: Roy Zang <roy.zang@nxp.com>
|
||||
L: linuxppc-dev@lists.ozlabs.org
|
||||
L: linux-pci@vger.kernel.org
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
L: imx@lists.linux.dev
|
||||
S: Maintained
|
||||
F: drivers/pci/controller/dwc/*layerscape*
|
||||
|
||||
@ -17461,6 +17479,7 @@ M: Richard Zhu <hongxing.zhu@nxp.com>
|
||||
M: Lucas Stach <l.stach@pengutronix.de>
|
||||
L: linux-pci@vger.kernel.org
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
L: imx@lists.linux.dev
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
|
||||
F: Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-ep.yaml
|
||||
@ -17639,6 +17658,7 @@ F: drivers/pci/controller/pci-xgene-msi.c
|
||||
PCI NATIVE HOST BRIDGE AND ENDPOINT DRIVERS
|
||||
M: Lorenzo Pieralisi <lpieralisi@kernel.org>
|
||||
M: Krzysztof Wilczyński <kw@linux.com>
|
||||
R: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
R: Rob Herring <robh@kernel.org>
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Supported
|
||||
@ -18545,7 +18565,6 @@ F: drivers/crypto/intel/qat/
|
||||
|
||||
QCOM AUDIO (ASoC) DRIVERS
|
||||
M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
M: Banajit Goswami <bgoswami@quicinc.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Supported
|
||||
@ -18794,7 +18813,7 @@ F: include/uapi/drm/qaic_accel.h
|
||||
|
||||
QUALCOMM CORE POWER REDUCTION (CPR) AVS DRIVER
|
||||
M: Bjorn Andersson <andersson@kernel.org>
|
||||
M: Konrad Dybcio <konrad.dybcio@linaro.org>
|
||||
M: Konrad Dybcio <konradybcio@kernel.org>
|
||||
L: linux-pm@vger.kernel.org
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
@ -19927,12 +19946,11 @@ F: tools/verification/
|
||||
RUST
|
||||
M: Miguel Ojeda <ojeda@kernel.org>
|
||||
M: Alex Gaynor <alex.gaynor@gmail.com>
|
||||
M: Wedson Almeida Filho <wedsonaf@gmail.com>
|
||||
R: Boqun Feng <boqun.feng@gmail.com>
|
||||
R: Gary Guo <gary@garyguo.net>
|
||||
R: Björn Roy Baron <bjorn3_gh@protonmail.com>
|
||||
R: Benno Lossin <benno.lossin@proton.me>
|
||||
R: Andreas Hindborg <a.hindborg@samsung.com>
|
||||
R: Andreas Hindborg <a.hindborg@kernel.org>
|
||||
R: Alice Ryhl <aliceryhl@google.com>
|
||||
L: rust-for-linux@vger.kernel.org
|
||||
S: Supported
|
||||
@ -23843,10 +23861,8 @@ F: drivers/media/usb/uvc/
|
||||
F: include/uapi/linux/uvcvideo.h
|
||||
|
||||
USB WEBCAM GADGET
|
||||
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
M: Daniel Scally <dan.scally@ideasonboard.com>
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
F: drivers/usb/gadget/function/*uvc*
|
||||
F: drivers/usb/gadget/legacy/webcam.c
|
||||
F: include/uapi/linux/usb/g_uvc.h
|
||||
|
3
Makefile
3
Makefile
@ -2,7 +2,7 @@
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 11
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc5
|
||||
EXTRAVERSION = -rc7
|
||||
NAME = Baby Opossum Posse
|
||||
|
||||
# *DOCUMENTATION*
|
||||
@ -445,6 +445,7 @@ KBUILD_USERLDFLAGS := $(USERLDFLAGS)
|
||||
# host programs.
|
||||
export rust_common_flags := --edition=2021 \
|
||||
-Zbinary_dep_depinfo=y \
|
||||
-Astable_features \
|
||||
-Dunsafe_op_in_unsafe_fn \
|
||||
-Dnon_ascii_idents \
|
||||
-Wrust_2018_idioms \
|
||||
|
@ -117,7 +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_LD_DEAD_CODE_DATA_ELIMINATION if (LD_VERSION >= 23600 || LD_IS_LLD)
|
||||
select HAVE_MOD_ARCH_SPECIFIC
|
||||
select HAVE_NMI
|
||||
select HAVE_OPTPROBES if !THUMB2_KERNEL
|
||||
|
@ -274,24 +274,24 @@
|
||||
|
||||
led@0 {
|
||||
chan-name = "R";
|
||||
led-cur = /bits/ 8 <0x20>;
|
||||
max-cur = /bits/ 8 <0x60>;
|
||||
led-cur = /bits/ 8 <0x6e>;
|
||||
max-cur = /bits/ 8 <0xc8>;
|
||||
reg = <0>;
|
||||
color = <LED_COLOR_ID_RED>;
|
||||
};
|
||||
|
||||
led@1 {
|
||||
chan-name = "G";
|
||||
led-cur = /bits/ 8 <0x20>;
|
||||
max-cur = /bits/ 8 <0x60>;
|
||||
led-cur = /bits/ 8 <0xbe>;
|
||||
max-cur = /bits/ 8 <0xc8>;
|
||||
reg = <1>;
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
};
|
||||
|
||||
led@2 {
|
||||
chan-name = "B";
|
||||
led-cur = /bits/ 8 <0x20>;
|
||||
max-cur = /bits/ 8 <0x60>;
|
||||
led-cur = /bits/ 8 <0xbe>;
|
||||
max-cur = /bits/ 8 <0xc8>;
|
||||
reg = <2>;
|
||||
color = <LED_COLOR_ID_BLUE>;
|
||||
};
|
||||
|
@ -781,7 +781,7 @@
|
||||
|
||||
mount-matrix = "-1", "0", "0",
|
||||
"0", "1", "0",
|
||||
"0", "0", "1";
|
||||
"0", "0", "-1";
|
||||
};
|
||||
|
||||
cam1: camera@3e {
|
||||
|
@ -29,6 +29,12 @@
|
||||
#include "entry-header.S"
|
||||
#include <asm/probes.h>
|
||||
|
||||
#ifdef CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION
|
||||
#define RELOC_TEXT_NONE .reloc .text, R_ARM_NONE, .
|
||||
#else
|
||||
#define RELOC_TEXT_NONE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Interrupt handling.
|
||||
*/
|
||||
@ -1065,7 +1071,7 @@ vector_addrexcptn:
|
||||
.globl vector_fiq
|
||||
|
||||
.section .vectors, "ax", %progbits
|
||||
.reloc .text, R_ARM_NONE, .
|
||||
RELOC_TEXT_NONE
|
||||
W(b) vector_rst
|
||||
W(b) vector_und
|
||||
ARM( .reloc ., R_ARM_LDR_PC_G0, .L__vector_swi )
|
||||
@ -1079,7 +1085,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, .
|
||||
RELOC_TEXT_NONE
|
||||
W(b) vector_rst
|
||||
W(b) vector_bhb_loop8_und
|
||||
ARM( .reloc ., R_ARM_LDR_PC_G0, .L__vector_bhb_loop8_swi )
|
||||
@ -1092,7 +1098,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, .
|
||||
RELOC_TEXT_NONE
|
||||
W(b) vector_rst
|
||||
W(b) vector_bhb_bpiall_und
|
||||
ARM( .reloc ., R_ARM_LDR_PC_G0, .L__vector_bhb_bpiall_swi )
|
||||
|
@ -175,7 +175,7 @@
|
||||
};
|
||||
};
|
||||
|
||||
core-cluster-thermal {
|
||||
cluster-thermal {
|
||||
polling-delay-passive = <1000>;
|
||||
polling-delay = <5000>;
|
||||
thermal-sensors = <&tmu 1>;
|
||||
|
@ -214,7 +214,7 @@
|
||||
};
|
||||
};
|
||||
|
||||
core-cluster-thermal {
|
||||
cluster-thermal {
|
||||
polling-delay-passive = <1000>;
|
||||
polling-delay = <5000>;
|
||||
thermal-sensors = <&tmu 3>;
|
||||
|
@ -182,7 +182,7 @@
|
||||
};
|
||||
};
|
||||
|
||||
core-cluster-thermal {
|
||||
cluster-thermal {
|
||||
polling-delay-passive = <1000>;
|
||||
polling-delay = <5000>;
|
||||
thermal-sensors = <&tmu 3>;
|
||||
|
@ -131,7 +131,7 @@
|
||||
};
|
||||
|
||||
thermal-zones {
|
||||
core-cluster-thermal {
|
||||
cluster-thermal {
|
||||
polling-delay-passive = <1000>;
|
||||
polling-delay = <5000>;
|
||||
thermal-sensors = <&tmu 0>;
|
||||
|
@ -122,7 +122,7 @@
|
||||
};
|
||||
};
|
||||
|
||||
core-cluster1-thermal {
|
||||
cluster1-thermal {
|
||||
polling-delay-passive = <1000>;
|
||||
polling-delay = <5000>;
|
||||
thermal-sensors = <&tmu 4>;
|
||||
@ -151,7 +151,7 @@
|
||||
};
|
||||
};
|
||||
|
||||
core-cluster2-thermal {
|
||||
cluster2-thermal {
|
||||
polling-delay-passive = <1000>;
|
||||
polling-delay = <5000>;
|
||||
thermal-sensors = <&tmu 5>;
|
||||
@ -180,7 +180,7 @@
|
||||
};
|
||||
};
|
||||
|
||||
core-cluster3-thermal {
|
||||
cluster3-thermal {
|
||||
polling-delay-passive = <1000>;
|
||||
polling-delay = <5000>;
|
||||
thermal-sensors = <&tmu 6>;
|
||||
@ -209,7 +209,7 @@
|
||||
};
|
||||
};
|
||||
|
||||
core-cluster4-thermal {
|
||||
cluster4-thermal {
|
||||
polling-delay-passive = <1000>;
|
||||
polling-delay = <5000>;
|
||||
thermal-sensors = <&tmu 7>;
|
||||
|
@ -492,7 +492,7 @@
|
||||
};
|
||||
};
|
||||
|
||||
ddr-cluster5-thermal {
|
||||
ddr-ctrl5-thermal {
|
||||
polling-delay-passive = <1000>;
|
||||
polling-delay = <5000>;
|
||||
thermal-sensors = <&tmu 1>;
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
&gpio3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrcl-0 = <&pinctrl_gpio3_hog>;
|
||||
pinctrl-0 = <&pinctrl_gpio3_hog>;
|
||||
|
||||
uart4_rs485_en {
|
||||
gpio-hog;
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
&gpio3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrcl-0 = <&pinctrl_gpio3_hog>;
|
||||
pinctrl-0 = <&pinctrl_gpio3_hog>;
|
||||
|
||||
uart4_rs485_en {
|
||||
gpio-hog;
|
||||
|
@ -211,13 +211,12 @@
|
||||
|
||||
simple-audio-card,cpu {
|
||||
sound-dai = <&sai3>;
|
||||
frame-master;
|
||||
bitclock-master;
|
||||
};
|
||||
|
||||
simple-audio-card,codec {
|
||||
sound-dai = <&wm8962>;
|
||||
clocks = <&clk IMX8MP_CLK_IPP_DO_CLKO1>;
|
||||
frame-master;
|
||||
bitclock-master;
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -507,10 +506,9 @@
|
||||
&sai3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_sai3>;
|
||||
assigned-clocks = <&clk IMX8MP_CLK_SAI3>,
|
||||
<&clk IMX8MP_AUDIO_PLL2> ;
|
||||
assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL2_OUT>;
|
||||
assigned-clock-rates = <12288000>, <361267200>;
|
||||
assigned-clocks = <&clk IMX8MP_CLK_SAI3>;
|
||||
assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>;
|
||||
assigned-clock-rates = <12288000>;
|
||||
fsl,sai-mclk-direction-output;
|
||||
status = "okay";
|
||||
};
|
||||
|
@ -499,7 +499,7 @@
|
||||
pinctrl-0 = <&pinctrl_usdhc2_hs>, <&pinctrl_usdhc2_gpio>;
|
||||
pinctrl-1 = <&pinctrl_usdhc2_uhs>, <&pinctrl_usdhc2_gpio>;
|
||||
pinctrl-2 = <&pinctrl_usdhc2_uhs>, <&pinctrl_usdhc2_gpio>;
|
||||
cd-gpios = <&gpio3 00 GPIO_ACTIVE_LOW>;
|
||||
cd-gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
|
||||
vmmc-supply = <®_usdhc2_vmmc>;
|
||||
bus-width = <4>;
|
||||
no-sdio;
|
||||
|
@ -19,7 +19,7 @@
|
||||
linux,cma {
|
||||
compatible = "shared-dma-pool";
|
||||
reusable;
|
||||
alloc-ranges = <0 0x60000000 0 0x40000000>;
|
||||
alloc-ranges = <0 0x80000000 0 0x40000000>;
|
||||
size = <0 0x10000000>;
|
||||
linux,cma-default;
|
||||
};
|
||||
@ -156,6 +156,7 @@
|
||||
&wdog3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_wdog>;
|
||||
fsl,ext-reset-output;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
@ -1105,7 +1105,7 @@
|
||||
<&clk IMX93_CLK_SYS_PLL_PFD0_DIV2>;
|
||||
assigned-clock-rates = <100000000>, <250000000>;
|
||||
intf_mode = <&wakeupmix_gpr 0x28>;
|
||||
snps,clk-csr = <0>;
|
||||
snps,clk-csr = <6>;
|
||||
nvmem-cells = <ð_mac2>;
|
||||
nvmem-cell-names = "mac-address";
|
||||
status = "disabled";
|
||||
|
@ -27,7 +27,7 @@
|
||||
reg = <0x0>;
|
||||
enable-method = "psci";
|
||||
#cooling-cells = <2>;
|
||||
power-domains = <&scmi_devpd IMX95_PERF_A55>;
|
||||
power-domains = <&scmi_perf IMX95_PERF_A55>;
|
||||
power-domain-names = "perf";
|
||||
i-cache-size = <32768>;
|
||||
i-cache-line-size = <64>;
|
||||
@ -44,7 +44,7 @@
|
||||
reg = <0x100>;
|
||||
enable-method = "psci";
|
||||
#cooling-cells = <2>;
|
||||
power-domains = <&scmi_devpd IMX95_PERF_A55>;
|
||||
power-domains = <&scmi_perf IMX95_PERF_A55>;
|
||||
power-domain-names = "perf";
|
||||
i-cache-size = <32768>;
|
||||
i-cache-line-size = <64>;
|
||||
@ -61,7 +61,7 @@
|
||||
reg = <0x200>;
|
||||
enable-method = "psci";
|
||||
#cooling-cells = <2>;
|
||||
power-domains = <&scmi_devpd IMX95_PERF_A55>;
|
||||
power-domains = <&scmi_perf IMX95_PERF_A55>;
|
||||
power-domain-names = "perf";
|
||||
i-cache-size = <32768>;
|
||||
i-cache-line-size = <64>;
|
||||
@ -78,7 +78,7 @@
|
||||
reg = <0x300>;
|
||||
enable-method = "psci";
|
||||
#cooling-cells = <2>;
|
||||
power-domains = <&scmi_devpd IMX95_PERF_A55>;
|
||||
power-domains = <&scmi_perf IMX95_PERF_A55>;
|
||||
power-domain-names = "perf";
|
||||
i-cache-size = <32768>;
|
||||
i-cache-line-size = <64>;
|
||||
@ -93,7 +93,7 @@
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a55";
|
||||
reg = <0x400>;
|
||||
power-domains = <&scmi_devpd IMX95_PERF_A55>;
|
||||
power-domains = <&scmi_perf IMX95_PERF_A55>;
|
||||
power-domain-names = "perf";
|
||||
enable-method = "psci";
|
||||
#cooling-cells = <2>;
|
||||
@ -110,7 +110,7 @@
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a55";
|
||||
reg = <0x500>;
|
||||
power-domains = <&scmi_devpd IMX95_PERF_A55>;
|
||||
power-domains = <&scmi_perf IMX95_PERF_A55>;
|
||||
power-domain-names = "perf";
|
||||
enable-method = "psci";
|
||||
#cooling-cells = <2>;
|
||||
@ -187,7 +187,7 @@
|
||||
compatible = "cache";
|
||||
cache-size = <524288>;
|
||||
cache-line-size = <64>;
|
||||
cache-sets = <1024>;
|
||||
cache-sets = <512>;
|
||||
cache-level = <3>;
|
||||
cache-unified;
|
||||
};
|
||||
|
@ -320,8 +320,8 @@
|
||||
reg = <0x08af8800 0x400>;
|
||||
|
||||
interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 53 IRQ_TYPE_EDGE_BOTH>,
|
||||
<GIC_SPI 52 IRQ_TYPE_EDGE_BOTH>;
|
||||
<GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "pwr_event",
|
||||
"dp_hs_phy_irq",
|
||||
"dm_hs_phy_irq";
|
||||
|
@ -278,6 +278,13 @@
|
||||
vdd-l3-supply = <&vreg_s1f_0p7>;
|
||||
vdd-s1-supply = <&vph_pwr>;
|
||||
vdd-s2-supply = <&vph_pwr>;
|
||||
|
||||
vreg_l3i_0p8: ldo3 {
|
||||
regulator-name = "vreg_l3i_0p8";
|
||||
regulator-min-microvolt = <880000>;
|
||||
regulator-max-microvolt = <920000>;
|
||||
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
|
||||
};
|
||||
};
|
||||
|
||||
regulators-7 {
|
||||
@ -423,11 +430,17 @@
|
||||
};
|
||||
|
||||
&pcie4 {
|
||||
perst-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>;
|
||||
wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>;
|
||||
|
||||
pinctrl-0 = <&pcie4_default>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pcie4_phy {
|
||||
vdda-phy-supply = <&vreg_l3j_0p8>;
|
||||
vdda-phy-supply = <&vreg_l3i_0p8>;
|
||||
vdda-pll-supply = <&vreg_l3e_1p2>;
|
||||
|
||||
status = "okay";
|
||||
@ -517,7 +530,30 @@
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
pcie6a_default: pcie2a-default-state {
|
||||
pcie4_default: pcie4-default-state {
|
||||
clkreq-n-pins {
|
||||
pins = "gpio147";
|
||||
function = "pcie4_clk";
|
||||
drive-strength = <2>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
perst-n-pins {
|
||||
pins = "gpio146";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
wake-n-pins {
|
||||
pins = "gpio148";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
pcie6a_default: pcie6a-default-state {
|
||||
clkreq-n-pins {
|
||||
pins = "gpio153";
|
||||
function = "pcie6a_clk";
|
||||
@ -529,7 +565,7 @@
|
||||
pins = "gpio152";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-pull-down;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
wake-n-pins {
|
||||
|
@ -268,7 +268,6 @@
|
||||
pinctrl-0 = <&edp_reg_en>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
@ -637,6 +636,14 @@
|
||||
};
|
||||
};
|
||||
|
||||
&gpu {
|
||||
status = "okay";
|
||||
|
||||
zap-shader {
|
||||
firmware-name = "qcom/x1e80100/gen70500_zap.mbn";
|
||||
};
|
||||
};
|
||||
|
||||
&i2c0 {
|
||||
clock-frequency = <400000>;
|
||||
|
||||
@ -724,9 +731,13 @@
|
||||
|
||||
aux-bus {
|
||||
panel {
|
||||
compatible = "edp-panel";
|
||||
compatible = "samsung,atna45af01", "samsung,atna33xc20";
|
||||
enable-gpios = <&pmc8380_3_gpios 4 GPIO_ACTIVE_HIGH>;
|
||||
power-supply = <&vreg_edp_3p3>;
|
||||
|
||||
pinctrl-0 = <&edp_bl_en>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
port {
|
||||
edp_panel_in: endpoint {
|
||||
remote-endpoint = <&mdss_dp3_out>;
|
||||
@ -756,11 +767,17 @@
|
||||
};
|
||||
|
||||
&pcie4 {
|
||||
perst-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>;
|
||||
wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>;
|
||||
|
||||
pinctrl-0 = <&pcie4_default>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pcie4_phy {
|
||||
vdda-phy-supply = <&vreg_l3j_0p8>;
|
||||
vdda-phy-supply = <&vreg_l3i_0p8>;
|
||||
vdda-pll-supply = <&vreg_l3e_1p2>;
|
||||
|
||||
status = "okay";
|
||||
@ -785,6 +802,16 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pmc8380_3_gpios {
|
||||
edp_bl_en: edp-bl-en-state {
|
||||
pins = "gpio4";
|
||||
function = "normal";
|
||||
power-source = <1>; /* 1.8V */
|
||||
input-disable;
|
||||
output-enable;
|
||||
};
|
||||
};
|
||||
|
||||
&qupv3_0 {
|
||||
status = "okay";
|
||||
};
|
||||
@ -931,7 +958,30 @@
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
pcie6a_default: pcie2a-default-state {
|
||||
pcie4_default: pcie4-default-state {
|
||||
clkreq-n-pins {
|
||||
pins = "gpio147";
|
||||
function = "pcie4_clk";
|
||||
drive-strength = <2>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
perst-n-pins {
|
||||
pins = "gpio146";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
wake-n-pins {
|
||||
pins = "gpio148";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
pcie6a_default: pcie6a-default-state {
|
||||
clkreq-n-pins {
|
||||
pins = "gpio153";
|
||||
function = "pcie6a_clk";
|
||||
@ -943,15 +993,15 @@
|
||||
pins = "gpio152";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-pull-down;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
wake-n-pins {
|
||||
pins = "gpio154";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-pull-up;
|
||||
};
|
||||
pins = "gpio154";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
tpad_default: tpad-default-state {
|
||||
|
@ -625,16 +625,31 @@
|
||||
};
|
||||
|
||||
&pcie4 {
|
||||
perst-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>;
|
||||
wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>;
|
||||
|
||||
pinctrl-0 = <&pcie4_default>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pcie4_phy {
|
||||
vdda-phy-supply = <&vreg_l3j_0p8>;
|
||||
vdda-phy-supply = <&vreg_l3i_0p8>;
|
||||
vdda-pll-supply = <&vreg_l3e_1p2>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pcie4_port0 {
|
||||
wifi@0 {
|
||||
compatible = "pci17cb,1107";
|
||||
reg = <0x10000 0x0 0x0 0x0 0x0>;
|
||||
|
||||
qcom,ath12k-calibration-variant = "LES790";
|
||||
};
|
||||
};
|
||||
|
||||
&pcie6a {
|
||||
perst-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>;
|
||||
wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>;
|
||||
@ -782,7 +797,30 @@
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
pcie6a_default: pcie2a-default-state {
|
||||
pcie4_default: pcie4-default-state {
|
||||
clkreq-n-pins {
|
||||
pins = "gpio147";
|
||||
function = "pcie4_clk";
|
||||
drive-strength = <2>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
perst-n-pins {
|
||||
pins = "gpio146";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
wake-n-pins {
|
||||
pins = "gpio148";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
pcie6a_default: pcie6a-default-state {
|
||||
clkreq-n-pins {
|
||||
pins = "gpio153";
|
||||
function = "pcie6a_clk";
|
||||
@ -794,15 +832,15 @@
|
||||
pins = "gpio152";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-pull-down;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
wake-n-pins {
|
||||
pins = "gpio154";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-pull-up;
|
||||
};
|
||||
pins = "gpio154";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
tpad_default: tpad-default-state {
|
||||
|
@ -606,6 +606,14 @@
|
||||
};
|
||||
};
|
||||
|
||||
&gpu {
|
||||
status = "okay";
|
||||
|
||||
zap-shader {
|
||||
firmware-name = "qcom/x1e80100/gen70500_zap.mbn";
|
||||
};
|
||||
};
|
||||
|
||||
&lpass_tlmm {
|
||||
spkr_01_sd_n_active: spkr-01-sd-n-active-state {
|
||||
pins = "gpio12";
|
||||
@ -660,11 +668,17 @@
|
||||
};
|
||||
|
||||
&pcie4 {
|
||||
perst-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>;
|
||||
wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>;
|
||||
|
||||
pinctrl-0 = <&pcie4_default>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pcie4_phy {
|
||||
vdda-phy-supply = <&vreg_l3j_0p8>;
|
||||
vdda-phy-supply = <&vreg_l3i_0p8>;
|
||||
vdda-pll-supply = <&vreg_l3e_1p2>;
|
||||
|
||||
status = "okay";
|
||||
@ -804,7 +818,30 @@
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
pcie6a_default: pcie2a-default-state {
|
||||
pcie4_default: pcie4-default-state {
|
||||
clkreq-n-pins {
|
||||
pins = "gpio147";
|
||||
function = "pcie4_clk";
|
||||
drive-strength = <2>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
perst-n-pins {
|
||||
pins = "gpio146";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
wake-n-pins {
|
||||
pins = "gpio148";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
pcie6a_default: pcie6a-default-state {
|
||||
clkreq-n-pins {
|
||||
pins = "gpio153";
|
||||
function = "pcie6a_clk";
|
||||
@ -816,15 +853,15 @@
|
||||
pins = "gpio152";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-pull-down;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
wake-n-pins {
|
||||
pins = "gpio154";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-pull-up;
|
||||
};
|
||||
pins = "gpio154";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
wcd_default: wcd-reset-n-active-state {
|
||||
|
@ -2901,7 +2901,7 @@
|
||||
|
||||
dma-coherent;
|
||||
|
||||
linux,pci-domain = <7>;
|
||||
linux,pci-domain = <6>;
|
||||
num-lanes = <2>;
|
||||
|
||||
interrupts = <GIC_SPI 773 IRQ_TYPE_LEVEL_HIGH>,
|
||||
@ -2959,6 +2959,7 @@
|
||||
"link_down";
|
||||
|
||||
power-domains = <&gcc GCC_PCIE_6A_GDSC>;
|
||||
required-opps = <&rpmhpd_opp_nom>;
|
||||
|
||||
phys = <&pcie6a_phy>;
|
||||
phy-names = "pciephy";
|
||||
@ -3022,7 +3023,7 @@
|
||||
|
||||
dma-coherent;
|
||||
|
||||
linux,pci-domain = <5>;
|
||||
linux,pci-domain = <4>;
|
||||
num-lanes = <2>;
|
||||
|
||||
interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
|
||||
@ -3080,11 +3081,22 @@
|
||||
"link_down";
|
||||
|
||||
power-domains = <&gcc GCC_PCIE_4_GDSC>;
|
||||
required-opps = <&rpmhpd_opp_nom>;
|
||||
|
||||
phys = <&pcie4_phy>;
|
||||
phy-names = "pciephy";
|
||||
|
||||
status = "disabled";
|
||||
|
||||
pcie4_port0: pcie@0 {
|
||||
device_type = "pci";
|
||||
reg = <0x0 0x0 0x0 0x0 0x0>;
|
||||
bus-range = <0x01 0xff>;
|
||||
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
};
|
||||
};
|
||||
|
||||
pcie4_phy: phy@1c0e000 {
|
||||
@ -3155,9 +3167,10 @@
|
||||
interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>;
|
||||
interconnect-names = "gfx-mem";
|
||||
|
||||
status = "disabled";
|
||||
|
||||
zap-shader {
|
||||
memory-region = <&gpu_microcode_mem>;
|
||||
firmware-name = "qcom/gen70500_zap.mbn";
|
||||
};
|
||||
|
||||
gpu_opp_table: opp-table {
|
||||
@ -3288,7 +3301,7 @@
|
||||
reg = <0x0 0x03da0000 0x0 0x40000>;
|
||||
#iommu-cells = <2>;
|
||||
#global-interrupts = <1>;
|
||||
interrupts = <GIC_SPI 673 IRQ_TYPE_LEVEL_HIGH>,
|
||||
interrupts = <GIC_SPI 674 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 678 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 679 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 680 IRQ_TYPE_LEVEL_HIGH>,
|
||||
|
@ -887,6 +887,7 @@ CONFIG_DRM_PANEL_KHADAS_TS050=m
|
||||
CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m
|
||||
CONFIG_DRM_PANEL_NOVATEK_NT36672E=m
|
||||
CONFIG_DRM_PANEL_RAYDIUM_RM67191=m
|
||||
CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20=m
|
||||
CONFIG_DRM_PANEL_SITRONIX_ST7703=m
|
||||
CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m
|
||||
CONFIG_DRM_PANEL_VISIONOX_VTDR6130=m
|
||||
|
@ -25,6 +25,7 @@
|
||||
*
|
||||
* @common: Common unwind state.
|
||||
* @task: The task being unwound.
|
||||
* @graph_idx: Used by ftrace_graph_ret_addr() for optimized stack unwinding.
|
||||
* @kr_cur: When KRETPROBES is selected, holds the kretprobe instance
|
||||
* associated with the most recently encountered replacement lr
|
||||
* value.
|
||||
@ -32,6 +33,7 @@
|
||||
struct kunwind_state {
|
||||
struct unwind_state common;
|
||||
struct task_struct *task;
|
||||
int graph_idx;
|
||||
#ifdef CONFIG_KRETPROBES
|
||||
struct llist_node *kr_cur;
|
||||
#endif
|
||||
@ -106,7 +108,7 @@ kunwind_recover_return_address(struct kunwind_state *state)
|
||||
if (state->task->ret_stack &&
|
||||
(state->common.pc == (unsigned long)return_to_handler)) {
|
||||
unsigned long orig_pc;
|
||||
orig_pc = ftrace_graph_ret_addr(state->task, NULL,
|
||||
orig_pc = ftrace_graph_ret_addr(state->task, &state->graph_idx,
|
||||
state->common.pc,
|
||||
(void *)state->common.fp);
|
||||
if (WARN_ON_ONCE(state->common.pc == orig_pc))
|
||||
|
@ -6,7 +6,6 @@ generic-y += mcs_spinlock.h
|
||||
generic-y += parport.h
|
||||
generic-y += early_ioremap.h
|
||||
generic-y += qrwlock.h
|
||||
generic-y += qspinlock.h
|
||||
generic-y += user.h
|
||||
generic-y += ioctl.h
|
||||
generic-y += statfs.h
|
||||
|
@ -1,11 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited
|
||||
*/
|
||||
#ifndef _LOONGARCH_DMA_DIRECT_H
|
||||
#define _LOONGARCH_DMA_DIRECT_H
|
||||
|
||||
dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
|
||||
phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
|
||||
|
||||
#endif /* _LOONGARCH_DMA_DIRECT_H */
|
@ -9,6 +9,8 @@
|
||||
|
||||
extern atomic_t irq_err_count;
|
||||
|
||||
#define ARCH_IRQ_INIT_FLAGS IRQ_NOPROBE
|
||||
|
||||
/*
|
||||
* interrupt-retrigger: NOP for now. This may not be appropriate for all
|
||||
* machines, we'll see ...
|
||||
|
@ -30,6 +30,7 @@
|
||||
: [val] "+r" (__v) \
|
||||
: [reg] "i" (csr) \
|
||||
: "memory"); \
|
||||
__v; \
|
||||
})
|
||||
|
||||
#define gcsr_xchg(v, m, csr) \
|
||||
@ -181,6 +182,8 @@ __BUILD_GCSR_OP(tlbidx)
|
||||
#define kvm_save_hw_gcsr(csr, gid) (csr->csrs[gid] = gcsr_read(gid))
|
||||
#define kvm_restore_hw_gcsr(csr, gid) (gcsr_write(csr->csrs[gid], gid))
|
||||
|
||||
#define kvm_read_clear_hw_gcsr(csr, gid) (csr->csrs[gid] = gcsr_write(0, gid))
|
||||
|
||||
int kvm_emu_iocsr(larch_inst inst, struct kvm_run *run, struct kvm_vcpu *vcpu);
|
||||
|
||||
static __always_inline unsigned long kvm_read_sw_gcsr(struct loongarch_csrs *csr, int gid)
|
||||
@ -208,4 +211,7 @@ static __always_inline void kvm_change_sw_gcsr(struct loongarch_csrs *csr,
|
||||
csr->csrs[gid] |= val & _mask;
|
||||
}
|
||||
|
||||
#define KVM_PMU_EVENT_ENABLED (CSR_PERFCTRL_PLV0 | CSR_PERFCTRL_PLV1 | \
|
||||
CSR_PERFCTRL_PLV2 | CSR_PERFCTRL_PLV3)
|
||||
|
||||
#endif /* __ASM_LOONGARCH_KVM_CSR_H__ */
|
||||
|
@ -30,6 +30,7 @@
|
||||
#define KVM_HALT_POLL_NS_DEFAULT 500000
|
||||
#define KVM_REQ_TLB_FLUSH_GPA KVM_ARCH_REQ(0)
|
||||
#define KVM_REQ_STEAL_UPDATE KVM_ARCH_REQ(1)
|
||||
#define KVM_REQ_PMU KVM_ARCH_REQ(2)
|
||||
|
||||
#define KVM_GUESTDBG_SW_BP_MASK \
|
||||
(KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)
|
||||
@ -60,9 +61,13 @@ struct kvm_arch_memory_slot {
|
||||
unsigned long flags;
|
||||
};
|
||||
|
||||
#define HOST_MAX_PMNUM 16
|
||||
struct kvm_context {
|
||||
unsigned long vpid_cache;
|
||||
struct kvm_vcpu *last_vcpu;
|
||||
/* Host PMU CSR */
|
||||
u64 perf_ctrl[HOST_MAX_PMNUM];
|
||||
u64 perf_cntr[HOST_MAX_PMNUM];
|
||||
};
|
||||
|
||||
struct kvm_world_switch {
|
||||
@ -107,6 +112,8 @@ struct kvm_arch {
|
||||
unsigned int root_level;
|
||||
spinlock_t phyid_map_lock;
|
||||
struct kvm_phyid_map *phyid_map;
|
||||
/* Enabled PV features */
|
||||
unsigned long pv_features;
|
||||
|
||||
s64 time_offset;
|
||||
struct kvm_context __percpu *vmcs;
|
||||
@ -133,8 +140,15 @@ enum emulation_result {
|
||||
#define KVM_LARCH_FPU (0x1 << 0)
|
||||
#define KVM_LARCH_LSX (0x1 << 1)
|
||||
#define KVM_LARCH_LASX (0x1 << 2)
|
||||
#define KVM_LARCH_SWCSR_LATEST (0x1 << 3)
|
||||
#define KVM_LARCH_HWCSR_USABLE (0x1 << 4)
|
||||
#define KVM_LARCH_LBT (0x1 << 3)
|
||||
#define KVM_LARCH_PMU (0x1 << 4)
|
||||
#define KVM_LARCH_SWCSR_LATEST (0x1 << 5)
|
||||
#define KVM_LARCH_HWCSR_USABLE (0x1 << 6)
|
||||
|
||||
#define LOONGARCH_PV_FEAT_UPDATED BIT_ULL(63)
|
||||
#define LOONGARCH_PV_FEAT_MASK (BIT(KVM_FEATURE_IPI) | \
|
||||
BIT(KVM_FEATURE_STEAL_TIME) | \
|
||||
BIT(KVM_FEATURE_VIRT_EXTIOI))
|
||||
|
||||
struct kvm_vcpu_arch {
|
||||
/*
|
||||
@ -168,10 +182,14 @@ struct kvm_vcpu_arch {
|
||||
|
||||
/* FPU state */
|
||||
struct loongarch_fpu fpu FPU_ALIGN;
|
||||
struct loongarch_lbt lbt;
|
||||
|
||||
/* CSR state */
|
||||
struct loongarch_csrs *csr;
|
||||
|
||||
/* Guest max PMU CSR id */
|
||||
int max_pmu_csrid;
|
||||
|
||||
/* GPR used as IO source/target */
|
||||
u32 io_gpr;
|
||||
|
||||
@ -239,6 +257,21 @@ static inline bool kvm_guest_has_lasx(struct kvm_vcpu_arch *arch)
|
||||
return arch->cpucfg[2] & CPUCFG2_LASX;
|
||||
}
|
||||
|
||||
static inline bool kvm_guest_has_lbt(struct kvm_vcpu_arch *arch)
|
||||
{
|
||||
return arch->cpucfg[2] & (CPUCFG2_X86BT | CPUCFG2_ARMBT | CPUCFG2_MIPSBT);
|
||||
}
|
||||
|
||||
static inline bool kvm_guest_has_pmu(struct kvm_vcpu_arch *arch)
|
||||
{
|
||||
return arch->cpucfg[6] & CPUCFG6_PMP;
|
||||
}
|
||||
|
||||
static inline int kvm_get_pmu_num(struct kvm_vcpu_arch *arch)
|
||||
{
|
||||
return (arch->cpucfg[6] & CPUCFG6_PMNUM) >> CPUCFG6_PMNUM_SHIFT;
|
||||
}
|
||||
|
||||
/* Debug: dump vcpu state */
|
||||
int kvm_arch_vcpu_dump_regs(struct kvm_vcpu *vcpu);
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
#ifndef _ASM_LOONGARCH_KVM_PARA_H
|
||||
#define _ASM_LOONGARCH_KVM_PARA_H
|
||||
|
||||
#include <uapi/asm/kvm_para.h>
|
||||
|
||||
/*
|
||||
* Hypercall code field
|
||||
*/
|
||||
@ -154,10 +156,20 @@ static __always_inline long kvm_hypercall5(u64 fid,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
bool kvm_para_available(void);
|
||||
unsigned int kvm_arch_para_features(void);
|
||||
#else
|
||||
static inline bool kvm_para_available(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline unsigned int kvm_arch_para_features(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline unsigned int kvm_arch_para_hints(void)
|
||||
{
|
||||
|
@ -75,8 +75,13 @@ static inline void kvm_save_lasx(struct loongarch_fpu *fpu) { }
|
||||
static inline void kvm_restore_lasx(struct loongarch_fpu *fpu) { }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_LBT
|
||||
int kvm_own_lbt(struct kvm_vcpu *vcpu);
|
||||
#else
|
||||
static inline int kvm_own_lbt(struct kvm_vcpu *vcpu) { return -EINVAL; }
|
||||
#endif
|
||||
|
||||
void kvm_init_timer(struct kvm_vcpu *vcpu, unsigned long hz);
|
||||
void kvm_reset_timer(struct kvm_vcpu *vcpu);
|
||||
void kvm_save_timer(struct kvm_vcpu *vcpu);
|
||||
void kvm_restore_timer(struct kvm_vcpu *vcpu);
|
||||
|
||||
@ -125,4 +130,9 @@ static inline bool kvm_pvtime_supported(void)
|
||||
return !!sched_info_on();
|
||||
}
|
||||
|
||||
static inline bool kvm_guest_has_pv_feature(struct kvm_vcpu *vcpu, unsigned int feature)
|
||||
{
|
||||
return vcpu->kvm->arch.pv_features & BIT(feature);
|
||||
}
|
||||
|
||||
#endif /* __ASM_LOONGARCH_KVM_VCPU_H__ */
|
||||
|
@ -119,6 +119,7 @@
|
||||
#define CPUCFG6_PMP BIT(0)
|
||||
#define CPUCFG6_PAMVER GENMASK(3, 1)
|
||||
#define CPUCFG6_PMNUM GENMASK(7, 4)
|
||||
#define CPUCFG6_PMNUM_SHIFT 4
|
||||
#define CPUCFG6_PMBITS GENMASK(13, 8)
|
||||
#define CPUCFG6_UPM BIT(14)
|
||||
|
||||
@ -160,16 +161,8 @@
|
||||
|
||||
/*
|
||||
* CPUCFG index area: 0x40000000 -- 0x400000ff
|
||||
* SW emulation for KVM hypervirsor
|
||||
* SW emulation for KVM hypervirsor, see arch/loongarch/include/uapi/asm/kvm_para.h
|
||||
*/
|
||||
#define CPUCFG_KVM_BASE 0x40000000
|
||||
#define CPUCFG_KVM_SIZE 0x100
|
||||
|
||||
#define CPUCFG_KVM_SIG (CPUCFG_KVM_BASE + 0)
|
||||
#define KVM_SIGNATURE "KVM\0"
|
||||
#define CPUCFG_KVM_FEATURE (CPUCFG_KVM_BASE + 4)
|
||||
#define KVM_FEATURE_IPI BIT(1)
|
||||
#define KVM_FEATURE_STEAL_TIME BIT(2)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
|
@ -19,6 +19,7 @@ static inline u64 paravirt_steal_clock(int cpu)
|
||||
|
||||
int __init pv_ipi_init(void);
|
||||
int __init pv_time_init(void);
|
||||
int __init pv_spinlock_init(void);
|
||||
|
||||
#else
|
||||
|
||||
@ -31,5 +32,11 @@ static inline int pv_time_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pv_spinlock_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // CONFIG_PARAVIRT
|
||||
#endif
|
||||
|
41
arch/loongarch/include/asm/qspinlock.h
Normal file
41
arch/loongarch/include/asm/qspinlock.h
Normal file
@ -0,0 +1,41 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_LOONGARCH_QSPINLOCK_H
|
||||
#define _ASM_LOONGARCH_QSPINLOCK_H
|
||||
|
||||
#include <linux/jump_label.h>
|
||||
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
|
||||
DECLARE_STATIC_KEY_FALSE(virt_spin_lock_key);
|
||||
|
||||
#define virt_spin_lock virt_spin_lock
|
||||
|
||||
static inline bool virt_spin_lock(struct qspinlock *lock)
|
||||
{
|
||||
int val;
|
||||
|
||||
if (!static_branch_unlikely(&virt_spin_lock_key))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* On hypervisors without PARAVIRT_SPINLOCKS support we fall
|
||||
* back to a Test-and-Set spinlock, because fair locks have
|
||||
* horrible lock 'holder' preemption issues.
|
||||
*/
|
||||
|
||||
__retry:
|
||||
val = atomic_read(&lock->val);
|
||||
|
||||
if (val || !atomic_try_cmpxchg(&lock->val, &val, _Q_LOCKED_VAL)) {
|
||||
cpu_relax();
|
||||
goto __retry;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PARAVIRT */
|
||||
|
||||
#include <asm-generic/qspinlock.h>
|
||||
|
||||
#endif // _ASM_LOONGARCH_QSPINLOCK_H
|
@ -1,4 +1,2 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
syscall-y += unistd_64.h
|
||||
|
||||
generic-y += kvm_para.h
|
||||
|
@ -64,6 +64,7 @@ struct kvm_fpu {
|
||||
#define KVM_REG_LOONGARCH_KVM (KVM_REG_LOONGARCH | 0x20000ULL)
|
||||
#define KVM_REG_LOONGARCH_FPSIMD (KVM_REG_LOONGARCH | 0x30000ULL)
|
||||
#define KVM_REG_LOONGARCH_CPUCFG (KVM_REG_LOONGARCH | 0x40000ULL)
|
||||
#define KVM_REG_LOONGARCH_LBT (KVM_REG_LOONGARCH | 0x50000ULL)
|
||||
#define KVM_REG_LOONGARCH_MASK (KVM_REG_LOONGARCH | 0x70000ULL)
|
||||
#define KVM_CSR_IDX_MASK 0x7fff
|
||||
#define KVM_CPUCFG_IDX_MASK 0x7fff
|
||||
@ -77,11 +78,30 @@ struct kvm_fpu {
|
||||
/* Debugging: Special instruction for software breakpoint */
|
||||
#define KVM_REG_LOONGARCH_DEBUG_INST (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 3)
|
||||
|
||||
/* LBT registers */
|
||||
#define KVM_REG_LOONGARCH_LBT_SCR0 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 1)
|
||||
#define KVM_REG_LOONGARCH_LBT_SCR1 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 2)
|
||||
#define KVM_REG_LOONGARCH_LBT_SCR2 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 3)
|
||||
#define KVM_REG_LOONGARCH_LBT_SCR3 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 4)
|
||||
#define KVM_REG_LOONGARCH_LBT_EFLAGS (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 5)
|
||||
#define KVM_REG_LOONGARCH_LBT_FTOP (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 6)
|
||||
|
||||
#define LOONGARCH_REG_SHIFT 3
|
||||
#define LOONGARCH_REG_64(TYPE, REG) (TYPE | KVM_REG_SIZE_U64 | (REG << LOONGARCH_REG_SHIFT))
|
||||
#define KVM_IOC_CSRID(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CSR, REG)
|
||||
#define KVM_IOC_CPUCFG(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CPUCFG, REG)
|
||||
|
||||
/* Device Control API on vm fd */
|
||||
#define KVM_LOONGARCH_VM_FEAT_CTRL 0
|
||||
#define KVM_LOONGARCH_VM_FEAT_LSX 0
|
||||
#define KVM_LOONGARCH_VM_FEAT_LASX 1
|
||||
#define KVM_LOONGARCH_VM_FEAT_X86BT 2
|
||||
#define KVM_LOONGARCH_VM_FEAT_ARMBT 3
|
||||
#define KVM_LOONGARCH_VM_FEAT_MIPSBT 4
|
||||
#define KVM_LOONGARCH_VM_FEAT_PMU 5
|
||||
#define KVM_LOONGARCH_VM_FEAT_PV_IPI 6
|
||||
#define KVM_LOONGARCH_VM_FEAT_PV_STEALTIME 7
|
||||
|
||||
/* Device Control API on vcpu fd */
|
||||
#define KVM_LOONGARCH_VCPU_CPUCFG 0
|
||||
#define KVM_LOONGARCH_VCPU_PVTIME_CTRL 1
|
||||
|
21
arch/loongarch/include/uapi/asm/kvm_para.h
Normal file
21
arch/loongarch/include/uapi/asm/kvm_para.h
Normal file
@ -0,0 +1,21 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
#ifndef _UAPI_ASM_KVM_PARA_H
|
||||
#define _UAPI_ASM_KVM_PARA_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/*
|
||||
* CPUCFG index area: 0x40000000 -- 0x400000ff
|
||||
* SW emulation for KVM hypervirsor
|
||||
*/
|
||||
#define CPUCFG_KVM_BASE 0x40000000
|
||||
#define CPUCFG_KVM_SIZE 0x100
|
||||
#define CPUCFG_KVM_SIG (CPUCFG_KVM_BASE + 0)
|
||||
#define KVM_SIGNATURE "KVM\0"
|
||||
#define CPUCFG_KVM_FEATURE (CPUCFG_KVM_BASE + 4)
|
||||
#define KVM_FEATURE_IPI 1
|
||||
#define KVM_FEATURE_STEAL_TIME 2
|
||||
/* BIT 24 - 31 are features configurable by user space vmm */
|
||||
#define KVM_FEATURE_VIRT_EXTIOI 24
|
||||
|
||||
#endif /* _UAPI_ASM_KVM_PARA_H */
|
@ -530,6 +530,10 @@ SYM_FUNC_END(_restore_lasx_context)
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_LBT
|
||||
STACK_FRAME_NON_STANDARD _restore_fp
|
||||
#ifdef CONFIG_CPU_HAS_LSX
|
||||
STACK_FRAME_NON_STANDARD _restore_lsx
|
||||
#endif
|
||||
#ifdef CONFIG_CPU_HAS_LASX
|
||||
STACK_FRAME_NON_STANDARD _restore_lasx
|
||||
#endif
|
||||
#endif
|
||||
|
@ -102,9 +102,6 @@ void __init init_IRQ(void)
|
||||
mp_ops.init_ipi();
|
||||
#endif
|
||||
|
||||
for (i = 0; i < NR_IRQS; i++)
|
||||
irq_set_noprobe(i);
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
page = alloc_pages_node(cpu_to_node(i), GFP_KERNEL, order);
|
||||
|
||||
|
@ -13,6 +13,7 @@ static int has_steal_clock;
|
||||
struct static_key paravirt_steal_enabled;
|
||||
struct static_key paravirt_steal_rq_enabled;
|
||||
static DEFINE_PER_CPU(struct kvm_steal_time, steal_time) __aligned(64);
|
||||
DEFINE_STATIC_KEY_FALSE(virt_spin_lock_key);
|
||||
|
||||
static u64 native_steal_clock(int cpu)
|
||||
{
|
||||
@ -151,11 +152,14 @@ static void pv_init_ipi(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool kvm_para_available(void)
|
||||
bool kvm_para_available(void)
|
||||
{
|
||||
int config;
|
||||
static int hypervisor_type;
|
||||
|
||||
if (!cpu_has_hypervisor)
|
||||
return false;
|
||||
|
||||
if (!hypervisor_type) {
|
||||
config = read_cpucfg(CPUCFG_KVM_SIG);
|
||||
if (!memcmp(&config, KVM_SIGNATURE, 4))
|
||||
@ -165,17 +169,22 @@ static bool kvm_para_available(void)
|
||||
return hypervisor_type == HYPERVISOR_KVM;
|
||||
}
|
||||
|
||||
int __init pv_ipi_init(void)
|
||||
unsigned int kvm_arch_para_features(void)
|
||||
{
|
||||
int feature;
|
||||
static unsigned int feature;
|
||||
|
||||
if (!cpu_has_hypervisor)
|
||||
return 0;
|
||||
if (!kvm_para_available())
|
||||
return 0;
|
||||
|
||||
feature = read_cpucfg(CPUCFG_KVM_FEATURE);
|
||||
if (!(feature & KVM_FEATURE_IPI))
|
||||
if (!feature)
|
||||
feature = read_cpucfg(CPUCFG_KVM_FEATURE);
|
||||
|
||||
return feature;
|
||||
}
|
||||
|
||||
int __init pv_ipi_init(void)
|
||||
{
|
||||
if (!kvm_para_has_feature(KVM_FEATURE_IPI))
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
@ -206,7 +215,7 @@ static int pv_enable_steal_time(void)
|
||||
}
|
||||
|
||||
addr |= KVM_STEAL_PHYS_VALID;
|
||||
kvm_hypercall2(KVM_HCALL_FUNC_NOTIFY, KVM_FEATURE_STEAL_TIME, addr);
|
||||
kvm_hypercall2(KVM_HCALL_FUNC_NOTIFY, BIT(KVM_FEATURE_STEAL_TIME), addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -214,7 +223,7 @@ static int pv_enable_steal_time(void)
|
||||
static void pv_disable_steal_time(void)
|
||||
{
|
||||
if (has_steal_clock)
|
||||
kvm_hypercall2(KVM_HCALL_FUNC_NOTIFY, KVM_FEATURE_STEAL_TIME, 0);
|
||||
kvm_hypercall2(KVM_HCALL_FUNC_NOTIFY, BIT(KVM_FEATURE_STEAL_TIME), 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
@ -258,15 +267,9 @@ static struct notifier_block pv_reboot_nb = {
|
||||
|
||||
int __init pv_time_init(void)
|
||||
{
|
||||
int r, feature;
|
||||
int r;
|
||||
|
||||
if (!cpu_has_hypervisor)
|
||||
return 0;
|
||||
if (!kvm_para_available())
|
||||
return 0;
|
||||
|
||||
feature = read_cpucfg(CPUCFG_KVM_FEATURE);
|
||||
if (!(feature & KVM_FEATURE_STEAL_TIME))
|
||||
if (!kvm_para_has_feature(KVM_FEATURE_STEAL_TIME))
|
||||
return 0;
|
||||
|
||||
has_steal_clock = 1;
|
||||
@ -300,3 +303,13 @@ int __init pv_time_init(void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __init pv_spinlock_init(void)
|
||||
{
|
||||
if (!cpu_has_hypervisor)
|
||||
return 0;
|
||||
|
||||
static_branch_enable(&virt_spin_lock_key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -603,6 +603,8 @@ void __init setup_arch(char **cmdline_p)
|
||||
arch_mem_init(cmdline_p);
|
||||
|
||||
resource_init();
|
||||
jump_label_init(); /* Initialise the static keys for paravirtualization */
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
plat_smp_setup();
|
||||
prefill_possible_map();
|
||||
|
@ -476,7 +476,7 @@ core_initcall(ipi_pm_init);
|
||||
#endif
|
||||
|
||||
/* Preload SMP state for boot cpu */
|
||||
void smp_prepare_boot_cpu(void)
|
||||
void __init smp_prepare_boot_cpu(void)
|
||||
{
|
||||
unsigned int cpu, node, rr_node;
|
||||
|
||||
@ -509,6 +509,8 @@ void smp_prepare_boot_cpu(void)
|
||||
rr_node = next_node_in(rr_node, node_online_map);
|
||||
}
|
||||
}
|
||||
|
||||
pv_spinlock_init();
|
||||
}
|
||||
|
||||
/* called from main before smp_init() */
|
||||
|
@ -50,9 +50,7 @@ static int kvm_emu_cpucfg(struct kvm_vcpu *vcpu, larch_inst inst)
|
||||
vcpu->arch.gprs[rd] = *(unsigned int *)KVM_SIGNATURE;
|
||||
break;
|
||||
case CPUCFG_KVM_FEATURE:
|
||||
ret = KVM_FEATURE_IPI;
|
||||
if (kvm_pvtime_supported())
|
||||
ret |= KVM_FEATURE_STEAL_TIME;
|
||||
ret = vcpu->kvm->arch.pv_features & LOONGARCH_PV_FEAT_MASK;
|
||||
vcpu->arch.gprs[rd] = ret;
|
||||
break;
|
||||
default:
|
||||
@ -127,6 +125,14 @@ static int kvm_handle_csr(struct kvm_vcpu *vcpu, larch_inst inst)
|
||||
rj = inst.reg2csr_format.rj;
|
||||
csrid = inst.reg2csr_format.csr;
|
||||
|
||||
if (csrid >= LOONGARCH_CSR_PERFCTRL0 && csrid <= vcpu->arch.max_pmu_csrid) {
|
||||
if (kvm_guest_has_pmu(&vcpu->arch)) {
|
||||
vcpu->arch.pc -= 4;
|
||||
kvm_make_request(KVM_REQ_PMU, vcpu);
|
||||
return EMULATE_DONE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Process CSR ops */
|
||||
switch (rj) {
|
||||
case 0: /* process csrrd */
|
||||
@ -697,25 +703,22 @@ static long kvm_save_notify(struct kvm_vcpu *vcpu)
|
||||
id = kvm_read_reg(vcpu, LOONGARCH_GPR_A1);
|
||||
data = kvm_read_reg(vcpu, LOONGARCH_GPR_A2);
|
||||
switch (id) {
|
||||
case KVM_FEATURE_STEAL_TIME:
|
||||
if (!kvm_pvtime_supported())
|
||||
return KVM_HCALL_INVALID_CODE;
|
||||
|
||||
case BIT(KVM_FEATURE_STEAL_TIME):
|
||||
if (data & ~(KVM_STEAL_PHYS_MASK | KVM_STEAL_PHYS_VALID))
|
||||
return KVM_HCALL_INVALID_PARAMETER;
|
||||
|
||||
vcpu->arch.st.guest_addr = data;
|
||||
if (!(data & KVM_STEAL_PHYS_VALID))
|
||||
break;
|
||||
return 0;
|
||||
|
||||
vcpu->arch.st.last_steal = current->sched_info.run_delay;
|
||||
kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu);
|
||||
break;
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
return KVM_HCALL_INVALID_CODE;
|
||||
};
|
||||
|
||||
return 0;
|
||||
return KVM_HCALL_INVALID_CODE;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -748,6 +751,14 @@ static int kvm_handle_lasx_disabled(struct kvm_vcpu *vcpu)
|
||||
return RESUME_GUEST;
|
||||
}
|
||||
|
||||
static int kvm_handle_lbt_disabled(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (kvm_own_lbt(vcpu))
|
||||
kvm_queue_exception(vcpu, EXCCODE_INE, 0);
|
||||
|
||||
return RESUME_GUEST;
|
||||
}
|
||||
|
||||
static int kvm_send_pv_ipi(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
unsigned int min, cpu, i;
|
||||
@ -781,19 +792,21 @@ static int kvm_send_pv_ipi(struct kvm_vcpu *vcpu)
|
||||
*/
|
||||
static void kvm_handle_service(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
long ret = KVM_HCALL_INVALID_CODE;
|
||||
unsigned long func = kvm_read_reg(vcpu, LOONGARCH_GPR_A0);
|
||||
long ret;
|
||||
|
||||
switch (func) {
|
||||
case KVM_HCALL_FUNC_IPI:
|
||||
kvm_send_pv_ipi(vcpu);
|
||||
ret = KVM_HCALL_SUCCESS;
|
||||
if (kvm_guest_has_pv_feature(vcpu, KVM_FEATURE_IPI)) {
|
||||
kvm_send_pv_ipi(vcpu);
|
||||
ret = KVM_HCALL_SUCCESS;
|
||||
}
|
||||
break;
|
||||
case KVM_HCALL_FUNC_NOTIFY:
|
||||
ret = kvm_save_notify(vcpu);
|
||||
if (kvm_guest_has_pv_feature(vcpu, KVM_FEATURE_STEAL_TIME))
|
||||
ret = kvm_save_notify(vcpu);
|
||||
break;
|
||||
default:
|
||||
ret = KVM_HCALL_INVALID_CODE;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -865,6 +878,7 @@ static exit_handle_fn kvm_fault_tables[EXCCODE_INT_START] = {
|
||||
[EXCCODE_FPDIS] = kvm_handle_fpu_disabled,
|
||||
[EXCCODE_LSXDIS] = kvm_handle_lsx_disabled,
|
||||
[EXCCODE_LASXDIS] = kvm_handle_lasx_disabled,
|
||||
[EXCCODE_BTDIS] = kvm_handle_lbt_disabled,
|
||||
[EXCCODE_GSPR] = kvm_handle_gspr,
|
||||
[EXCCODE_HVC] = kvm_handle_hypercall,
|
||||
};
|
||||
|
@ -277,6 +277,10 @@ SYM_DATA(kvm_enter_guest_size, .quad kvm_enter_guest_end - kvm_enter_guest)
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_LBT
|
||||
STACK_FRAME_NON_STANDARD kvm_restore_fpu
|
||||
#ifdef CONFIG_CPU_HAS_LSX
|
||||
STACK_FRAME_NON_STANDARD kvm_restore_lsx
|
||||
#endif
|
||||
#ifdef CONFIG_CPU_HAS_LASX
|
||||
STACK_FRAME_NON_STANDARD kvm_restore_lasx
|
||||
#endif
|
||||
#endif
|
||||
|
@ -188,10 +188,3 @@ void kvm_save_timer(struct kvm_vcpu *vcpu)
|
||||
kvm_save_hw_gcsr(csr, LOONGARCH_CSR_ESTAT);
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
void kvm_reset_timer(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
write_gcsr_timercfg(0);
|
||||
kvm_write_sw_gcsr(vcpu->arch.csr, LOONGARCH_CSR_TCFG, 0);
|
||||
hrtimer_cancel(&vcpu->arch.swtimer);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <linux/kvm_host.h>
|
||||
#include <linux/entry-kvm.h>
|
||||
#include <asm/fpu.h>
|
||||
#include <asm/lbt.h>
|
||||
#include <asm/loongarch.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/time.h>
|
||||
@ -31,6 +32,126 @@ const struct kvm_stats_header kvm_vcpu_stats_header = {
|
||||
sizeof(kvm_vcpu_stats_desc),
|
||||
};
|
||||
|
||||
static inline void kvm_save_host_pmu(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm_context *context;
|
||||
|
||||
context = this_cpu_ptr(vcpu->kvm->arch.vmcs);
|
||||
context->perf_cntr[0] = read_csr_perfcntr0();
|
||||
context->perf_cntr[1] = read_csr_perfcntr1();
|
||||
context->perf_cntr[2] = read_csr_perfcntr2();
|
||||
context->perf_cntr[3] = read_csr_perfcntr3();
|
||||
context->perf_ctrl[0] = write_csr_perfctrl0(0);
|
||||
context->perf_ctrl[1] = write_csr_perfctrl1(0);
|
||||
context->perf_ctrl[2] = write_csr_perfctrl2(0);
|
||||
context->perf_ctrl[3] = write_csr_perfctrl3(0);
|
||||
}
|
||||
|
||||
static inline void kvm_restore_host_pmu(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm_context *context;
|
||||
|
||||
context = this_cpu_ptr(vcpu->kvm->arch.vmcs);
|
||||
write_csr_perfcntr0(context->perf_cntr[0]);
|
||||
write_csr_perfcntr1(context->perf_cntr[1]);
|
||||
write_csr_perfcntr2(context->perf_cntr[2]);
|
||||
write_csr_perfcntr3(context->perf_cntr[3]);
|
||||
write_csr_perfctrl0(context->perf_ctrl[0]);
|
||||
write_csr_perfctrl1(context->perf_ctrl[1]);
|
||||
write_csr_perfctrl2(context->perf_ctrl[2]);
|
||||
write_csr_perfctrl3(context->perf_ctrl[3]);
|
||||
}
|
||||
|
||||
|
||||
static inline void kvm_save_guest_pmu(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct loongarch_csrs *csr = vcpu->arch.csr;
|
||||
|
||||
kvm_save_hw_gcsr(csr, LOONGARCH_CSR_PERFCNTR0);
|
||||
kvm_save_hw_gcsr(csr, LOONGARCH_CSR_PERFCNTR1);
|
||||
kvm_save_hw_gcsr(csr, LOONGARCH_CSR_PERFCNTR2);
|
||||
kvm_save_hw_gcsr(csr, LOONGARCH_CSR_PERFCNTR3);
|
||||
kvm_read_clear_hw_gcsr(csr, LOONGARCH_CSR_PERFCTRL0);
|
||||
kvm_read_clear_hw_gcsr(csr, LOONGARCH_CSR_PERFCTRL1);
|
||||
kvm_read_clear_hw_gcsr(csr, LOONGARCH_CSR_PERFCTRL2);
|
||||
kvm_read_clear_hw_gcsr(csr, LOONGARCH_CSR_PERFCTRL3);
|
||||
}
|
||||
|
||||
static inline void kvm_restore_guest_pmu(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct loongarch_csrs *csr = vcpu->arch.csr;
|
||||
|
||||
kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_PERFCNTR0);
|
||||
kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_PERFCNTR1);
|
||||
kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_PERFCNTR2);
|
||||
kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_PERFCNTR3);
|
||||
kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_PERFCTRL0);
|
||||
kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_PERFCTRL1);
|
||||
kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_PERFCTRL2);
|
||||
kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_PERFCTRL3);
|
||||
}
|
||||
|
||||
static int kvm_own_pmu(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
unsigned long val;
|
||||
|
||||
if (!kvm_guest_has_pmu(&vcpu->arch))
|
||||
return -EINVAL;
|
||||
|
||||
kvm_save_host_pmu(vcpu);
|
||||
|
||||
/* Set PM0-PM(num) to guest */
|
||||
val = read_csr_gcfg() & ~CSR_GCFG_GPERF;
|
||||
val |= (kvm_get_pmu_num(&vcpu->arch) + 1) << CSR_GCFG_GPERF_SHIFT;
|
||||
write_csr_gcfg(val);
|
||||
|
||||
kvm_restore_guest_pmu(vcpu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void kvm_lose_pmu(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
unsigned long val;
|
||||
struct loongarch_csrs *csr = vcpu->arch.csr;
|
||||
|
||||
if (!(vcpu->arch.aux_inuse & KVM_LARCH_PMU))
|
||||
return;
|
||||
|
||||
kvm_save_guest_pmu(vcpu);
|
||||
|
||||
/* Disable pmu access from guest */
|
||||
write_csr_gcfg(read_csr_gcfg() & ~CSR_GCFG_GPERF);
|
||||
|
||||
/*
|
||||
* Clear KVM_LARCH_PMU if the guest is not using PMU CSRs when
|
||||
* exiting the guest, so that the next time trap into the guest.
|
||||
* We don't need to deal with PMU CSRs contexts.
|
||||
*/
|
||||
val = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_PERFCTRL0);
|
||||
val |= kvm_read_sw_gcsr(csr, LOONGARCH_CSR_PERFCTRL1);
|
||||
val |= kvm_read_sw_gcsr(csr, LOONGARCH_CSR_PERFCTRL2);
|
||||
val |= kvm_read_sw_gcsr(csr, LOONGARCH_CSR_PERFCTRL3);
|
||||
if (!(val & KVM_PMU_EVENT_ENABLED))
|
||||
vcpu->arch.aux_inuse &= ~KVM_LARCH_PMU;
|
||||
|
||||
kvm_restore_host_pmu(vcpu);
|
||||
}
|
||||
|
||||
static void kvm_restore_pmu(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if ((vcpu->arch.aux_inuse & KVM_LARCH_PMU))
|
||||
kvm_make_request(KVM_REQ_PMU, vcpu);
|
||||
}
|
||||
|
||||
static void kvm_check_pmu(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (kvm_check_request(KVM_REQ_PMU, vcpu)) {
|
||||
kvm_own_pmu(vcpu);
|
||||
vcpu->arch.aux_inuse |= KVM_LARCH_PMU;
|
||||
}
|
||||
}
|
||||
|
||||
static void kvm_update_stolen_time(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
u32 version;
|
||||
@ -158,6 +279,7 @@ static int kvm_pre_enter_guest(struct kvm_vcpu *vcpu)
|
||||
/* Make sure the vcpu mode has been written */
|
||||
smp_store_mb(vcpu->mode, IN_GUEST_MODE);
|
||||
kvm_check_vpid(vcpu);
|
||||
kvm_check_pmu(vcpu);
|
||||
|
||||
/*
|
||||
* Called after function kvm_check_vpid()
|
||||
@ -195,6 +317,8 @@ static int kvm_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
|
||||
/* Set a default exit reason */
|
||||
run->exit_reason = KVM_EXIT_UNKNOWN;
|
||||
|
||||
kvm_lose_pmu(vcpu);
|
||||
|
||||
guest_timing_exit_irqoff();
|
||||
guest_state_exit_irqoff();
|
||||
local_irq_enable();
|
||||
@ -468,6 +592,22 @@ static int _kvm_setcsr(struct kvm_vcpu *vcpu, unsigned int id, u64 val)
|
||||
|
||||
kvm_write_sw_gcsr(csr, id, val);
|
||||
|
||||
/*
|
||||
* After modifying the PMU CSR register value of the vcpu.
|
||||
* If the PMU CSRs are used, we need to set KVM_REQ_PMU.
|
||||
*/
|
||||
if (id >= LOONGARCH_CSR_PERFCTRL0 && id <= LOONGARCH_CSR_PERFCNTR3) {
|
||||
unsigned long val;
|
||||
|
||||
val = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_PERFCTRL0) |
|
||||
kvm_read_sw_gcsr(csr, LOONGARCH_CSR_PERFCTRL1) |
|
||||
kvm_read_sw_gcsr(csr, LOONGARCH_CSR_PERFCTRL2) |
|
||||
kvm_read_sw_gcsr(csr, LOONGARCH_CSR_PERFCTRL3);
|
||||
|
||||
if (val & KVM_PMU_EVENT_ENABLED)
|
||||
kvm_make_request(KVM_REQ_PMU, vcpu);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -497,6 +637,12 @@ static int _kvm_get_cpucfg_mask(int id, u64 *v)
|
||||
*v |= CPUCFG2_LSX;
|
||||
if (cpu_has_lasx)
|
||||
*v |= CPUCFG2_LASX;
|
||||
if (cpu_has_lbt_x86)
|
||||
*v |= CPUCFG2_X86BT;
|
||||
if (cpu_has_lbt_arm)
|
||||
*v |= CPUCFG2_ARMBT;
|
||||
if (cpu_has_lbt_mips)
|
||||
*v |= CPUCFG2_MIPSBT;
|
||||
|
||||
return 0;
|
||||
case LOONGARCH_CPUCFG3:
|
||||
@ -506,6 +652,12 @@ static int _kvm_get_cpucfg_mask(int id, u64 *v)
|
||||
case LOONGARCH_CPUCFG5:
|
||||
*v = GENMASK(31, 0);
|
||||
return 0;
|
||||
case LOONGARCH_CPUCFG6:
|
||||
if (cpu_has_pmp)
|
||||
*v = GENMASK(14, 0);
|
||||
else
|
||||
*v = 0;
|
||||
return 0;
|
||||
case LOONGARCH_CPUCFG16:
|
||||
*v = GENMASK(16, 0);
|
||||
return 0;
|
||||
@ -550,6 +702,17 @@ static int kvm_check_cpucfg(int id, u64 val)
|
||||
/* LASX architecturally implies LSX and FP but val does not satisfy that */
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
case LOONGARCH_CPUCFG6:
|
||||
if (val & CPUCFG6_PMP) {
|
||||
u32 host = read_cpucfg(LOONGARCH_CPUCFG6);
|
||||
if ((val & CPUCFG6_PMBITS) != (host & CPUCFG6_PMBITS))
|
||||
return -EINVAL;
|
||||
if ((val & CPUCFG6_PMNUM) > (host & CPUCFG6_PMNUM))
|
||||
return -EINVAL;
|
||||
if ((val & CPUCFG6_UPM) && !(host & CPUCFG6_UPM))
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
default:
|
||||
/*
|
||||
* Values for the other CPUCFG IDs are not being further validated
|
||||
@ -577,6 +740,34 @@ static int kvm_get_one_reg(struct kvm_vcpu *vcpu,
|
||||
else
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
case KVM_REG_LOONGARCH_LBT:
|
||||
if (!kvm_guest_has_lbt(&vcpu->arch))
|
||||
return -ENXIO;
|
||||
|
||||
switch (reg->id) {
|
||||
case KVM_REG_LOONGARCH_LBT_SCR0:
|
||||
*v = vcpu->arch.lbt.scr0;
|
||||
break;
|
||||
case KVM_REG_LOONGARCH_LBT_SCR1:
|
||||
*v = vcpu->arch.lbt.scr1;
|
||||
break;
|
||||
case KVM_REG_LOONGARCH_LBT_SCR2:
|
||||
*v = vcpu->arch.lbt.scr2;
|
||||
break;
|
||||
case KVM_REG_LOONGARCH_LBT_SCR3:
|
||||
*v = vcpu->arch.lbt.scr3;
|
||||
break;
|
||||
case KVM_REG_LOONGARCH_LBT_EFLAGS:
|
||||
*v = vcpu->arch.lbt.eflags;
|
||||
break;
|
||||
case KVM_REG_LOONGARCH_LBT_FTOP:
|
||||
*v = vcpu->arch.fpu.ftop;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case KVM_REG_LOONGARCH_KVM:
|
||||
switch (reg->id) {
|
||||
case KVM_REG_LOONGARCH_COUNTER:
|
||||
@ -635,6 +826,37 @@ static int kvm_set_one_reg(struct kvm_vcpu *vcpu,
|
||||
if (ret)
|
||||
break;
|
||||
vcpu->arch.cpucfg[id] = (u32)v;
|
||||
if (id == LOONGARCH_CPUCFG6)
|
||||
vcpu->arch.max_pmu_csrid =
|
||||
LOONGARCH_CSR_PERFCTRL0 + 2 * kvm_get_pmu_num(&vcpu->arch) + 1;
|
||||
break;
|
||||
case KVM_REG_LOONGARCH_LBT:
|
||||
if (!kvm_guest_has_lbt(&vcpu->arch))
|
||||
return -ENXIO;
|
||||
|
||||
switch (reg->id) {
|
||||
case KVM_REG_LOONGARCH_LBT_SCR0:
|
||||
vcpu->arch.lbt.scr0 = v;
|
||||
break;
|
||||
case KVM_REG_LOONGARCH_LBT_SCR1:
|
||||
vcpu->arch.lbt.scr1 = v;
|
||||
break;
|
||||
case KVM_REG_LOONGARCH_LBT_SCR2:
|
||||
vcpu->arch.lbt.scr2 = v;
|
||||
break;
|
||||
case KVM_REG_LOONGARCH_LBT_SCR3:
|
||||
vcpu->arch.lbt.scr3 = v;
|
||||
break;
|
||||
case KVM_REG_LOONGARCH_LBT_EFLAGS:
|
||||
vcpu->arch.lbt.eflags = v;
|
||||
break;
|
||||
case KVM_REG_LOONGARCH_LBT_FTOP:
|
||||
vcpu->arch.fpu.ftop = v;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case KVM_REG_LOONGARCH_KVM:
|
||||
switch (reg->id) {
|
||||
@ -647,7 +869,7 @@ static int kvm_set_one_reg(struct kvm_vcpu *vcpu,
|
||||
vcpu->kvm->arch.time_offset = (signed long)(v - drdtime());
|
||||
break;
|
||||
case KVM_REG_LOONGARCH_VCPU_RESET:
|
||||
kvm_reset_timer(vcpu);
|
||||
vcpu->arch.st.guest_addr = 0;
|
||||
memset(&vcpu->arch.irq_pending, 0, sizeof(vcpu->arch.irq_pending));
|
||||
memset(&vcpu->arch.irq_clear, 0, sizeof(vcpu->arch.irq_clear));
|
||||
break;
|
||||
@ -728,7 +950,10 @@ static int kvm_loongarch_cpucfg_has_attr(struct kvm_vcpu *vcpu,
|
||||
struct kvm_device_attr *attr)
|
||||
{
|
||||
switch (attr->attr) {
|
||||
case 2:
|
||||
case LOONGARCH_CPUCFG2:
|
||||
case LOONGARCH_CPUCFG6:
|
||||
return 0;
|
||||
case CPUCFG_KVM_FEATURE:
|
||||
return 0;
|
||||
default:
|
||||
return -ENXIO;
|
||||
@ -740,8 +965,8 @@ static int kvm_loongarch_cpucfg_has_attr(struct kvm_vcpu *vcpu,
|
||||
static int kvm_loongarch_pvtime_has_attr(struct kvm_vcpu *vcpu,
|
||||
struct kvm_device_attr *attr)
|
||||
{
|
||||
if (!kvm_pvtime_supported() ||
|
||||
attr->attr != KVM_LOONGARCH_VCPU_PVTIME_GPA)
|
||||
if (!kvm_guest_has_pv_feature(vcpu, KVM_FEATURE_STEAL_TIME)
|
||||
|| attr->attr != KVM_LOONGARCH_VCPU_PVTIME_GPA)
|
||||
return -ENXIO;
|
||||
|
||||
return 0;
|
||||
@ -773,9 +998,18 @@ static int kvm_loongarch_cpucfg_get_attr(struct kvm_vcpu *vcpu,
|
||||
uint64_t val;
|
||||
uint64_t __user *uaddr = (uint64_t __user *)attr->addr;
|
||||
|
||||
ret = _kvm_get_cpucfg_mask(attr->attr, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
switch (attr->attr) {
|
||||
case 0 ... (KVM_MAX_CPUCFG_REGS - 1):
|
||||
ret = _kvm_get_cpucfg_mask(attr->attr, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
case CPUCFG_KVM_FEATURE:
|
||||
val = vcpu->kvm->arch.pv_features & LOONGARCH_PV_FEAT_MASK;
|
||||
break;
|
||||
default:
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
put_user(val, uaddr);
|
||||
|
||||
@ -788,8 +1022,8 @@ static int kvm_loongarch_pvtime_get_attr(struct kvm_vcpu *vcpu,
|
||||
u64 gpa;
|
||||
u64 __user *user = (u64 __user *)attr->addr;
|
||||
|
||||
if (!kvm_pvtime_supported() ||
|
||||
attr->attr != KVM_LOONGARCH_VCPU_PVTIME_GPA)
|
||||
if (!kvm_guest_has_pv_feature(vcpu, KVM_FEATURE_STEAL_TIME)
|
||||
|| attr->attr != KVM_LOONGARCH_VCPU_PVTIME_GPA)
|
||||
return -ENXIO;
|
||||
|
||||
gpa = vcpu->arch.st.guest_addr;
|
||||
@ -821,7 +1055,28 @@ static int kvm_loongarch_vcpu_get_attr(struct kvm_vcpu *vcpu,
|
||||
static int kvm_loongarch_cpucfg_set_attr(struct kvm_vcpu *vcpu,
|
||||
struct kvm_device_attr *attr)
|
||||
{
|
||||
return -ENXIO;
|
||||
u64 val, valid;
|
||||
u64 __user *user = (u64 __user *)attr->addr;
|
||||
struct kvm *kvm = vcpu->kvm;
|
||||
|
||||
switch (attr->attr) {
|
||||
case CPUCFG_KVM_FEATURE:
|
||||
if (get_user(val, user))
|
||||
return -EFAULT;
|
||||
|
||||
valid = LOONGARCH_PV_FEAT_MASK;
|
||||
if (val & ~valid)
|
||||
return -EINVAL;
|
||||
|
||||
/* All vCPUs need set the same PV features */
|
||||
if ((kvm->arch.pv_features & LOONGARCH_PV_FEAT_UPDATED)
|
||||
&& ((kvm->arch.pv_features & valid) != val))
|
||||
return -EINVAL;
|
||||
kvm->arch.pv_features = val | LOONGARCH_PV_FEAT_UPDATED;
|
||||
return 0;
|
||||
default:
|
||||
return -ENXIO;
|
||||
}
|
||||
}
|
||||
|
||||
static int kvm_loongarch_pvtime_set_attr(struct kvm_vcpu *vcpu,
|
||||
@ -831,8 +1086,8 @@ static int kvm_loongarch_pvtime_set_attr(struct kvm_vcpu *vcpu,
|
||||
u64 gpa, __user *user = (u64 __user *)attr->addr;
|
||||
struct kvm *kvm = vcpu->kvm;
|
||||
|
||||
if (!kvm_pvtime_supported() ||
|
||||
attr->attr != KVM_LOONGARCH_VCPU_PVTIME_GPA)
|
||||
if (!kvm_guest_has_pv_feature(vcpu, KVM_FEATURE_STEAL_TIME)
|
||||
|| attr->attr != KVM_LOONGARCH_VCPU_PVTIME_GPA)
|
||||
return -ENXIO;
|
||||
|
||||
if (get_user(gpa, user))
|
||||
@ -977,12 +1232,66 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_LBT
|
||||
int kvm_own_lbt(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (!kvm_guest_has_lbt(&vcpu->arch))
|
||||
return -EINVAL;
|
||||
|
||||
preempt_disable();
|
||||
set_csr_euen(CSR_EUEN_LBTEN);
|
||||
_restore_lbt(&vcpu->arch.lbt);
|
||||
vcpu->arch.aux_inuse |= KVM_LARCH_LBT;
|
||||
preempt_enable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void kvm_lose_lbt(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
preempt_disable();
|
||||
if (vcpu->arch.aux_inuse & KVM_LARCH_LBT) {
|
||||
_save_lbt(&vcpu->arch.lbt);
|
||||
clear_csr_euen(CSR_EUEN_LBTEN);
|
||||
vcpu->arch.aux_inuse &= ~KVM_LARCH_LBT;
|
||||
}
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
static void kvm_check_fcsr(struct kvm_vcpu *vcpu, unsigned long fcsr)
|
||||
{
|
||||
/*
|
||||
* If TM is enabled, top register save/restore will
|
||||
* cause lbt exception, here enable lbt in advance
|
||||
*/
|
||||
if (fcsr & FPU_CSR_TM)
|
||||
kvm_own_lbt(vcpu);
|
||||
}
|
||||
|
||||
static void kvm_check_fcsr_alive(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (vcpu->arch.aux_inuse & KVM_LARCH_FPU) {
|
||||
if (vcpu->arch.aux_inuse & KVM_LARCH_LBT)
|
||||
return;
|
||||
kvm_check_fcsr(vcpu, read_fcsr(LOONGARCH_FCSR0));
|
||||
}
|
||||
}
|
||||
#else
|
||||
static inline void kvm_lose_lbt(struct kvm_vcpu *vcpu) { }
|
||||
static inline void kvm_check_fcsr(struct kvm_vcpu *vcpu, unsigned long fcsr) { }
|
||||
static inline void kvm_check_fcsr_alive(struct kvm_vcpu *vcpu) { }
|
||||
#endif
|
||||
|
||||
/* Enable FPU and restore context */
|
||||
void kvm_own_fpu(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
preempt_disable();
|
||||
|
||||
/* Enable FPU */
|
||||
/*
|
||||
* Enable FPU for guest
|
||||
* Set FR and FRE according to guest context
|
||||
*/
|
||||
kvm_check_fcsr(vcpu, vcpu->arch.fpu.fcsr);
|
||||
set_csr_euen(CSR_EUEN_FPEN);
|
||||
|
||||
kvm_restore_fpu(&vcpu->arch.fpu);
|
||||
@ -1002,6 +1311,7 @@ int kvm_own_lsx(struct kvm_vcpu *vcpu)
|
||||
preempt_disable();
|
||||
|
||||
/* Enable LSX for guest */
|
||||
kvm_check_fcsr(vcpu, vcpu->arch.fpu.fcsr);
|
||||
set_csr_euen(CSR_EUEN_LSXEN | CSR_EUEN_FPEN);
|
||||
switch (vcpu->arch.aux_inuse & KVM_LARCH_FPU) {
|
||||
case KVM_LARCH_FPU:
|
||||
@ -1036,6 +1346,7 @@ int kvm_own_lasx(struct kvm_vcpu *vcpu)
|
||||
|
||||
preempt_disable();
|
||||
|
||||
kvm_check_fcsr(vcpu, vcpu->arch.fpu.fcsr);
|
||||
set_csr_euen(CSR_EUEN_FPEN | CSR_EUEN_LSXEN | CSR_EUEN_LASXEN);
|
||||
switch (vcpu->arch.aux_inuse & (KVM_LARCH_FPU | KVM_LARCH_LSX)) {
|
||||
case KVM_LARCH_LSX:
|
||||
@ -1067,6 +1378,7 @@ void kvm_lose_fpu(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
preempt_disable();
|
||||
|
||||
kvm_check_fcsr_alive(vcpu);
|
||||
if (vcpu->arch.aux_inuse & KVM_LARCH_LASX) {
|
||||
kvm_save_lasx(&vcpu->arch.fpu);
|
||||
vcpu->arch.aux_inuse &= ~(KVM_LARCH_LSX | KVM_LARCH_FPU | KVM_LARCH_LASX);
|
||||
@ -1089,6 +1401,7 @@ void kvm_lose_fpu(struct kvm_vcpu *vcpu)
|
||||
/* Disable FPU */
|
||||
clear_csr_euen(CSR_EUEN_FPEN);
|
||||
}
|
||||
kvm_lose_lbt(vcpu);
|
||||
|
||||
preempt_enable();
|
||||
}
|
||||
@ -1235,6 +1548,9 @@ static int _kvm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
|
||||
change_csr_gcfg(CSR_GCFG_MATC_MASK, CSR_GCFG_MATC_ROOT);
|
||||
kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu);
|
||||
|
||||
/* Restore hardware PMU CSRs */
|
||||
kvm_restore_pmu(vcpu);
|
||||
|
||||
/* Don't bother restoring registers multiple times unless necessary */
|
||||
if (vcpu->arch.aux_inuse & KVM_LARCH_HWCSR_USABLE)
|
||||
return 0;
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include <linux/kvm_host.h>
|
||||
#include <asm/kvm_mmu.h>
|
||||
#include <asm/kvm_vcpu.h>
|
||||
|
||||
const struct _kvm_stats_desc kvm_vm_stats_desc[] = {
|
||||
KVM_GENERIC_VM_STATS(),
|
||||
@ -39,6 +40,12 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
|
||||
spin_lock_init(&kvm->arch.phyid_map_lock);
|
||||
|
||||
kvm_init_vmcs(kvm);
|
||||
|
||||
/* Enable all PV features by default */
|
||||
kvm->arch.pv_features = BIT(KVM_FEATURE_IPI);
|
||||
if (kvm_pvtime_supported())
|
||||
kvm->arch.pv_features |= BIT(KVM_FEATURE_STEAL_TIME);
|
||||
|
||||
kvm->arch.gpa_size = BIT(cpu_vabits - 1);
|
||||
kvm->arch.root_level = CONFIG_PGTABLE_LEVELS - 1;
|
||||
kvm->arch.invalid_ptes[0] = 0;
|
||||
@ -99,7 +106,67 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
|
||||
return r;
|
||||
}
|
||||
|
||||
static int kvm_vm_feature_has_attr(struct kvm *kvm, struct kvm_device_attr *attr)
|
||||
{
|
||||
switch (attr->attr) {
|
||||
case KVM_LOONGARCH_VM_FEAT_LSX:
|
||||
if (cpu_has_lsx)
|
||||
return 0;
|
||||
return -ENXIO;
|
||||
case KVM_LOONGARCH_VM_FEAT_LASX:
|
||||
if (cpu_has_lasx)
|
||||
return 0;
|
||||
return -ENXIO;
|
||||
case KVM_LOONGARCH_VM_FEAT_X86BT:
|
||||
if (cpu_has_lbt_x86)
|
||||
return 0;
|
||||
return -ENXIO;
|
||||
case KVM_LOONGARCH_VM_FEAT_ARMBT:
|
||||
if (cpu_has_lbt_arm)
|
||||
return 0;
|
||||
return -ENXIO;
|
||||
case KVM_LOONGARCH_VM_FEAT_MIPSBT:
|
||||
if (cpu_has_lbt_mips)
|
||||
return 0;
|
||||
return -ENXIO;
|
||||
case KVM_LOONGARCH_VM_FEAT_PMU:
|
||||
if (cpu_has_pmp)
|
||||
return 0;
|
||||
return -ENXIO;
|
||||
case KVM_LOONGARCH_VM_FEAT_PV_IPI:
|
||||
return 0;
|
||||
case KVM_LOONGARCH_VM_FEAT_PV_STEALTIME:
|
||||
if (kvm_pvtime_supported())
|
||||
return 0;
|
||||
return -ENXIO;
|
||||
default:
|
||||
return -ENXIO;
|
||||
}
|
||||
}
|
||||
|
||||
static int kvm_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr)
|
||||
{
|
||||
switch (attr->group) {
|
||||
case KVM_LOONGARCH_VM_FEAT_CTRL:
|
||||
return kvm_vm_feature_has_attr(kvm, attr);
|
||||
default:
|
||||
return -ENXIO;
|
||||
}
|
||||
}
|
||||
|
||||
int kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
|
||||
{
|
||||
return -ENOIOCTLCMD;
|
||||
void __user *argp = (void __user *)arg;
|
||||
struct kvm *kvm = filp->private_data;
|
||||
struct kvm_device_attr attr;
|
||||
|
||||
switch (ioctl) {
|
||||
case KVM_HAS_DEVICE_ATTR:
|
||||
if (copy_from_user(&attr, argp, sizeof(attr)))
|
||||
return -EFAULT;
|
||||
|
||||
return kvm_vm_has_attr(kvm, &attr);
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
}
|
||||
|
@ -193,11 +193,6 @@ asmlinkage void __init mmu_init(void)
|
||||
{
|
||||
unsigned int kstart, ksize;
|
||||
|
||||
if (!memblock.reserved.cnt) {
|
||||
pr_emerg("Error memory count\n");
|
||||
machine_restart(NULL);
|
||||
}
|
||||
|
||||
if ((u32) memblock.memory.regions[0].size < 0x400000) {
|
||||
pr_emerg("Memory must be greater than 4MB\n");
|
||||
machine_restart(NULL);
|
||||
|
@ -21,9 +21,7 @@ static struct clocksource clocksource_mips = {
|
||||
.name = "MIPS",
|
||||
.read = c0_hpt_read,
|
||||
.mask = CLOCKSOURCE_MASK(32),
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS |
|
||||
CLOCK_SOURCE_MUST_VERIFY |
|
||||
CLOCK_SOURCE_VERIFY_PERCPU,
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
};
|
||||
|
||||
static u64 __maybe_unused notrace r4k_read_sched_clock(void)
|
||||
|
@ -459,7 +459,6 @@ void free_initmem(void)
|
||||
unsigned long kernel_end = (unsigned long)&_end;
|
||||
|
||||
/* Remap kernel text and data, but do not touch init section yet. */
|
||||
kernel_set_to_readonly = true;
|
||||
map_pages(init_end, __pa(init_end), kernel_end - init_end,
|
||||
PAGE_KERNEL, 0);
|
||||
|
||||
@ -493,11 +492,18 @@ void free_initmem(void)
|
||||
#ifdef CONFIG_STRICT_KERNEL_RWX
|
||||
void mark_rodata_ro(void)
|
||||
{
|
||||
/* rodata memory was already mapped with KERNEL_RO access rights by
|
||||
pagetable_init() and map_pages(). No need to do additional stuff here */
|
||||
unsigned long roai_size = __end_ro_after_init - __start_ro_after_init;
|
||||
unsigned long start = (unsigned long) &__start_rodata;
|
||||
unsigned long end = (unsigned long) &__end_rodata;
|
||||
|
||||
pr_info("Write protected read-only-after-init data: %luk\n", roai_size >> 10);
|
||||
pr_info("Write protecting the kernel read-only data: %luk\n",
|
||||
(end - start) >> 10);
|
||||
|
||||
kernel_set_to_readonly = true;
|
||||
map_pages(start, __pa(start), end - start, PAGE_KERNEL, 0);
|
||||
|
||||
/* force the kernel to see the new page table entries */
|
||||
flush_cache_all();
|
||||
flush_tlb_all();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -52,7 +52,7 @@
|
||||
#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
|
||||
|
||||
#define pgd_ERROR(e) \
|
||||
pr_err("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
|
||||
pr_err("%s:%d: bad pgd %08llx.\n", __FILE__, __LINE__, (unsigned long long)pgd_val(e))
|
||||
|
||||
/*
|
||||
* This is the bottom of the PKMAP area with HIGHMEM or an arbitrary
|
||||
@ -170,7 +170,7 @@ static inline void pmd_clear(pmd_t *pmdp)
|
||||
#define pmd_pfn(pmd) (pmd_val(pmd) >> PAGE_SHIFT)
|
||||
#else
|
||||
#define pmd_page_vaddr(pmd) \
|
||||
((const void *)(pmd_val(pmd) & ~(PTE_TABLE_SIZE - 1)))
|
||||
((const void *)((unsigned long)pmd_val(pmd) & ~(PTE_TABLE_SIZE - 1)))
|
||||
#define pmd_pfn(pmd) (__pa(pmd_val(pmd)) >> PAGE_SHIFT)
|
||||
#endif
|
||||
|
||||
|
@ -49,16 +49,22 @@ static inline unsigned long pud_val(pud_t x)
|
||||
#endif /* CONFIG_PPC64 */
|
||||
|
||||
/* PGD level */
|
||||
#if defined(CONFIG_PPC_E500) && defined(CONFIG_PTE_64BIT)
|
||||
#if defined(CONFIG_PPC_85xx) && defined(CONFIG_PTE_64BIT)
|
||||
typedef struct { unsigned long long pgd; } pgd_t;
|
||||
|
||||
static inline unsigned long long pgd_val(pgd_t x)
|
||||
{
|
||||
return x.pgd;
|
||||
}
|
||||
#else
|
||||
typedef struct { unsigned long pgd; } pgd_t;
|
||||
#endif
|
||||
#define __pgd(x) ((pgd_t) { (x) })
|
||||
|
||||
static inline unsigned long pgd_val(pgd_t x)
|
||||
{
|
||||
return x.pgd;
|
||||
}
|
||||
#endif
|
||||
#define __pgd(x) ((pgd_t) { (x) })
|
||||
|
||||
/* Page protection bits */
|
||||
typedef struct { unsigned long pgprot; } pgprot_t;
|
||||
|
@ -74,6 +74,8 @@ SECTIONS
|
||||
.got : { *(.got) } :text
|
||||
.plt : { *(.plt) }
|
||||
|
||||
.rela.dyn : { *(.rela .rela*) }
|
||||
|
||||
_end = .;
|
||||
__end = .;
|
||||
PROVIDE(end = .);
|
||||
@ -87,7 +89,7 @@ SECTIONS
|
||||
*(.branch_lt)
|
||||
*(.data .data.* .gnu.linkonce.d.* .sdata*)
|
||||
*(.bss .sbss .dynbss .dynsbss)
|
||||
*(.got1 .glink .iplt .rela*)
|
||||
*(.got1 .glink .iplt)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ SECTIONS
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
|
||||
.eh_frame : { KEEP (*(.eh_frame)) } :text
|
||||
.gcc_except_table : { *(.gcc_except_table) }
|
||||
.rela.dyn ALIGN(8) : { *(.rela.dyn) }
|
||||
.rela.dyn ALIGN(8) : { *(.rela .rela*) }
|
||||
|
||||
.got ALIGN(8) : { *(.got .toc) }
|
||||
|
||||
@ -86,7 +86,7 @@ SECTIONS
|
||||
*(.data .data.* .gnu.linkonce.d.* .sdata*)
|
||||
*(.bss .sbss .dynbss .dynsbss)
|
||||
*(.opd)
|
||||
*(.glink .iplt .plt .rela*)
|
||||
*(.glink .iplt .plt)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -697,7 +697,15 @@ again:
|
||||
}
|
||||
|
||||
release:
|
||||
qnodesp->count--; /* release the node */
|
||||
/*
|
||||
* Clear the lock before releasing the node, as another CPU might see stale
|
||||
* values if an interrupt occurs after we increment qnodesp->count
|
||||
* but before node->lock is initialized. The barrier ensures that
|
||||
* there are no further stores to the node after it has been released.
|
||||
*/
|
||||
node->lock = NULL;
|
||||
barrier();
|
||||
qnodesp->count--;
|
||||
}
|
||||
|
||||
void queued_spin_lock_slowpath(struct qspinlock *lock)
|
||||
|
@ -33,7 +33,7 @@
|
||||
* though this will probably be made common with other nohash
|
||||
* implementations at some point
|
||||
*/
|
||||
int mmu_pte_psize; /* Page size used for PTE pages */
|
||||
static int mmu_pte_psize; /* Page size used for PTE pages */
|
||||
int mmu_vmemmap_psize; /* Page size used for the virtual mem map */
|
||||
int book3e_htw_mode; /* HW tablewalk? Value is PPC_HTW_* */
|
||||
unsigned long linear_map_top; /* Top of linear mapping */
|
||||
|
@ -552,8 +552,8 @@ config RISCV_ISA_SVPBMT
|
||||
config TOOLCHAIN_HAS_V
|
||||
bool
|
||||
default y
|
||||
depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64iv)
|
||||
depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32iv)
|
||||
depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64imv)
|
||||
depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32imv)
|
||||
depends on LLD_VERSION >= 140000 || LD_VERSION >= 23800
|
||||
depends on AS_HAS_OPTION_ARCH
|
||||
|
||||
|
@ -14,36 +14,14 @@
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
/*
|
||||
* addr is a hint to the maximum userspace address that mmap should provide, so
|
||||
* this macro needs to return the largest address space available so that
|
||||
* mmap_end < addr, being mmap_end the top of that address space.
|
||||
* See Documentation/arch/riscv/vm-layout.rst for more details.
|
||||
*/
|
||||
#define arch_get_mmap_end(addr, len, flags) \
|
||||
({ \
|
||||
unsigned long mmap_end; \
|
||||
typeof(addr) _addr = (addr); \
|
||||
if ((_addr) == 0 || is_compat_task() || \
|
||||
((_addr + len) > BIT(VA_BITS - 1))) \
|
||||
mmap_end = STACK_TOP_MAX; \
|
||||
else \
|
||||
mmap_end = (_addr + len); \
|
||||
mmap_end; \
|
||||
STACK_TOP_MAX; \
|
||||
})
|
||||
|
||||
#define arch_get_mmap_base(addr, base) \
|
||||
({ \
|
||||
unsigned long mmap_base; \
|
||||
typeof(addr) _addr = (addr); \
|
||||
typeof(base) _base = (base); \
|
||||
unsigned long rnd_gap = DEFAULT_MAP_WINDOW - (_base); \
|
||||
if ((_addr) == 0 || is_compat_task() || \
|
||||
((_addr + len) > BIT(VA_BITS - 1))) \
|
||||
mmap_base = (_base); \
|
||||
else \
|
||||
mmap_base = (_addr + len) - rnd_gap; \
|
||||
mmap_base; \
|
||||
base; \
|
||||
})
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/jump_label.h>
|
||||
|
||||
#ifdef CONFIG_RISCV_SBI
|
||||
enum sbi_ext_id {
|
||||
@ -304,6 +305,7 @@ struct sbiret {
|
||||
};
|
||||
|
||||
void sbi_init(void);
|
||||
long __sbi_base_ecall(int fid);
|
||||
struct sbiret __sbi_ecall(unsigned long arg0, unsigned long arg1,
|
||||
unsigned long arg2, unsigned long arg3,
|
||||
unsigned long arg4, unsigned long arg5,
|
||||
@ -373,7 +375,23 @@ static inline unsigned long sbi_mk_version(unsigned long major,
|
||||
| (minor & SBI_SPEC_VERSION_MINOR_MASK);
|
||||
}
|
||||
|
||||
int sbi_err_map_linux_errno(int err);
|
||||
static inline int sbi_err_map_linux_errno(int err)
|
||||
{
|
||||
switch (err) {
|
||||
case SBI_SUCCESS:
|
||||
return 0;
|
||||
case SBI_ERR_DENIED:
|
||||
return -EPERM;
|
||||
case SBI_ERR_INVALID_PARAM:
|
||||
return -EINVAL;
|
||||
case SBI_ERR_INVALID_ADDRESS:
|
||||
return -EFAULT;
|
||||
case SBI_ERR_NOT_SUPPORTED:
|
||||
case SBI_ERR_FAILURE:
|
||||
default:
|
||||
return -ENOTSUPP;
|
||||
};
|
||||
}
|
||||
|
||||
extern bool sbi_debug_console_available;
|
||||
int sbi_debug_console_write(const char *bytes, unsigned int num_bytes);
|
||||
|
@ -20,17 +20,21 @@ endif
|
||||
ifdef CONFIG_RISCV_ALTERNATIVE_EARLY
|
||||
CFLAGS_alternative.o := -mcmodel=medany
|
||||
CFLAGS_cpufeature.o := -mcmodel=medany
|
||||
CFLAGS_sbi_ecall.o := -mcmodel=medany
|
||||
ifdef CONFIG_FTRACE
|
||||
CFLAGS_REMOVE_alternative.o = $(CC_FLAGS_FTRACE)
|
||||
CFLAGS_REMOVE_cpufeature.o = $(CC_FLAGS_FTRACE)
|
||||
CFLAGS_REMOVE_sbi_ecall.o = $(CC_FLAGS_FTRACE)
|
||||
endif
|
||||
ifdef CONFIG_RELOCATABLE
|
||||
CFLAGS_alternative.o += -fno-pie
|
||||
CFLAGS_cpufeature.o += -fno-pie
|
||||
CFLAGS_sbi_ecall.o += -fno-pie
|
||||
endif
|
||||
ifdef CONFIG_KASAN
|
||||
KASAN_SANITIZE_alternative.o := n
|
||||
KASAN_SANITIZE_cpufeature.o := n
|
||||
KASAN_SANITIZE_sbi_ecall.o := n
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -88,7 +92,7 @@ obj-$(CONFIG_DYNAMIC_FTRACE) += mcount-dyn.o
|
||||
|
||||
obj-$(CONFIG_PERF_EVENTS) += perf_callchain.o
|
||||
obj-$(CONFIG_HAVE_PERF_REGS) += perf_regs.o
|
||||
obj-$(CONFIG_RISCV_SBI) += sbi.o
|
||||
obj-$(CONFIG_RISCV_SBI) += sbi.o sbi_ecall.o
|
||||
ifeq ($(CONFIG_RISCV_SBI), y)
|
||||
obj-$(CONFIG_SMP) += sbi-ipi.o
|
||||
obj-$(CONFIG_SMP) += cpu_ops_sbi.o
|
||||
|
@ -14,9 +14,6 @@
|
||||
#include <asm/smp.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <asm/trace.h>
|
||||
|
||||
/* default SBI version is 0.1 */
|
||||
unsigned long sbi_spec_version __ro_after_init = SBI_SPEC_VERSION_DEFAULT;
|
||||
EXPORT_SYMBOL(sbi_spec_version);
|
||||
@ -27,55 +24,6 @@ static int (*__sbi_rfence)(int fid, const struct cpumask *cpu_mask,
|
||||
unsigned long start, unsigned long size,
|
||||
unsigned long arg4, unsigned long arg5) __ro_after_init;
|
||||
|
||||
struct sbiret __sbi_ecall(unsigned long arg0, unsigned long arg1,
|
||||
unsigned long arg2, unsigned long arg3,
|
||||
unsigned long arg4, unsigned long arg5,
|
||||
int fid, int ext)
|
||||
{
|
||||
struct sbiret ret;
|
||||
|
||||
trace_sbi_call(ext, fid);
|
||||
|
||||
register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0);
|
||||
register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1);
|
||||
register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2);
|
||||
register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3);
|
||||
register uintptr_t a4 asm ("a4") = (uintptr_t)(arg4);
|
||||
register uintptr_t a5 asm ("a5") = (uintptr_t)(arg5);
|
||||
register uintptr_t a6 asm ("a6") = (uintptr_t)(fid);
|
||||
register uintptr_t a7 asm ("a7") = (uintptr_t)(ext);
|
||||
asm volatile ("ecall"
|
||||
: "+r" (a0), "+r" (a1)
|
||||
: "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7)
|
||||
: "memory");
|
||||
ret.error = a0;
|
||||
ret.value = a1;
|
||||
|
||||
trace_sbi_return(ext, ret.error, ret.value);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(__sbi_ecall);
|
||||
|
||||
int sbi_err_map_linux_errno(int err)
|
||||
{
|
||||
switch (err) {
|
||||
case SBI_SUCCESS:
|
||||
return 0;
|
||||
case SBI_ERR_DENIED:
|
||||
return -EPERM;
|
||||
case SBI_ERR_INVALID_PARAM:
|
||||
return -EINVAL;
|
||||
case SBI_ERR_INVALID_ADDRESS:
|
||||
return -EFAULT;
|
||||
case SBI_ERR_NOT_SUPPORTED:
|
||||
case SBI_ERR_FAILURE:
|
||||
default:
|
||||
return -ENOTSUPP;
|
||||
};
|
||||
}
|
||||
EXPORT_SYMBOL(sbi_err_map_linux_errno);
|
||||
|
||||
#ifdef CONFIG_RISCV_SBI_V01
|
||||
static unsigned long __sbi_v01_cpumask_to_hartmask(const struct cpumask *cpu_mask)
|
||||
{
|
||||
@ -535,17 +483,6 @@ long sbi_probe_extension(int extid)
|
||||
}
|
||||
EXPORT_SYMBOL(sbi_probe_extension);
|
||||
|
||||
static long __sbi_base_ecall(int fid)
|
||||
{
|
||||
struct sbiret ret;
|
||||
|
||||
ret = sbi_ecall(SBI_EXT_BASE, fid, 0, 0, 0, 0, 0, 0);
|
||||
if (!ret.error)
|
||||
return ret.value;
|
||||
else
|
||||
return sbi_err_map_linux_errno(ret.error);
|
||||
}
|
||||
|
||||
static inline long sbi_get_spec_version(void)
|
||||
{
|
||||
return __sbi_base_ecall(SBI_EXT_BASE_GET_SPEC_VERSION);
|
||||
|
48
arch/riscv/kernel/sbi_ecall.c
Normal file
48
arch/riscv/kernel/sbi_ecall.c
Normal file
@ -0,0 +1,48 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2024 Rivos Inc. */
|
||||
|
||||
#include <asm/sbi.h>
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <asm/trace.h>
|
||||
|
||||
long __sbi_base_ecall(int fid)
|
||||
{
|
||||
struct sbiret ret;
|
||||
|
||||
ret = sbi_ecall(SBI_EXT_BASE, fid, 0, 0, 0, 0, 0, 0);
|
||||
if (!ret.error)
|
||||
return ret.value;
|
||||
else
|
||||
return sbi_err_map_linux_errno(ret.error);
|
||||
}
|
||||
EXPORT_SYMBOL(__sbi_base_ecall);
|
||||
|
||||
struct sbiret __sbi_ecall(unsigned long arg0, unsigned long arg1,
|
||||
unsigned long arg2, unsigned long arg3,
|
||||
unsigned long arg4, unsigned long arg5,
|
||||
int fid, int ext)
|
||||
{
|
||||
struct sbiret ret;
|
||||
|
||||
trace_sbi_call(ext, fid);
|
||||
|
||||
register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0);
|
||||
register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1);
|
||||
register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2);
|
||||
register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3);
|
||||
register uintptr_t a4 asm ("a4") = (uintptr_t)(arg4);
|
||||
register uintptr_t a5 asm ("a5") = (uintptr_t)(arg5);
|
||||
register uintptr_t a6 asm ("a6") = (uintptr_t)(fid);
|
||||
register uintptr_t a7 asm ("a7") = (uintptr_t)(ext);
|
||||
asm volatile ("ecall"
|
||||
: "+r" (a0), "+r" (a1)
|
||||
: "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7)
|
||||
: "memory");
|
||||
ret.error = a0;
|
||||
ret.value = a1;
|
||||
|
||||
trace_sbi_return(ext, ret.error, ret.value);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(__sbi_ecall);
|
@ -417,7 +417,7 @@ int handle_misaligned_load(struct pt_regs *regs)
|
||||
|
||||
val.data_u64 = 0;
|
||||
if (user_mode(regs)) {
|
||||
if (raw_copy_from_user(&val, (u8 __user *)addr, len))
|
||||
if (copy_from_user(&val, (u8 __user *)addr, len))
|
||||
return -1;
|
||||
} else {
|
||||
memcpy(&val, (u8 *)addr, len);
|
||||
@ -515,7 +515,7 @@ int handle_misaligned_store(struct pt_regs *regs)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (user_mode(regs)) {
|
||||
if (raw_copy_to_user((u8 __user *)addr, &val, len))
|
||||
if (copy_to_user((u8 __user *)addr, &val, len))
|
||||
return -1;
|
||||
} else {
|
||||
memcpy((u8 *)addr, &val, len);
|
||||
|
@ -252,7 +252,7 @@ static void __init setup_bootmem(void)
|
||||
* The size of the linear page mapping may restrict the amount of
|
||||
* usable RAM.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_64BIT)) {
|
||||
if (IS_ENABLED(CONFIG_64BIT) && IS_ENABLED(CONFIG_MMU)) {
|
||||
max_mapped_addr = __pa(PAGE_OFFSET) + KERN_VIRT_SIZE;
|
||||
memblock_cap_memory_range(phys_ram_base,
|
||||
max_mapped_addr - phys_ram_base);
|
||||
|
@ -389,7 +389,6 @@ static bool mmio_read(int size, unsigned long addr, unsigned long *val)
|
||||
.r12 = size,
|
||||
.r13 = EPT_READ,
|
||||
.r14 = addr,
|
||||
.r15 = *val,
|
||||
};
|
||||
|
||||
if (__tdx_hypercall(&args))
|
||||
|
@ -4589,6 +4589,25 @@ static enum hybrid_cpu_type adl_get_hybrid_cpu_type(void)
|
||||
return HYBRID_INTEL_CORE;
|
||||
}
|
||||
|
||||
static inline bool erratum_hsw11(struct perf_event *event)
|
||||
{
|
||||
return (event->hw.config & INTEL_ARCH_EVENT_MASK) ==
|
||||
X86_CONFIG(.event=0xc0, .umask=0x01);
|
||||
}
|
||||
|
||||
/*
|
||||
* The HSW11 requires a period larger than 100 which is the same as the BDM11.
|
||||
* A minimum period of 128 is enforced as well for the INST_RETIRED.ALL.
|
||||
*
|
||||
* The message 'interrupt took too long' can be observed on any counter which
|
||||
* was armed with a period < 32 and two events expired in the same NMI.
|
||||
* A minimum period of 32 is enforced for the rest of the events.
|
||||
*/
|
||||
static void hsw_limit_period(struct perf_event *event, s64 *left)
|
||||
{
|
||||
*left = max(*left, erratum_hsw11(event) ? 128 : 32);
|
||||
}
|
||||
|
||||
/*
|
||||
* Broadwell:
|
||||
*
|
||||
@ -4606,8 +4625,7 @@ static enum hybrid_cpu_type adl_get_hybrid_cpu_type(void)
|
||||
*/
|
||||
static void bdw_limit_period(struct perf_event *event, s64 *left)
|
||||
{
|
||||
if ((event->hw.config & INTEL_ARCH_EVENT_MASK) ==
|
||||
X86_CONFIG(.event=0xc0, .umask=0x01)) {
|
||||
if (erratum_hsw11(event)) {
|
||||
if (*left < 128)
|
||||
*left = 128;
|
||||
*left &= ~0x3fULL;
|
||||
@ -6766,6 +6784,7 @@ __init int intel_pmu_init(void)
|
||||
|
||||
x86_pmu.hw_config = hsw_hw_config;
|
||||
x86_pmu.get_event_constraints = hsw_get_event_constraints;
|
||||
x86_pmu.limit_period = hsw_limit_period;
|
||||
x86_pmu.lbr_double_abort = true;
|
||||
extra_attr = boot_cpu_has(X86_FEATURE_RTM) ?
|
||||
hsw_format_attr : nhm_format_attr;
|
||||
|
@ -591,6 +591,13 @@ struct fpu_state_config {
|
||||
* even without XSAVE support, i.e. legacy features FP + SSE
|
||||
*/
|
||||
u64 legacy_features;
|
||||
/*
|
||||
* @independent_features:
|
||||
*
|
||||
* Features that are supported by XSAVES, but not managed as part of
|
||||
* the FPU core, such as LBR
|
||||
*/
|
||||
u64 independent_features;
|
||||
};
|
||||
|
||||
/* FPU state configuration information */
|
||||
|
@ -17,6 +17,7 @@ extern unsigned long phys_base;
|
||||
extern unsigned long page_offset_base;
|
||||
extern unsigned long vmalloc_base;
|
||||
extern unsigned long vmemmap_base;
|
||||
extern unsigned long physmem_end;
|
||||
|
||||
static __always_inline unsigned long __phys_addr_nodebug(unsigned long x)
|
||||
{
|
||||
|
@ -140,6 +140,10 @@ extern unsigned int ptrs_per_p4d;
|
||||
# define VMEMMAP_START __VMEMMAP_BASE_L4
|
||||
#endif /* CONFIG_DYNAMIC_MEMORY_LAYOUT */
|
||||
|
||||
#ifdef CONFIG_RANDOMIZE_MEMORY
|
||||
# define PHYSMEM_END physmem_end
|
||||
#endif
|
||||
|
||||
/*
|
||||
* End of the region for which vmalloc page tables are pre-allocated.
|
||||
* For non-KMSAN builds, this is the same as VMALLOC_END.
|
||||
|
@ -156,12 +156,6 @@ static inline void resctrl_sched_in(struct task_struct *tsk)
|
||||
__resctrl_sched_in(tsk);
|
||||
}
|
||||
|
||||
static inline u32 resctrl_arch_system_num_rmid_idx(void)
|
||||
{
|
||||
/* RMID are independent numbers for x86. num_rmid_idx == num_rmid */
|
||||
return boot_cpu_data.x86_cache_max_rmid + 1;
|
||||
}
|
||||
|
||||
static inline void resctrl_arch_rmid_idx_decode(u32 idx, u32 *closid, u32 *rmid)
|
||||
{
|
||||
*rmid = idx;
|
||||
|
@ -1775,12 +1775,9 @@ static __init void apic_set_fixmap(bool read_apic);
|
||||
|
||||
static __init void x2apic_disable(void)
|
||||
{
|
||||
u32 x2apic_id, state = x2apic_state;
|
||||
u32 x2apic_id;
|
||||
|
||||
x2apic_mode = 0;
|
||||
x2apic_state = X2APIC_DISABLED;
|
||||
|
||||
if (state != X2APIC_ON)
|
||||
if (x2apic_state < X2APIC_ON)
|
||||
return;
|
||||
|
||||
x2apic_id = read_apic_id();
|
||||
@ -1793,6 +1790,10 @@ static __init void x2apic_disable(void)
|
||||
}
|
||||
|
||||
__x2apic_disable();
|
||||
|
||||
x2apic_mode = 0;
|
||||
x2apic_state = X2APIC_DISABLED;
|
||||
|
||||
/*
|
||||
* Don't reread the APIC ID as it was already done from
|
||||
* check_x2apic() and the APIC driver still is a x2APIC variant,
|
||||
|
@ -119,6 +119,14 @@ struct rdt_hw_resource rdt_resources_all[] = {
|
||||
},
|
||||
};
|
||||
|
||||
u32 resctrl_arch_system_num_rmid_idx(void)
|
||||
{
|
||||
struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
|
||||
|
||||
/* RMID are independent numbers for x86. num_rmid_idx == num_rmid */
|
||||
return r->num_rmid;
|
||||
}
|
||||
|
||||
/*
|
||||
* cache_alloc_hsw_probe() - Have to probe for Intel haswell server CPUs
|
||||
* as they do not have CPUID enumeration support for Cache allocation.
|
||||
|
@ -788,6 +788,9 @@ void __init fpu__init_system_xstate(unsigned int legacy_size)
|
||||
goto out_disable;
|
||||
}
|
||||
|
||||
fpu_kernel_cfg.independent_features = fpu_kernel_cfg.max_features &
|
||||
XFEATURE_MASK_INDEPENDENT;
|
||||
|
||||
/*
|
||||
* Clear XSAVE features that are disabled in the normal CPUID.
|
||||
*/
|
||||
|
@ -62,9 +62,9 @@ static inline u64 xfeatures_mask_supervisor(void)
|
||||
static inline u64 xfeatures_mask_independent(void)
|
||||
{
|
||||
if (!cpu_feature_enabled(X86_FEATURE_ARCH_LBR))
|
||||
return XFEATURE_MASK_INDEPENDENT & ~XFEATURE_MASK_LBR;
|
||||
return fpu_kernel_cfg.independent_features & ~XFEATURE_MASK_LBR;
|
||||
|
||||
return XFEATURE_MASK_INDEPENDENT;
|
||||
return fpu_kernel_cfg.independent_features;
|
||||
}
|
||||
|
||||
/* XSAVE/XRSTOR wrapper functions */
|
||||
|
@ -19,7 +19,6 @@ if VIRTUALIZATION
|
||||
|
||||
config KVM
|
||||
tristate "Kernel-based Virtual Machine (KVM) support"
|
||||
depends on HIGH_RES_TIMERS
|
||||
depends on X86_LOCAL_APIC
|
||||
select KVM_COMMON
|
||||
select KVM_GENERIC_MMU_NOTIFIER
|
||||
@ -144,8 +143,10 @@ config KVM_AMD_SEV
|
||||
select HAVE_KVM_ARCH_GMEM_PREPARE
|
||||
select HAVE_KVM_ARCH_GMEM_INVALIDATE
|
||||
help
|
||||
Provides support for launching Encrypted VMs (SEV) and Encrypted VMs
|
||||
with Encrypted State (SEV-ES) on AMD processors.
|
||||
Provides support for launching encrypted VMs which use Secure
|
||||
Encrypted Virtualization (SEV), Secure Encrypted Virtualization with
|
||||
Encrypted State (SEV-ES), and Secure Encrypted Virtualization with
|
||||
Secure Nested Paging (SEV-SNP) technologies on AMD processors.
|
||||
|
||||
config KVM_SMM
|
||||
bool "System Management Mode emulation"
|
||||
|
@ -4750,7 +4750,9 @@ long kvm_arch_vcpu_pre_fault_memory(struct kvm_vcpu *vcpu,
|
||||
* reload is efficient when called repeatedly, so we can do it on
|
||||
* every iteration.
|
||||
*/
|
||||
kvm_mmu_reload(vcpu);
|
||||
r = kvm_mmu_reload(vcpu);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (kvm_arch_has_private_mem(vcpu->kvm) &&
|
||||
kvm_mem_is_private(vcpu->kvm, gpa_to_gfn(range->gpa)))
|
||||
|
@ -391,9 +391,9 @@ void kvm_mmu_set_mmio_spte_mask(u64 mmio_value, u64 mmio_mask, u64 access_mask)
|
||||
mmio_value = 0;
|
||||
|
||||
/*
|
||||
* The masked MMIO value must obviously match itself and a removed SPTE
|
||||
* must not get a false positive. Removed SPTEs and MMIO SPTEs should
|
||||
* never collide as MMIO must set some RWX bits, and removed SPTEs must
|
||||
* The masked MMIO value must obviously match itself and a frozen SPTE
|
||||
* must not get a false positive. Frozen SPTEs and MMIO SPTEs should
|
||||
* never collide as MMIO must set some RWX bits, and frozen SPTEs must
|
||||
* not set any RWX bits.
|
||||
*/
|
||||
if (WARN_ON((mmio_value & mmio_mask) != mmio_value) ||
|
||||
|
@ -214,7 +214,7 @@ extern u64 __read_mostly shadow_nonpresent_or_rsvd_mask;
|
||||
*/
|
||||
#define FROZEN_SPTE (SHADOW_NONPRESENT_VALUE | 0x5a0ULL)
|
||||
|
||||
/* Removed SPTEs must not be misconstrued as shadow present PTEs. */
|
||||
/* Frozen SPTEs must not be misconstrued as shadow present PTEs. */
|
||||
static_assert(!(FROZEN_SPTE & SPTE_MMU_PRESENT_MASK));
|
||||
|
||||
static inline bool is_frozen_spte(u64 spte)
|
||||
|
@ -359,10 +359,10 @@ static void handle_removed_pt(struct kvm *kvm, tdp_ptep_t pt, bool shared)
|
||||
/*
|
||||
* Set the SPTE to a nonpresent value that other
|
||||
* threads will not overwrite. If the SPTE was
|
||||
* already marked as removed then another thread
|
||||
* already marked as frozen then another thread
|
||||
* handling a page fault could overwrite it, so
|
||||
* set the SPTE until it is set from some other
|
||||
* value to the removed SPTE value.
|
||||
* value to the frozen SPTE value.
|
||||
*/
|
||||
for (;;) {
|
||||
old_spte = kvm_tdp_mmu_write_spte_atomic(sptep, FROZEN_SPTE);
|
||||
@ -536,8 +536,8 @@ static inline int __must_check __tdp_mmu_set_spte_atomic(struct tdp_iter *iter,
|
||||
u64 *sptep = rcu_dereference(iter->sptep);
|
||||
|
||||
/*
|
||||
* The caller is responsible for ensuring the old SPTE is not a REMOVED
|
||||
* SPTE. KVM should never attempt to zap or manipulate a REMOVED SPTE,
|
||||
* The caller is responsible for ensuring the old SPTE is not a FROZEN
|
||||
* SPTE. KVM should never attempt to zap or manipulate a FROZEN SPTE,
|
||||
* and pre-checking before inserting a new SPTE is advantageous as it
|
||||
* avoids unnecessary work.
|
||||
*/
|
||||
|
@ -2876,6 +2876,12 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
|
||||
case MSR_CSTAR:
|
||||
msr_info->data = svm->vmcb01.ptr->save.cstar;
|
||||
break;
|
||||
case MSR_GS_BASE:
|
||||
msr_info->data = svm->vmcb01.ptr->save.gs.base;
|
||||
break;
|
||||
case MSR_FS_BASE:
|
||||
msr_info->data = svm->vmcb01.ptr->save.fs.base;
|
||||
break;
|
||||
case MSR_KERNEL_GS_BASE:
|
||||
msr_info->data = svm->vmcb01.ptr->save.kernel_gs_base;
|
||||
break;
|
||||
@ -3101,6 +3107,12 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
|
||||
case MSR_CSTAR:
|
||||
svm->vmcb01.ptr->save.cstar = data;
|
||||
break;
|
||||
case MSR_GS_BASE:
|
||||
svm->vmcb01.ptr->save.gs.base = data;
|
||||
break;
|
||||
case MSR_FS_BASE:
|
||||
svm->vmcb01.ptr->save.fs.base = data;
|
||||
break;
|
||||
case MSR_KERNEL_GS_BASE:
|
||||
svm->vmcb01.ptr->save.kernel_gs_base = data;
|
||||
break;
|
||||
@ -5224,6 +5236,9 @@ static __init void svm_set_cpu_caps(void)
|
||||
|
||||
/* CPUID 0x8000001F (SME/SEV features) */
|
||||
sev_set_cpu_caps();
|
||||
|
||||
/* Don't advertise Bus Lock Detect to guest if SVM support is absent */
|
||||
kvm_cpu_cap_clear(X86_FEATURE_BUS_LOCK_DETECT);
|
||||
}
|
||||
|
||||
static __init int svm_hardware_setup(void)
|
||||
|
@ -4656,7 +4656,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
|
||||
case KVM_CAP_ASYNC_PF_INT:
|
||||
case KVM_CAP_GET_TSC_KHZ:
|
||||
case KVM_CAP_KVMCLOCK_CTRL:
|
||||
case KVM_CAP_READONLY_MEM:
|
||||
case KVM_CAP_IOAPIC_POLARITY_IGNORED:
|
||||
case KVM_CAP_TSC_DEADLINE_TIMER:
|
||||
case KVM_CAP_DISABLE_QUIRKS:
|
||||
@ -4815,6 +4814,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
|
||||
case KVM_CAP_VM_TYPES:
|
||||
r = kvm_caps.supported_vm_types;
|
||||
break;
|
||||
case KVM_CAP_READONLY_MEM:
|
||||
r = kvm ? kvm_arch_has_readonly_mem(kvm) : 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -6040,7 +6042,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
|
||||
if (copy_from_user(&events, argp, sizeof(struct kvm_vcpu_events)))
|
||||
break;
|
||||
|
||||
kvm_vcpu_srcu_read_lock(vcpu);
|
||||
r = kvm_vcpu_ioctl_x86_set_vcpu_events(vcpu, &events);
|
||||
kvm_vcpu_srcu_read_unlock(vcpu);
|
||||
break;
|
||||
}
|
||||
case KVM_GET_DEBUGREGS: {
|
||||
|
@ -958,8 +958,12 @@ static void update_end_of_memory_vars(u64 start, u64 size)
|
||||
int add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages,
|
||||
struct mhp_params *params)
|
||||
{
|
||||
unsigned long end = ((start_pfn + nr_pages) << PAGE_SHIFT) - 1;
|
||||
int ret;
|
||||
|
||||
if (WARN_ON_ONCE(end > PHYSMEM_END))
|
||||
return -ERANGE;
|
||||
|
||||
ret = __add_pages(nid, start_pfn, nr_pages, params);
|
||||
WARN_ON_ONCE(ret);
|
||||
|
||||
|
@ -47,13 +47,24 @@ static const unsigned long vaddr_end = CPU_ENTRY_AREA_BASE;
|
||||
*/
|
||||
static __initdata struct kaslr_memory_region {
|
||||
unsigned long *base;
|
||||
unsigned long *end;
|
||||
unsigned long size_tb;
|
||||
} kaslr_regions[] = {
|
||||
{ &page_offset_base, 0 },
|
||||
{ &vmalloc_base, 0 },
|
||||
{ &vmemmap_base, 0 },
|
||||
{
|
||||
.base = &page_offset_base,
|
||||
.end = &physmem_end,
|
||||
},
|
||||
{
|
||||
.base = &vmalloc_base,
|
||||
},
|
||||
{
|
||||
.base = &vmemmap_base,
|
||||
},
|
||||
};
|
||||
|
||||
/* The end of the possible address space for physical memory */
|
||||
unsigned long physmem_end __ro_after_init;
|
||||
|
||||
/* Get size in bytes used by the memory region */
|
||||
static inline unsigned long get_padding(struct kaslr_memory_region *region)
|
||||
{
|
||||
@ -82,6 +93,8 @@ void __init kernel_randomize_memory(void)
|
||||
BUILD_BUG_ON(vaddr_end != CPU_ENTRY_AREA_BASE);
|
||||
BUILD_BUG_ON(vaddr_end > __START_KERNEL_map);
|
||||
|
||||
/* Preset the end of the possible address space for physical memory */
|
||||
physmem_end = ((1ULL << MAX_PHYSMEM_BITS) - 1);
|
||||
if (!kaslr_memory_enabled())
|
||||
return;
|
||||
|
||||
@ -128,11 +141,18 @@ void __init kernel_randomize_memory(void)
|
||||
vaddr += entropy;
|
||||
*kaslr_regions[i].base = vaddr;
|
||||
|
||||
/*
|
||||
* Jump the region and add a minimum padding based on
|
||||
* randomization alignment.
|
||||
*/
|
||||
/* Calculate the end of the region */
|
||||
vaddr += get_padding(&kaslr_regions[i]);
|
||||
/*
|
||||
* KASLR trims the maximum possible size of the
|
||||
* direct-map. Update the physmem_end boundary.
|
||||
* No rounding required as the region starts
|
||||
* PUD aligned and size is in units of TB.
|
||||
*/
|
||||
if (kaslr_regions[i].end)
|
||||
*kaslr_regions[i].end = __pa_nodebug(vaddr - 1);
|
||||
|
||||
/* Add a minimum padding based on randomization alignment. */
|
||||
vaddr = round_up(vaddr + 1, PUD_SIZE);
|
||||
remain_entropy -= entropy;
|
||||
}
|
||||
|
@ -167,10 +167,6 @@ int bio_integrity_add_page(struct bio *bio, struct page *page,
|
||||
struct request_queue *q = bdev_get_queue(bio->bi_bdev);
|
||||
struct bio_integrity_payload *bip = bio_integrity(bio);
|
||||
|
||||
if (((bip->bip_iter.bi_size + len) >> SECTOR_SHIFT) >
|
||||
queue_max_hw_sectors(q))
|
||||
return 0;
|
||||
|
||||
if (bip->bip_vcnt > 0) {
|
||||
struct bio_vec *bv = &bip->bip_vec[bip->bip_vcnt - 1];
|
||||
bool same_page = false;
|
||||
|
@ -174,7 +174,7 @@ static int blkdev_issue_write_zeroes(struct block_device *bdev, sector_t sector,
|
||||
* on an I/O error, in which case we'll turn any error into
|
||||
* "not supported" here.
|
||||
*/
|
||||
if (ret && !limit)
|
||||
if (ret && !bdev_write_zeroes_sectors(bdev))
|
||||
return -EOPNOTSUPP;
|
||||
return ret;
|
||||
}
|
||||
|
@ -3422,6 +3422,7 @@ static void binder_transaction(struct binder_proc *proc,
|
||||
*/
|
||||
copy_size = object_offset - user_offset;
|
||||
if (copy_size && (user_offset > object_offset ||
|
||||
object_offset > tr->data_size ||
|
||||
binder_alloc_copy_user_to_buffer(
|
||||
&target_proc->alloc,
|
||||
t->buffer, user_offset,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user