mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-06-02 13:23:37 -04:00
Merge tag 'asoc-fix-v7.1-rc5' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Fixes for v7.1 This round of fixes is mostly Sirini's Qualcomm cleanups that have been in review for a while, we also have a couple of small fixes from Cássio.
This commit is contained in:
2
.mailmap
2
.mailmap
@@ -584,6 +584,8 @@ Mayuresh Janorkar <mayur@ti.com>
|
||||
Md Sadre Alam <quic_mdalam@quicinc.com> <mdalam@codeaurora.org>
|
||||
Miaoqing Pan <quic_miaoqing@quicinc.com> <miaoqing@codeaurora.org>
|
||||
Michael Buesch <m@bues.ch>
|
||||
Michal Grzeschik <mgr@kernel.org> <m.grzeschik@pengutronix.de>
|
||||
Michal Grzeschik <mgr@kernel.org> <mgr@pengutronix.de>
|
||||
Michael Riesch <michael.riesch@collabora.com> <michael.riesch@wolfvision.net>
|
||||
Michal Simek <michal.simek@amd.com> <michal.simek@xilinx.com>
|
||||
Michel Dänzer <michel@tungstengraphics.com>
|
||||
|
||||
@@ -786,6 +786,7 @@ networking/altera_tse networking/device_drivers/ethernet/altera/altera_tse
|
||||
networking/bpf_flow_dissector bpf/prog_flow_dissector
|
||||
networking/cxacru networking/device_drivers/atm/cxacru
|
||||
networking/defza networking/device_drivers/fddi/defza
|
||||
networking/device_drivers/3com/3c509 networking/device_drivers/ethernet/3com/3c509
|
||||
networking/device_drivers/3com/vortex networking/device_drivers/ethernet/3com/vortex
|
||||
networking/device_drivers/amazon/ena networking/device_drivers/ethernet/amazon/ena
|
||||
networking/device_drivers/aquantia/atlantic networking/device_drivers/ethernet/aquantia/atlantic
|
||||
|
||||
@@ -43,6 +43,11 @@ Support for changing the platform performance mode is currently not implemented.
|
||||
Battery Charging Control
|
||||
------------------------
|
||||
|
||||
.. warning:: Some devices do not properly implement the charging threshold interface. Forcing
|
||||
the driver to enable access to said interface on such devices might damage the
|
||||
battery [1]_. Because of this the driver will not enable said feature even when
|
||||
using the ``force`` module parameter.
|
||||
|
||||
The ``uniwill-laptop`` driver supports controlling the battery charge limit. This happens over
|
||||
the standard ``charge_control_end_threshold`` power supply sysfs attribute. All values
|
||||
between 1 and 100 percent are supported.
|
||||
@@ -70,3 +75,8 @@ The ``uniwill-laptop`` driver allows to set the configurable TGP for devices wit
|
||||
allow it.
|
||||
|
||||
See Documentation/ABI/testing/sysfs-driver-uniwill-laptop for details.
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
.. [1] https://www.reddit.com/r/XMG_gg/comments/ld9yyf/battery_limit_hidden_function_discovered_on/
|
||||
|
||||
@@ -358,9 +358,9 @@ Dynamic energy performance profile
|
||||
The amd-pstate driver supports dynamically selecting the energy performance
|
||||
profile based on whether the machine is running on AC or DC power.
|
||||
|
||||
Whether this behavior is enabled by default depends on the kernel
|
||||
config option `CONFIG_X86_AMD_PSTATE_DYNAMIC_EPP`. This behavior can also be overridden
|
||||
at runtime by the sysfs file ``/sys/devices/system/cpu/cpufreq/policyX/dynamic_epp``.
|
||||
Whether this behavior is enabled by default depends on the kernel command line option
|
||||
``amd_dynamic_epp`` is set. This behavior can also be overridden
|
||||
at runtime by the sysfs file ``/sys/devices/system/cpu/amd_pstate/dynamic_epp``.
|
||||
|
||||
When set to enabled, the driver will select a different energy performance
|
||||
profile when the machine is running on battery or AC power. The driver will
|
||||
@@ -485,9 +485,8 @@ kernel parameter ``amd_prefcore=disable``.
|
||||
``amd_dynamic_epp``
|
||||
|
||||
When AMD pstate is in auto mode, dynamic EPP will control whether the kernel
|
||||
autonomously changes the EPP mode. The default is configured by
|
||||
``CONFIG_X86_AMD_PSTATE_DYNAMIC_EPP`` but can be explicitly enabled with
|
||||
``amd_dynamic_epp=enable`` or disabled with ``amd_dynamic_epp=disable``.
|
||||
autonomously changes the EPP mode. The default is disabled. It can be enabled
|
||||
with the kernel parameter ``amd_dynamic_epp=enable``.
|
||||
|
||||
User Space Interface in ``sysfs`` - General
|
||||
===========================================
|
||||
|
||||
@@ -355,11 +355,12 @@ HyperThreading (HT) in the context of Intel processors, is enabled on at least
|
||||
one core, ``intel_pstate`` assigns performance-based priorities to CPUs. Namely,
|
||||
the priority of a given CPU reflects its highest HWP performance level which
|
||||
causes the CPU scheduler to generally prefer more performant CPUs, so the less
|
||||
performant CPUs are used when the other ones are fully loaded. However, SMT
|
||||
siblings (that is, logical CPUs sharing one physical core) are treated in a
|
||||
special way such that if one of them is in use, the effective priority of the
|
||||
other ones is lowered below the priorities of the CPUs located in the other
|
||||
physical cores.
|
||||
performant CPUs are used when the other ones are fully loaded. SMT siblings
|
||||
(that is, logical CPUs sharing one physical core) are given the same priority.
|
||||
The scheduler can pull tasks from lower-priority cores and place them on any
|
||||
sibling. Since the scheduler spreads tasks among physical cores, tasks will be
|
||||
placed on the SMT siblings of physical cores only after all physical cores are
|
||||
busy.
|
||||
|
||||
This approach maximizes performance in the majority of cases, but unfortunately
|
||||
it also leads to excessive energy usage in some important scenarios, like video
|
||||
|
||||
@@ -158,13 +158,22 @@ returned.
|
||||
When a message has been received, the location and size of the data with the
|
||||
message can be determined by calling::
|
||||
|
||||
void crypto_krb5_where_is_the_data(const struct krb5_enctype *krb5,
|
||||
enum krb5_crypto_mode mode,
|
||||
size_t *_offset, size_t *_len);
|
||||
int crypto_krb5_where_is_the_data(const struct krb5_enctype *krb5,
|
||||
enum krb5_crypto_mode mode,
|
||||
size_t *_offset, size_t *_len);
|
||||
|
||||
The caller provides the offset and length of the message to the function, which
|
||||
then alters those values to indicate the region containing the data (plus any
|
||||
padding). It is up to the caller to determine how much padding there is.
|
||||
padding). It is up to the caller to determine how much padding there is. The
|
||||
function returns an error if the length is too small or if the mode is
|
||||
unsupported. An additional function::
|
||||
|
||||
int crypto_krb5_check_data_len(const struct krb5_enctype *krb5,
|
||||
enum krb5_crypto_mode mode,
|
||||
size_t len, size_t min_content);
|
||||
|
||||
is provided to just do a basic check that the decrypted/verified message would
|
||||
have a sufficient minimum payload.
|
||||
|
||||
Preparation Functions
|
||||
---------------------
|
||||
|
||||
@@ -219,6 +219,7 @@ allOf:
|
||||
- required:
|
||||
- "#sound-dai-cells"
|
||||
else:
|
||||
$ref: /schemas/sound/dai-common.yaml#
|
||||
properties:
|
||||
aux-bus: false
|
||||
required:
|
||||
@@ -243,7 +244,7 @@ allOf:
|
||||
clocks:
|
||||
minItems: 5
|
||||
maxItems: 5
|
||||
clocks-names:
|
||||
clock-names:
|
||||
minItems: 5
|
||||
maxItems: 5
|
||||
|
||||
@@ -264,7 +265,7 @@ allOf:
|
||||
clocks:
|
||||
minItems: 5
|
||||
maxItems: 6
|
||||
clocks-names:
|
||||
clock-names:
|
||||
minItems: 5
|
||||
maxItems: 6
|
||||
|
||||
@@ -277,7 +278,6 @@ allOf:
|
||||
- qcom,sc8180x-dp
|
||||
- qcom,sdm845-dp
|
||||
- qcom,sm8350-dp
|
||||
- qcom,sm8650-dp
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
@@ -286,6 +286,24 @@ allOf:
|
||||
clocks:
|
||||
minItems: 6
|
||||
maxItems: 6
|
||||
clock-names:
|
||||
minItems: 6
|
||||
maxItems: 6
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sm8650-dp
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
minItems: 5
|
||||
maxItems: 9
|
||||
clocks:
|
||||
minItems: 6
|
||||
maxItems: 6
|
||||
clocks-names:
|
||||
minItems: 6
|
||||
maxItems: 6
|
||||
@@ -306,7 +324,7 @@ allOf:
|
||||
clocks:
|
||||
minItems: 6
|
||||
maxItems: 8
|
||||
clocks-names:
|
||||
clock-names:
|
||||
minItems: 6
|
||||
maxItems: 8
|
||||
|
||||
@@ -326,7 +344,7 @@ allOf:
|
||||
clocks:
|
||||
minItems: 5
|
||||
maxItems: 6
|
||||
clocks-names:
|
||||
clock-names:
|
||||
minItems: 5
|
||||
maxItems: 6
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ examples:
|
||||
mdss_mdp: display-controller@ae01000 {
|
||||
compatible = "qcom,eliza-dpu";
|
||||
reg = <0x0ae01000 0x93000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
<0x0aeb0000 0x3000>;
|
||||
reg-names = "mdp",
|
||||
"vbif";
|
||||
|
||||
@@ -304,7 +304,7 @@ examples:
|
||||
mdss_dsi0_phy: phy@ae95000 {
|
||||
compatible = "qcom,eliza-dsi-phy-4nm", "qcom,sm8650-dsi-phy-4nm";
|
||||
reg = <0x0ae95000 0x200>,
|
||||
<0x0ae95200 0x280>,
|
||||
<0x0ae95200 0x300>,
|
||||
<0x0ae95500 0x400>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
@@ -388,7 +388,7 @@ examples:
|
||||
mdss_dsi1_phy: phy@ae97000 {
|
||||
compatible = "qcom,eliza-dsi-phy-4nm", "qcom,sm8650-dsi-phy-4nm";
|
||||
reg = <0x0ae97000 0x200>,
|
||||
<0x0ae97200 0x280>,
|
||||
<0x0ae97200 0x300>,
|
||||
<0x0ae97500 0x400>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
@@ -407,11 +407,15 @@ examples:
|
||||
|
||||
displayport-controller@af54000 {
|
||||
compatible = "qcom,eliza-dp", "qcom,sm8650-dp";
|
||||
reg = <0xaf54000 0x104>,
|
||||
<0xaf54200 0xc0>,
|
||||
<0xaf55000 0x770>,
|
||||
<0xaf56000 0x9c>,
|
||||
<0xaf57000 0x9c>;
|
||||
reg = <0x0af54000 0x200>,
|
||||
<0x0af54200 0x200>,
|
||||
<0x0af55000 0xc00>,
|
||||
<0x0af56000 0x400>,
|
||||
<0x0af57000 0x400>,
|
||||
<0x0af58000 0x400>,
|
||||
<0x0af59000 0x400>,
|
||||
<0x0af5a000 0x600>,
|
||||
<0x0af5b000 0x600>;
|
||||
|
||||
interrupts-extended = <&mdss 12>;
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ examples:
|
||||
display-controller@ae01000 {
|
||||
compatible = "qcom,sm8650-dpu";
|
||||
reg = <0x0ae01000 0x8f000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
<0x0aeb0000 0x3000>;
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&gcc_axi_clk>,
|
||||
|
||||
@@ -112,7 +112,7 @@ examples:
|
||||
display-controller@ae01000 {
|
||||
compatible = "qcom,sm8650-dpu";
|
||||
reg = <0x0ae01000 0x8f000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
<0x0aeb0000 0x3000>;
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&gcc_axi_clk>,
|
||||
|
||||
@@ -117,7 +117,7 @@ examples:
|
||||
display-controller@ae01000 {
|
||||
compatible = "qcom,sm8750-dpu";
|
||||
reg = <0x0ae01000 0x93000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
<0x0aeb0000 0x3000>;
|
||||
reg-names = "mdp",
|
||||
"vbif";
|
||||
|
||||
@@ -389,11 +389,15 @@ examples:
|
||||
|
||||
displayport-controller@af54000 {
|
||||
compatible = "qcom,sm8750-dp", "qcom,sm8650-dp";
|
||||
reg = <0xaf54000 0x104>,
|
||||
<0xaf54200 0xc0>,
|
||||
<0xaf55000 0x770>,
|
||||
<0xaf56000 0x9c>,
|
||||
<0xaf57000 0x9c>;
|
||||
reg = <0x0af54000 0x200>,
|
||||
<0x0af54200 0x200>,
|
||||
<0x0af55000 0xc00>,
|
||||
<0x0af56000 0x400>,
|
||||
<0x0af57000 0x400>,
|
||||
<0x0af58000 0x400>,
|
||||
<0x0af59000 0x400>,
|
||||
<0x0af5a000 0x600>,
|
||||
<0x0af5b000 0x600>;
|
||||
|
||||
interrupts-extended = <&mdss 12>;
|
||||
|
||||
|
||||
@@ -73,6 +73,15 @@ properties:
|
||||
HSP CSR is to control and get status of different high-speed peripherals
|
||||
(such as Ethernet, USB, SATA, etc.) via register, which can tune
|
||||
board-level's parameters of PHY, etc.
|
||||
|
||||
Additional background information about the High-Speed Subsystem
|
||||
and the HSP CSR block is available in Chapter 10 ("High-Speed Interface")
|
||||
of the EIC7700X SoC Technical Reference Manual, Part 4
|
||||
(EIC7700X_SoC_Technical_Reference_Manual_Part4.pdf). The manual is
|
||||
publicly available at
|
||||
https://github.com/eswincomputing/EIC7700X-SoC-Technical-Reference-Manual/releases
|
||||
|
||||
This reference is provided for background information only.
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
items:
|
||||
- items:
|
||||
@@ -82,6 +91,8 @@ properties:
|
||||
- description: Offset of AXI clock controller Low-Power request
|
||||
register
|
||||
- description: Offset of register controlling TX/RX clock delay
|
||||
- description: Optional offset of register controlling TXD delay
|
||||
- description: Optional offset of register controlling RXD delay
|
||||
|
||||
required:
|
||||
- compatible
|
||||
@@ -116,7 +127,7 @@ examples:
|
||||
reset-names = "stmmaceth";
|
||||
rx-internal-delay-ps = <200>;
|
||||
tx-internal-delay-ps = <200>;
|
||||
eswin,hsp-sp-csr = <&hsp_sp_csr 0x100 0x108 0x118>;
|
||||
eswin,hsp-sp-csr = <&hsp_sp_csr 0x100 0x108 0x118 0x114 0x11c>;
|
||||
snps,axi-config = <&stmmac_axi_setup>;
|
||||
snps,aal;
|
||||
snps,fixed-burst;
|
||||
|
||||
@@ -20,6 +20,9 @@ properties:
|
||||
- fsl,ls1021a-qspi
|
||||
- fsl,ls2080a-qspi
|
||||
- spacemit,k1-qspi
|
||||
- items:
|
||||
- const: spacemit,k3-qspi
|
||||
- const: spacemit,k1-qspi
|
||||
- items:
|
||||
- enum:
|
||||
- fsl,ls1043a-qspi
|
||||
|
||||
249
Documentation/networking/device_drivers/ethernet/3com/3c509.rst
Normal file
249
Documentation/networking/device_drivers/ethernet/3com/3c509.rst
Normal file
@@ -0,0 +1,249 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
=============================================================================
|
||||
Linux and the 3Com EtherLink III Series Ethercards (driver v1.18c and higher)
|
||||
=============================================================================
|
||||
|
||||
This file contains the instructions and caveats for v1.18c and higher versions
|
||||
of the 3c509 driver. You should not use the driver without reading this file.
|
||||
|
||||
release 1.0
|
||||
|
||||
28 February 2002
|
||||
|
||||
Current maintainer (corrections to):
|
||||
Maciej W. Rozycki <macro@orcam.me.uk>
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
The following are notes and information on using the 3Com EtherLink III series
|
||||
ethercards in Linux. These cards are commonly known by the most widely-used
|
||||
card's 3Com model number, 3c509. They are all 10mb/s ISA-bus cards and shouldn't
|
||||
be (but sometimes are) confused with the similarly-numbered PCI-bus "3c905"
|
||||
(aka "Vortex" or "Boomerang") series. Kernel support for the 3c509 family is
|
||||
provided by the module 3c509.c, which has code to support all of the following
|
||||
models:
|
||||
|
||||
- 3c509 (original ISA card)
|
||||
- 3c509B (later revision of the ISA card; supports full-duplex)
|
||||
- 3c589 (PCMCIA)
|
||||
- 3c589B (later revision of the 3c589; supports full-duplex)
|
||||
- 3c579 (EISA)
|
||||
|
||||
Large portions of this documentation were heavily borrowed from the guide
|
||||
written the original author of the 3c509 driver, Donald Becker. The master
|
||||
copy of that document, which contains notes on older versions of the driver,
|
||||
currently resides on Scyld web server: http://www.scyld.com/.
|
||||
|
||||
|
||||
Special Driver Features
|
||||
=======================
|
||||
|
||||
Overriding card settings
|
||||
|
||||
The driver allows boot- or load-time overriding of the card's detected IOADDR,
|
||||
IRQ, and transceiver settings, although this capability shouldn't generally be
|
||||
needed except to enable full-duplex mode (see below). An example of the syntax
|
||||
for LILO parameters for doing this::
|
||||
|
||||
ether=10,0x310,3,0x3c509,eth0
|
||||
|
||||
This configures the first found 3c509 card for IRQ 10, base I/O 0x310, and
|
||||
transceiver type 3 (10base2). The flag "0x3c509" must be set to avoid conflicts
|
||||
with other card types when overriding the I/O address. When the driver is
|
||||
loaded as a module, only the IRQ may be overridden. For example,
|
||||
setting two cards to IRQ10 and IRQ11 is done by using the irq module
|
||||
option::
|
||||
|
||||
options 3c509 irq=10,11
|
||||
|
||||
|
||||
Full-duplex mode
|
||||
================
|
||||
|
||||
The v1.18c driver added support for the 3c509B's full-duplex capabilities.
|
||||
In order to enable and successfully use full-duplex mode, three conditions
|
||||
must be met:
|
||||
|
||||
(a) You must have a Etherlink III card model whose hardware supports full-
|
||||
duplex operations. Currently, the only members of the 3c509 family that are
|
||||
positively known to support full-duplex are the 3c509B (ISA bus) and 3c589B
|
||||
(PCMCIA) cards. Cards without the "B" model designation do *not* support
|
||||
full-duplex mode; these include the original 3c509 (no "B"), the original
|
||||
3c589, the 3c529 (MCA bus), and the 3c579 (EISA bus).
|
||||
|
||||
(b) You must be using your card's 10baseT transceiver (i.e., the RJ-45
|
||||
connector), not its AUI (thick-net) or 10base2 (thin-net/coax) interfaces.
|
||||
AUI and 10base2 network cabling is physically incapable of full-duplex
|
||||
operation.
|
||||
|
||||
(c) Most importantly, your 3c509B must be connected to a link partner that is
|
||||
itself full-duplex capable. This is almost certainly one of two things: a full-
|
||||
duplex-capable Ethernet switch (*not* a hub), or a full-duplex-capable NIC on
|
||||
another system that's connected directly to the 3c509B via a crossover cable.
|
||||
|
||||
Full-duplex mode can be enabled using 'ethtool'.
|
||||
|
||||
.. warning::
|
||||
|
||||
Extremely important caution concerning full-duplex mode
|
||||
|
||||
Understand that the 3c509B's hardware's full-duplex support is much more
|
||||
limited than that provide by more modern network interface cards. Although
|
||||
at the physical layer of the network it fully supports full-duplex operation,
|
||||
the card was designed before the current Ethernet auto-negotiation (N-way)
|
||||
spec was written. This means that the 3c509B family ***cannot and will not
|
||||
auto-negotiate a full-duplex connection with its link partner under any
|
||||
circumstances, no matter how it is initialized***. If the full-duplex mode
|
||||
of the 3c509B is enabled, its link partner will very likely need to be
|
||||
independently _forced_ into full-duplex mode as well; otherwise various nasty
|
||||
failures will occur - at the very least, you'll see massive numbers of packet
|
||||
collisions. This is one of very rare circumstances where disabling auto-
|
||||
negotiation and forcing the duplex mode of a network interface card or switch
|
||||
would ever be necessary or desirable.
|
||||
|
||||
|
||||
Available Transceiver Types
|
||||
===========================
|
||||
|
||||
For versions of the driver v1.18c and above, the available transceiver types are:
|
||||
|
||||
== =========================================================================
|
||||
0 transceiver type from EEPROM config (normally 10baseT); force half-duplex
|
||||
1 AUI (thick-net / DB15 connector)
|
||||
2 (undefined)
|
||||
3 10base2 (thin-net == coax / BNC connector)
|
||||
4 10baseT (RJ-45 connector); force half-duplex mode
|
||||
8 transceiver type and duplex mode taken from card's EEPROM config settings
|
||||
12 10baseT (RJ-45 connector); force full-duplex mode
|
||||
== =========================================================================
|
||||
|
||||
Prior to driver version 1.18c, only transceiver codes 0-4 were supported. Note
|
||||
that the new transceiver codes 8 and 12 are the *only* ones that will enable
|
||||
full-duplex mode, no matter what the card's detected EEPROM settings might be.
|
||||
This insured that merely upgrading the driver from an earlier version would
|
||||
never automatically enable full-duplex mode in an existing installation;
|
||||
it must always be explicitly enabled via one of these code in order to be
|
||||
activated.
|
||||
|
||||
The transceiver type can be changed using 'ethtool'.
|
||||
|
||||
|
||||
Interpretation of error messages and common problems
|
||||
----------------------------------------------------
|
||||
|
||||
Error Messages
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
eth0: Infinite loop in interrupt, status 2011.
|
||||
These are "mostly harmless" message indicating that the driver had too much
|
||||
work during that interrupt cycle. With a status of 0x2011 you are receiving
|
||||
packets faster than they can be removed from the card. This should be rare
|
||||
or impossible in normal operation. Possible causes of this error report are:
|
||||
|
||||
- a "green" mode enabled that slows the processor down when there is no
|
||||
keyboard activity.
|
||||
|
||||
- some other device or device driver hogging the bus or disabling interrupts.
|
||||
Check /proc/interrupts for excessive interrupt counts. The timer tick
|
||||
interrupt should always be incrementing faster than the others.
|
||||
|
||||
No received packets
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If a 3c509, 3c562 or 3c589 can successfully transmit packets, but never
|
||||
receives packets (as reported by /proc/net/dev or 'ifconfig') you likely
|
||||
have an interrupt line problem. Check /proc/interrupts to verify that the
|
||||
card is actually generating interrupts. If the interrupt count is not
|
||||
increasing you likely have a physical conflict with two devices trying to
|
||||
use the same ISA IRQ line. The common conflict is with a sound card on IRQ10
|
||||
or IRQ5, and the easiest solution is to move the 3c509 to a different
|
||||
interrupt line. If the device is receiving packets but 'ping' doesn't work,
|
||||
you have a routing problem.
|
||||
|
||||
Tx Carrier Errors Reported in /proc/net/dev
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
If an EtherLink III appears to transmit packets, but the "Tx carrier errors"
|
||||
field in /proc/net/dev increments as quickly as the Tx packet count, you
|
||||
likely have an unterminated network or the incorrect media transceiver selected.
|
||||
|
||||
3c509B card is not detected on machines with an ISA PnP BIOS.
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
While the updated driver works with most PnP BIOS programs, it does not work
|
||||
with all. This can be fixed by disabling PnP support using the 3Com-supplied
|
||||
setup program.
|
||||
|
||||
3c509 card is not detected on overclocked machines
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Increase the delay time in id_read_eeprom() from the current value, 500,
|
||||
to an absurdly high value, such as 5000.
|
||||
|
||||
|
||||
Decoding Status and Error Messages
|
||||
----------------------------------
|
||||
|
||||
|
||||
The bits in the main status register are:
|
||||
|
||||
===== ======================================
|
||||
value description
|
||||
===== ======================================
|
||||
0x01 Interrupt latch
|
||||
0x02 Tx overrun, or Rx underrun
|
||||
0x04 Tx complete
|
||||
0x08 Tx FIFO room available
|
||||
0x10 A complete Rx packet has arrived
|
||||
0x20 A Rx packet has started to arrive
|
||||
0x40 The driver has requested an interrupt
|
||||
0x80 Statistics counter nearly full
|
||||
===== ======================================
|
||||
|
||||
The bits in the transmit (Tx) status word are:
|
||||
|
||||
===== ============================================
|
||||
value description
|
||||
===== ============================================
|
||||
0x02 Out-of-window collision.
|
||||
0x04 Status stack overflow (normally impossible).
|
||||
0x08 16 collisions.
|
||||
0x10 Tx underrun (not enough PCI bus bandwidth).
|
||||
0x20 Tx jabber.
|
||||
0x40 Tx interrupt requested.
|
||||
0x80 Status is valid (this should always be set).
|
||||
===== ============================================
|
||||
|
||||
|
||||
When a transmit error occurs the driver produces a status message such as::
|
||||
|
||||
eth0: Transmit error, Tx status register 82
|
||||
|
||||
The two values typically seen here are:
|
||||
|
||||
0x82
|
||||
^^^^
|
||||
|
||||
Out of window collision. This typically occurs when some other Ethernet
|
||||
host is incorrectly set to full duplex on a half duplex network.
|
||||
|
||||
0x88
|
||||
^^^^
|
||||
|
||||
16 collisions. This typically occurs when the network is exceptionally busy
|
||||
or when another host doesn't correctly back off after a collision. If this
|
||||
error is mixed with 0x82 errors it is the result of a host incorrectly set
|
||||
to full duplex (see above).
|
||||
|
||||
Both of these errors are the result of network problems that should be
|
||||
corrected. They do not represent driver malfunction.
|
||||
|
||||
|
||||
Revision history (this file)
|
||||
============================
|
||||
|
||||
28Feb02 v1.0 DR New; major portions based on Becker original 3c509 docs
|
||||
|
||||
@@ -10,6 +10,7 @@ Contents:
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
3com/3c509
|
||||
3com/vortex
|
||||
amazon/ena
|
||||
altera/altera_tse
|
||||
|
||||
18
MAINTAINERS
18
MAINTAINERS
@@ -2064,7 +2064,7 @@ F: Documentation/devicetree/bindings/display/snps,arcpgu.txt
|
||||
F: drivers/gpu/drm/tiny/arcpgu.c
|
||||
|
||||
ARCNET NETWORK LAYER
|
||||
M: Michael Grzeschik <m.grzeschik@pengutronix.de>
|
||||
M: Michael Grzeschik <mgr@kernel.org>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/arcnet/
|
||||
@@ -3367,7 +3367,9 @@ F: drivers/irqchip/irq-rda-intc.c
|
||||
F: drivers/tty/serial/rda-uart.c
|
||||
|
||||
ARM/REALTEK ARCHITECTURE
|
||||
M: Andreas Färber <afaerber@suse.de>
|
||||
M: James Tai <james.tai@realtek.com>
|
||||
M: Yu-Chun Lin <eleanor.lin@realtek.com>
|
||||
R: Andreas Färber <afaerber@suse.com>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
L: linux-realtek-soc@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
@@ -3375,6 +3377,7 @@ F: Documentation/devicetree/bindings/arm/realtek.yaml
|
||||
F: arch/arm/boot/dts/realtek/
|
||||
F: arch/arm/mach-realtek/
|
||||
F: arch/arm64/boot/dts/realtek/
|
||||
F: drivers/pinctrl/realtek/
|
||||
|
||||
ARM/RISC-V/RENESAS ARCHITECTURE
|
||||
M: Geert Uytterhoeven <geert+renesas@glider.be>
|
||||
@@ -13868,6 +13871,7 @@ M: Pratyush Yadav <pratyush@kernel.org>
|
||||
R: Dave Young <ruirui.yang@linux.dev>
|
||||
L: kexec@lists.infradead.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/liveupdate/linux.git
|
||||
F: Documentation/admin-guide/kdump/
|
||||
F: fs/proc/vmcore.c
|
||||
F: include/linux/crash_core.h
|
||||
@@ -14185,6 +14189,7 @@ M: Pasha Tatashin <pasha.tatashin@soleen.com>
|
||||
M: Pratyush Yadav <pratyush@kernel.org>
|
||||
L: kexec@lists.infradead.org
|
||||
W: http://kernel.org/pub/linux/utils/kernel/kexec/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/liveupdate/linux.git
|
||||
F: include/linux/kexec.h
|
||||
F: include/uapi/linux/kexec.h
|
||||
F: kernel/kexec*
|
||||
@@ -14901,6 +14906,7 @@ LIVE UPDATE
|
||||
M: Pasha Tatashin <pasha.tatashin@soleen.com>
|
||||
M: Mike Rapoport <rppt@kernel.org>
|
||||
M: Pratyush Yadav <pratyush@kernel.org>
|
||||
L: kexec@lists.infradead.org
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/liveupdate/linux.git
|
||||
@@ -18631,6 +18637,7 @@ F: tools/testing/selftests/net/
|
||||
X: Documentation/networking/mac80211-injection.rst
|
||||
X: Documentation/networking/mac80211_hwsim/
|
||||
X: Documentation/networking/regulatory.rst
|
||||
X: include/net/bluetooth/
|
||||
X: include/net/cfg80211.h
|
||||
X: include/net/ieee80211_radiotap.h
|
||||
X: include/net/iw_handler.h
|
||||
@@ -18940,7 +18947,8 @@ F: drivers/hid/hid-nintendo*
|
||||
|
||||
NIOS2 ARCHITECTURE
|
||||
M: Dinh Nguyen <dinguyen@kernel.org>
|
||||
S: Maintained
|
||||
M: Simon Schuster <schuster.simon@siemens-energy.com>
|
||||
S: Supported
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux.git
|
||||
F: arch/nios2/
|
||||
|
||||
@@ -20735,15 +20743,13 @@ F: Documentation/devicetree/bindings/pci/intel,keembay-pcie*
|
||||
F: drivers/pci/controller/dwc/pcie-keembay.c
|
||||
|
||||
PCIE DRIVER FOR INTEL LGM GW SOC
|
||||
M: Chuanhua Lei <lchuanhua@maxlinear.com>
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
F: Documentation/devicetree/bindings/pci/intel-gw-pcie.yaml
|
||||
F: drivers/pci/controller/dwc/pcie-intel-gw.c
|
||||
|
||||
PCIE DRIVER FOR MEDIATEK
|
||||
M: Ryder Lee <ryder.lee@mediatek.com>
|
||||
M: Jianjun Wang <jianjun.wang@mediatek.com>
|
||||
L: linux-pci@vger.kernel.org
|
||||
L: linux-mediatek@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Supported
|
||||
|
||||
2
Makefile
2
Makefile
@@ -2,7 +2,7 @@
|
||||
VERSION = 7
|
||||
PATCHLEVEL = 1
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc4
|
||||
EXTRAVERSION = -rc5
|
||||
NAME = Baby Opossum Posse
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
||||
@@ -5,4 +5,5 @@ generic-y += agp.h
|
||||
generic-y += asm-offsets.h
|
||||
generic-y += kvm_para.h
|
||||
generic-y += mcs_spinlock.h
|
||||
generic-y += ring_buffer.h
|
||||
generic-y += text-patching.h
|
||||
|
||||
@@ -5,5 +5,6 @@ generic-y += extable.h
|
||||
generic-y += kvm_para.h
|
||||
generic-y += mcs_spinlock.h
|
||||
generic-y += parport.h
|
||||
generic-y += ring_buffer.h
|
||||
generic-y += user.h
|
||||
generic-y += text-patching.h
|
||||
|
||||
@@ -34,9 +34,6 @@ flash@18000000 {
|
||||
clocks = <&mstp9_clks R7S72100_CLK_SPIBSC0>;
|
||||
power-domains = <&cpg_clocks>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
#address-cells = <1>;
|
||||
|
||||
@@ -36,8 +36,6 @@ flash@18000000 {
|
||||
power-domains = <&cpg_clocks>;
|
||||
bank-width = <4>;
|
||||
device-width = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
|
||||
@@ -37,7 +37,7 @@ b_clk: b {
|
||||
clock-div = <3>;
|
||||
};
|
||||
|
||||
bsc: bus {
|
||||
bsc: bus@0 {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
@@ -40,7 +40,7 @@ aliases {
|
||||
spi2 = &hspi2;
|
||||
};
|
||||
|
||||
lbsc: bus {
|
||||
lbsc: bus@0 {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
@@ -704,7 +704,7 @@ R8A7779_CLK_MMC1 R8A7779_CLK_MMC0
|
||||
};
|
||||
};
|
||||
|
||||
lbsc: bus {
|
||||
lbsc: bus@0 {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
@@ -86,7 +86,7 @@ extal_clk: extal {
|
||||
bootph-all;
|
||||
};
|
||||
|
||||
lbsc: bus {
|
||||
lbsc: bus@0 {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
@@ -3,6 +3,7 @@ generic-y += early_ioremap.h
|
||||
generic-y += extable.h
|
||||
generic-y += flat.h
|
||||
generic-y += parport.h
|
||||
generic-y += ring_buffer.h
|
||||
|
||||
generated-y += mach-types.h
|
||||
generated-y += unistd-nr.h
|
||||
|
||||
@@ -86,14 +86,6 @@ static u64 notrace intcp_read_sched_clock(void)
|
||||
return val;
|
||||
}
|
||||
|
||||
static void __init intcp_init_early(void)
|
||||
{
|
||||
cm_map = syscon_regmap_lookup_by_compatible("arm,core-module-integrator");
|
||||
if (IS_ERR(cm_map))
|
||||
return;
|
||||
sched_clock_register(intcp_read_sched_clock, 32, 24000000);
|
||||
}
|
||||
|
||||
static void __init intcp_init_irq_of(void)
|
||||
{
|
||||
cm_init();
|
||||
@@ -119,6 +111,10 @@ static void __init intcp_init_of(void)
|
||||
{
|
||||
struct device_node *cpcon;
|
||||
|
||||
cm_map = syscon_regmap_lookup_by_compatible("arm,core-module-integrator");
|
||||
if (!IS_ERR(cm_map))
|
||||
sched_clock_register(intcp_read_sched_clock, 32, 24000000);
|
||||
|
||||
cpcon = of_find_matching_node(NULL, intcp_syscon_match);
|
||||
if (!cpcon)
|
||||
return;
|
||||
@@ -138,7 +134,6 @@ static const char * intcp_dt_board_compat[] = {
|
||||
DT_MACHINE_START(INTEGRATOR_CP_DT, "ARM Integrator/CP (Device Tree)")
|
||||
.reserve = integrator_reserve,
|
||||
.map_io = intcp_map_io,
|
||||
.init_early = intcp_init_early,
|
||||
.init_irq = intcp_init_irq_of,
|
||||
.init_machine = intcp_init_of,
|
||||
.dt_compat = intcp_dt_board_compat,
|
||||
|
||||
@@ -27,7 +27,12 @@ &lvds1 {
|
||||
status = "okay";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
lvds1_out: endpoint {
|
||||
remote-endpoint = <&panel_in>;
|
||||
};
|
||||
|
||||
@@ -699,7 +699,7 @@ scif0: serial@c0700000 {
|
||||
"renesas,rcar-gen5-scif", "renesas,scif";
|
||||
reg = <0 0xc0700000 0 0x40>;
|
||||
interrupts = <GIC_ESPI 10 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd16>, <&scif_clk>;
|
||||
clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd4>, <&scif_clk>;
|
||||
clock-names = "fck", "brg_int", "scif_clk";
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -709,7 +709,7 @@ scif1: serial@c0704000 {
|
||||
"renesas,rcar-gen5-scif", "renesas,scif";
|
||||
reg = <0 0xc0704000 0 0x40>;
|
||||
interrupts = <GIC_ESPI 11 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd16>, <&scif_clk>;
|
||||
clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd4>, <&scif_clk>;
|
||||
clock-names = "fck", "brg_int", "scif_clk";
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -719,7 +719,7 @@ scif3: serial@c0708000 {
|
||||
"renesas,rcar-gen5-scif", "renesas,scif";
|
||||
reg = <0 0xc0708000 0 0x40>;
|
||||
interrupts = <GIC_ESPI 12 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd16>, <&scif_clk>;
|
||||
clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd4>, <&scif_clk>;
|
||||
clock-names = "fck", "brg_int", "scif_clk";
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -729,7 +729,7 @@ scif4: serial@c070c000 {
|
||||
"renesas,rcar-gen5-scif", "renesas,scif";
|
||||
reg = <0 0xc070c000 0 0x40>;
|
||||
interrupts = <GIC_ESPI 13 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd16>, <&scif_clk>;
|
||||
clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd4>, <&scif_clk>;
|
||||
clock-names = "fck", "brg_int", "scif_clk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -1327,6 +1327,7 @@ usb20phyrst: usb20phy-reset@15830000 {
|
||||
resets = <&cpg 0xaf>;
|
||||
power-domains = <&cpg>;
|
||||
#reset-cells = <0>;
|
||||
#mux-state-cells = <1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
||||
@@ -1345,6 +1345,7 @@ usb20phyrst: usb20phy-reset@15830000 {
|
||||
resets = <&cpg 0xaf>;
|
||||
power-domains = <&cpg>;
|
||||
#reset-cells = <0>;
|
||||
#mux-state-cells = <1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -1355,6 +1356,7 @@ usb21phyrst: usb21phy-reset@15840000 {
|
||||
resets = <&cpg 0xaf>;
|
||||
power-domains = <&cpg>;
|
||||
#reset-cells = <0>;
|
||||
#mux-state-cells = <1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
||||
@@ -46,7 +46,12 @@ &csi2 {
|
||||
status = "okay";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
csi2_in: endpoint {
|
||||
clock-lanes = <0>;
|
||||
data-lanes = <1 2>;
|
||||
|
||||
@@ -26,7 +26,12 @@ &du {
|
||||
status = "okay";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
du_out_rgb: endpoint {
|
||||
remote-endpoint = <&adv7513_in>;
|
||||
};
|
||||
|
||||
@@ -27,7 +27,12 @@ &lvds0 {
|
||||
status = "okay";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
lvds0_out: endpoint {
|
||||
remote-endpoint = <&panel_in>;
|
||||
};
|
||||
|
||||
@@ -409,7 +409,7 @@ __AARCH64_INSN_FUNCS(cbz, 0x7F000000, 0x34000000)
|
||||
__AARCH64_INSN_FUNCS(cbnz, 0x7F000000, 0x35000000)
|
||||
__AARCH64_INSN_FUNCS(tbz, 0x7F000000, 0x36000000)
|
||||
__AARCH64_INSN_FUNCS(tbnz, 0x7F000000, 0x37000000)
|
||||
__AARCH64_INSN_FUNCS(bcond, 0xFF000010, 0x54000000)
|
||||
__AARCH64_INSN_FUNCS(bcond, 0xFF000000, 0x54000000)
|
||||
__AARCH64_INSN_FUNCS(svc, 0xFFE0001F, 0xD4000001)
|
||||
__AARCH64_INSN_FUNCS(hvc, 0xFFE0001F, 0xD4000002)
|
||||
__AARCH64_INSN_FUNCS(smc, 0xFFE0001F, 0xD4000003)
|
||||
|
||||
@@ -33,7 +33,7 @@ struct folio *vma_alloc_zeroed_movable_folio(struct vm_area_struct *vma,
|
||||
unsigned long vaddr);
|
||||
#define vma_alloc_zeroed_movable_folio vma_alloc_zeroed_movable_folio
|
||||
|
||||
bool tag_clear_highpages(struct page *to, int numpages);
|
||||
bool tag_clear_highpages(struct page *to, int numpages, bool clear_pages);
|
||||
#define __HAVE_ARCH_TAG_CLEAR_HIGHPAGES
|
||||
|
||||
#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
|
||||
|
||||
10
arch/arm64/include/asm/ring_buffer.h
Normal file
10
arch/arm64/include/asm/ring_buffer.h
Normal file
@@ -0,0 +1,10 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
#ifndef _ASM_ARM64_RING_BUFFER_H
|
||||
#define _ASM_ARM64_RING_BUFFER_H
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
/* Flush D-cache on persistent ring buffer */
|
||||
#define arch_ring_buffer_flush_range(start, end) dcache_clean_pop(start, end)
|
||||
|
||||
#endif /* _ASM_ARM64_RING_BUFFER_H */
|
||||
@@ -53,7 +53,8 @@ static inline int tlb_get_level(struct mmu_gather *tlb)
|
||||
static inline void tlb_flush(struct mmu_gather *tlb)
|
||||
{
|
||||
struct vm_area_struct vma = TLB_FLUSH_VMA(tlb->mm, 0);
|
||||
tlbf_t flags = tlb->freed_tables ? TLBF_NONE : TLBF_NOWALKCACHE;
|
||||
tlbf_t flags = (tlb->freed_tables || tlb->unshared_tables) ?
|
||||
TLBF_NONE : TLBF_NOWALKCACHE;
|
||||
unsigned long stride = tlb_get_unmap_size(tlb);
|
||||
int tlb_level = tlb_get_level(tlb);
|
||||
|
||||
|
||||
@@ -555,8 +555,10 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
|
||||
kvm_destroy_mpidr_data(vcpu->kvm);
|
||||
|
||||
err = kvm_vgic_vcpu_init(vcpu);
|
||||
if (err)
|
||||
if (err) {
|
||||
kvm_vgic_vcpu_destroy(vcpu);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = kvm_share_hyp(vcpu, vcpu + 1);
|
||||
if (err)
|
||||
|
||||
@@ -164,13 +164,16 @@ static int hyp_trace_buffer_load(struct hyp_trace_buffer *trace_buffer,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool hyp_trace_desc_validate(struct hyp_trace_desc *desc, size_t desc_size)
|
||||
static bool hyp_trace_desc_is_valid(struct hyp_trace_desc *desc, size_t desc_size)
|
||||
{
|
||||
struct ring_buffer_desc *rb_desc;
|
||||
unsigned int cpu;
|
||||
size_t nr_bpages;
|
||||
void *desc_end;
|
||||
|
||||
if (!is_protected_kvm_enabled())
|
||||
return true;
|
||||
|
||||
/*
|
||||
* Both desc_size and bpages_backing_size are untrusted host-provided
|
||||
* values. We rely on __pkvm_host_donate_hyp() to enforce their validity.
|
||||
@@ -212,8 +215,10 @@ int __tracing_load(unsigned long desc_hva, size_t desc_size)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!hyp_trace_desc_validate(desc, desc_size))
|
||||
if (!hyp_trace_desc_is_valid(desc, desc_size)) {
|
||||
ret = -EINVAL;
|
||||
goto err_release_desc;
|
||||
}
|
||||
|
||||
hyp_spin_lock(&trace_buffer.lock);
|
||||
|
||||
|
||||
@@ -2307,6 +2307,10 @@ static int vgic_its_restore_dte(struct vgic_its *its, u32 id,
|
||||
/* dte entry is valid */
|
||||
offset = (entry & KVM_ITS_DTE_NEXT_MASK) >> KVM_ITS_DTE_NEXT_SHIFT;
|
||||
|
||||
/* Mimic the MAPD behaviour and reject invalid EID bits. */
|
||||
if (num_eventid_bits > VITS_TYPER_IDBITS)
|
||||
return -EINVAL;
|
||||
|
||||
if (!vgic_its_check_id(its, baser, id, NULL))
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@@ -1018,7 +1018,7 @@ struct folio *vma_alloc_zeroed_movable_folio(struct vm_area_struct *vma,
|
||||
return vma_alloc_folio(flags, 0, vma, vaddr);
|
||||
}
|
||||
|
||||
bool tag_clear_highpages(struct page *page, int numpages)
|
||||
bool tag_clear_highpages(struct page *page, int numpages, bool clear_pages)
|
||||
{
|
||||
/*
|
||||
* Check if MTE is supported and fall back to clear_highpage().
|
||||
@@ -1026,13 +1026,16 @@ bool tag_clear_highpages(struct page *page, int numpages)
|
||||
* post_alloc_hook() will invoke tag_clear_highpages().
|
||||
*/
|
||||
if (!system_supports_mte())
|
||||
return false;
|
||||
return clear_pages;
|
||||
|
||||
/* Newly allocated pages, shouldn't have been tagged yet */
|
||||
for (int i = 0; i < numpages; i++, page++) {
|
||||
WARN_ON_ONCE(!try_page_mte_tagging(page));
|
||||
mte_zero_clear_page_tags(page_address(page));
|
||||
if (clear_pages)
|
||||
mte_zero_clear_page_tags(page_address(page));
|
||||
else
|
||||
mte_clear_page_tags(page_address(page));
|
||||
set_page_mte_tagged(page);
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ generic-y += qrwlock.h
|
||||
generic-y += qrwlock_types.h
|
||||
generic-y += qspinlock.h
|
||||
generic-y += parport.h
|
||||
generic-y += ring_buffer.h
|
||||
generic-y += user.h
|
||||
generic-y += vmlinux.lds.h
|
||||
generic-y += text-patching.h
|
||||
|
||||
@@ -5,4 +5,5 @@ generic-y += extable.h
|
||||
generic-y += iomap.h
|
||||
generic-y += kvm_para.h
|
||||
generic-y += mcs_spinlock.h
|
||||
generic-y += ring_buffer.h
|
||||
generic-y += text-patching.h
|
||||
|
||||
@@ -10,5 +10,6 @@ generic-y += qrwlock.h
|
||||
generic-y += user.h
|
||||
generic-y += ioctl.h
|
||||
generic-y += mmzone.h
|
||||
generic-y += ring_buffer.h
|
||||
generic-y += statfs.h
|
||||
generic-y += text-patching.h
|
||||
|
||||
@@ -30,6 +30,8 @@ static inline unsigned long efi_get_kimg_min_align(void)
|
||||
return SZ_2M;
|
||||
}
|
||||
|
||||
#define EFI_KIMG_PREFERRED_ADDRESS PHYSADDR(VMLINUX_LOAD_ADDRESS)
|
||||
unsigned long efi_get_kimg_kaslr_address(void);
|
||||
|
||||
#define EFI_KIMG_PREFERRED_ADDRESS efi_get_kimg_kaslr_address()
|
||||
|
||||
#endif /* _ASM_LOONGARCH_EFI_H */
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
|
||||
#include <linux/jump_label.h>
|
||||
|
||||
DECLARE_STATIC_KEY_FALSE(virt_preempt_key);
|
||||
DECLARE_STATIC_KEY_FALSE(virt_spin_lock_key);
|
||||
DECLARE_PER_CPU(struct kvm_steal_time, steal_time);
|
||||
|
||||
int __init pv_ipi_init(void);
|
||||
int __init pv_time_init(void);
|
||||
int __init pv_spinlock_init(void);
|
||||
|
||||
@@ -3,12 +3,9 @@
|
||||
#define _ASM_LOONGARCH_QSPINLOCK_H
|
||||
|
||||
#include <asm/kvm_para.h>
|
||||
#include <linux/jump_label.h>
|
||||
#include <asm/paravirt.h>
|
||||
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
DECLARE_STATIC_KEY_FALSE(virt_preempt_key);
|
||||
DECLARE_STATIC_KEY_FALSE(virt_spin_lock_key);
|
||||
DECLARE_PER_CPU(struct kvm_steal_time, steal_time);
|
||||
|
||||
#define virt_spin_lock virt_spin_lock
|
||||
|
||||
|
||||
@@ -60,16 +60,18 @@ NOKPROBE_SYMBOL(arch_prepare_kprobe);
|
||||
/* Install breakpoint in text */
|
||||
void arch_arm_kprobe(struct kprobe *p)
|
||||
{
|
||||
*p->addr = KPROBE_BP_INSN;
|
||||
flush_insn_slot(p);
|
||||
u32 insn = KPROBE_BP_INSN;
|
||||
|
||||
larch_insn_text_copy(p->addr, &insn, LOONGARCH_INSN_SIZE);
|
||||
}
|
||||
NOKPROBE_SYMBOL(arch_arm_kprobe);
|
||||
|
||||
/* Remove breakpoint from text */
|
||||
void arch_disarm_kprobe(struct kprobe *p)
|
||||
{
|
||||
*p->addr = p->opcode;
|
||||
flush_insn_slot(p);
|
||||
u32 insn = p->opcode;
|
||||
|
||||
larch_insn_text_copy(p->addr, &insn, LOONGARCH_INSN_SIZE);
|
||||
}
|
||||
NOKPROBE_SYMBOL(arch_disarm_kprobe);
|
||||
|
||||
@@ -184,16 +186,16 @@ static bool reenter_kprobe(struct kprobe *p, struct pt_regs *regs,
|
||||
struct kprobe_ctlblk *kcb)
|
||||
{
|
||||
switch (kcb->kprobe_status) {
|
||||
case KPROBE_HIT_SS:
|
||||
case KPROBE_HIT_SSDONE:
|
||||
case KPROBE_HIT_ACTIVE:
|
||||
kprobes_inc_nmissed_count(p);
|
||||
setup_singlestep(p, regs, kcb, 1);
|
||||
break;
|
||||
case KPROBE_HIT_SS:
|
||||
case KPROBE_REENTER:
|
||||
pr_warn("Failed to recover from reentered kprobes.\n");
|
||||
dump_kprobe(p);
|
||||
WARN_ON_ONCE(1);
|
||||
BUG();
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
|
||||
@@ -134,11 +134,23 @@ early_param("nokaslr", nokaslr);
|
||||
|
||||
#define KASLR_DISABLED_MESSAGE "KASLR is disabled by %s in %s cmdline.\n"
|
||||
|
||||
/*
|
||||
* Note: strictly-defined KASLR means the kernel's final runtime address
|
||||
* has a random offset from the kernel's load address, which is implemented
|
||||
* in relocate.c; broadly-defined KALSR means the kernel's final runtime
|
||||
* address has a random offset from the kernel's link address (a.k.a.
|
||||
* VMLINUX_LOAD_ADDRESS), which also include the efistlub implementation,
|
||||
* kexec_file implementation and QEMU direct kernel boot. kaslr_disabled()
|
||||
* return true only means strictly-defined KASLR is disabled.
|
||||
*/
|
||||
static inline __init bool kaslr_disabled(void)
|
||||
{
|
||||
char *str;
|
||||
const char *builtin_cmdline = CONFIG_CMDLINE;
|
||||
|
||||
if (kaslr_offset())
|
||||
return true; /* KASLR is performed during early boot. */
|
||||
|
||||
str = strstr(builtin_cmdline, "nokaslr");
|
||||
if (str == builtin_cmdline || (str > builtin_cmdline && *(str - 1) == ' ')) {
|
||||
pr_info(KASLR_DISABLED_MESSAGE, "\'nokaslr\'", "built-in");
|
||||
@@ -210,14 +222,52 @@ static inline void __init *determine_relocation_address(void)
|
||||
return RELOCATED_KASLR(destination);
|
||||
}
|
||||
|
||||
static unsigned long __init determine_initrd_address(unsigned long *size)
|
||||
{
|
||||
unsigned long start = 0;
|
||||
unsigned long key_length;
|
||||
char *p, *endp, *key = "initrd=";
|
||||
|
||||
key_length = strlen(key);
|
||||
p = strstr(boot_command_line, key);
|
||||
|
||||
if (!p) {
|
||||
key = "initrdmem=";
|
||||
key_length = strlen(key);
|
||||
p = strstr(boot_command_line, key);
|
||||
}
|
||||
|
||||
if (p == boot_command_line || (p > boot_command_line && *(p - 1) == ' ')) {
|
||||
p += key_length;
|
||||
start = memparse(p, &endp);
|
||||
if (*endp == ',')
|
||||
*size = memparse(endp + 1, NULL);
|
||||
}
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
static inline int __init relocation_addr_valid(void *location_new)
|
||||
{
|
||||
unsigned long kernel_start, kernel_size;
|
||||
unsigned long initrd_start, initrd_size = 0;
|
||||
|
||||
if ((unsigned long)location_new & 0x00000ffff)
|
||||
return 0; /* Inappropriately aligned new location */
|
||||
|
||||
if ((unsigned long)location_new < (unsigned long)_end)
|
||||
return 0; /* New location overlaps original kernel */
|
||||
|
||||
initrd_start = determine_initrd_address(&initrd_size);
|
||||
if (initrd_start && initrd_size) {
|
||||
kernel_start = PHYSADDR(location_new);
|
||||
kernel_size = (unsigned long)_end - (unsigned long)_text;
|
||||
|
||||
if (kernel_start < (initrd_start + initrd_size) &&
|
||||
initrd_start < (kernel_start + kernel_size))
|
||||
return 0; /* initrd/initramfs overlaps kernel */
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -123,11 +123,7 @@ void arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap)
|
||||
{
|
||||
unsigned long start_pfn = start >> PAGE_SHIFT;
|
||||
unsigned long nr_pages = size >> PAGE_SHIFT;
|
||||
struct page *page = pfn_to_page(start_pfn);
|
||||
|
||||
/* With altmap the first mapped page is offset from @start */
|
||||
if (altmap)
|
||||
page += vmem_altmap_offset(altmap);
|
||||
__remove_pages(start_pfn, nr_pages, altmap);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -3,5 +3,6 @@ generated-y += syscall_table.h
|
||||
generic-y += extable.h
|
||||
generic-y += kvm_para.h
|
||||
generic-y += mcs_spinlock.h
|
||||
generic-y += ring_buffer.h
|
||||
generic-y += spinlock.h
|
||||
generic-y += text-patching.h
|
||||
|
||||
@@ -5,6 +5,7 @@ generic-y += extable.h
|
||||
generic-y += kvm_para.h
|
||||
generic-y += mcs_spinlock.h
|
||||
generic-y += parport.h
|
||||
generic-y += ring_buffer.h
|
||||
generic-y += syscalls.h
|
||||
generic-y += tlb.h
|
||||
generic-y += user.h
|
||||
|
||||
@@ -12,5 +12,6 @@ generic-y += mcs_spinlock.h
|
||||
generic-y += parport.h
|
||||
generic-y += qrwlock.h
|
||||
generic-y += qspinlock.h
|
||||
generic-y += ring_buffer.h
|
||||
generic-y += user.h
|
||||
generic-y += text-patching.h
|
||||
|
||||
@@ -5,6 +5,7 @@ generic-y += cmpxchg.h
|
||||
generic-y += extable.h
|
||||
generic-y += kvm_para.h
|
||||
generic-y += mcs_spinlock.h
|
||||
generic-y += ring_buffer.h
|
||||
generic-y += spinlock.h
|
||||
generic-y += user.h
|
||||
generic-y += text-patching.h
|
||||
|
||||
@@ -12,4 +12,6 @@
|
||||
#define __ALIGN .align 4
|
||||
#define __ALIGN_STR ".align 4"
|
||||
|
||||
#define _THIS_IP_ ({ unsigned long __ip; asm volatile("nextpc %0" : "=r" (__ip)); __ip; })
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,4 +8,5 @@ generic-y += spinlock_types.h
|
||||
generic-y += spinlock.h
|
||||
generic-y += qrwlock_types.h
|
||||
generic-y += qrwlock.h
|
||||
generic-y += ring_buffer.h
|
||||
generic-y += user.h
|
||||
|
||||
@@ -4,4 +4,5 @@ generated-y += syscall_table_64.h
|
||||
generic-y += agp.h
|
||||
generic-y += kvm_para.h
|
||||
generic-y += mcs_spinlock.h
|
||||
generic-y += ring_buffer.h
|
||||
generic-y += user.h
|
||||
|
||||
@@ -393,6 +393,7 @@ CONFIG_NETCONSOLE=m
|
||||
CONFIG_TUN=m
|
||||
CONFIG_VETH=m
|
||||
CONFIG_VIRTIO_NET=m
|
||||
CONFIG_EL3=m
|
||||
CONFIG_VORTEX=m
|
||||
CONFIG_TYPHOON=m
|
||||
CONFIG_ADAPTEC_STARFIRE=m
|
||||
|
||||
@@ -5,4 +5,5 @@ generated-y += syscall_table_spu.h
|
||||
generic-y += agp.h
|
||||
generic-y += mcs_spinlock.h
|
||||
generic-y += qrwlock.h
|
||||
generic-y += ring_buffer.h
|
||||
generic-y += early_ioremap.h
|
||||
|
||||
@@ -101,16 +101,6 @@ &ccc_nw {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2c0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2c0_fabric>;
|
||||
};
|
||||
|
||||
&i2c1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2c1_mssio>;
|
||||
};
|
||||
|
||||
&mmuart1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart1_fabric>;
|
||||
|
||||
@@ -14,6 +14,16 @@ / {
|
||||
"microchip,mpfs";
|
||||
};
|
||||
|
||||
&i2c0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2c0_fabric>;
|
||||
};
|
||||
|
||||
&i2c1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2c1_mssio>;
|
||||
};
|
||||
|
||||
&syscontroller {
|
||||
microchip,bitstream-flash = <&sys_ctrl_flash>;
|
||||
};
|
||||
|
||||
@@ -11,3 +11,22 @@ / {
|
||||
"microchip,mpfs-icicle-kit",
|
||||
"microchip,mpfs";
|
||||
};
|
||||
|
||||
&i2c0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2c0_fabric>;
|
||||
};
|
||||
|
||||
/*
|
||||
* Due to silicon errata, routing via MSS IOs doesn't work on ES devices.
|
||||
* Instead, i2c1, appearing on B1/C1, which are normally MSS IOs, is routed
|
||||
* via the fabric and back to B1/C1 via "fabric-test" functionality.
|
||||
* This is done silently by Libero, so the iomux0 setting for i2c1 has to
|
||||
* be fabric IO, despite tooling etc saying that MSS IOs are used.
|
||||
*
|
||||
* See Section 3.3 of https://ww1.microchip.com/downloads/aemDocuments/documents/FPGA/ProductDocuments/Errata/polarfiresoc/microsemi_polarfire_soc_fpga_egineering_samples_errata_er0219_v1.pdf
|
||||
*/
|
||||
&i2c1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2c1_fabric>;
|
||||
};
|
||||
|
||||
@@ -135,29 +135,6 @@ &tdm_ext {
|
||||
clock-frequency = <49152000>;
|
||||
};
|
||||
|
||||
&camss {
|
||||
assigned-clocks = <&ispcrg JH7110_ISPCLK_DOM4_APB_FUNC>,
|
||||
<&ispcrg JH7110_ISPCLK_MIPI_RX0_PXL>;
|
||||
assigned-clock-rates = <49500000>, <198000000>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
camss_from_csi2rx: endpoint {
|
||||
remote-endpoint = <&csi2rx_to_camss>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&csi2rx {
|
||||
assigned-clocks = <&ispcrg JH7110_ISPCLK_VIN_SYS>;
|
||||
assigned-clock-rates = <297000000>;
|
||||
@@ -175,9 +152,7 @@ port@0 {
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
csi2rx_to_camss: endpoint {
|
||||
remote-endpoint = <&camss_from_csi2rx>;
|
||||
};
|
||||
/* remote CAMSS endpoint */
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1199,34 +1199,6 @@ csi_phy: phy@19820000 {
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
camss: isp@19840000 {
|
||||
compatible = "starfive,jh7110-camss";
|
||||
reg = <0x0 0x19840000 0x0 0x10000>,
|
||||
<0x0 0x19870000 0x0 0x30000>;
|
||||
reg-names = "syscon", "isp";
|
||||
clocks = <&ispcrg JH7110_ISPCLK_DOM4_APB_FUNC>,
|
||||
<&ispcrg JH7110_ISPCLK_ISPV2_TOP_WRAPPER_C>,
|
||||
<&ispcrg JH7110_ISPCLK_DVP_INV>,
|
||||
<&ispcrg JH7110_ISPCLK_VIN_P_AXI_WR>,
|
||||
<&ispcrg JH7110_ISPCLK_MIPI_RX0_PXL>,
|
||||
<&syscrg JH7110_SYSCLK_ISP_TOP_CORE>,
|
||||
<&syscrg JH7110_SYSCLK_ISP_TOP_AXI>;
|
||||
clock-names = "apb_func", "wrapper_clk_c", "dvp_inv",
|
||||
"axiwr", "mipi_rx0_pxl", "ispcore_2x",
|
||||
"isp_axi";
|
||||
resets = <&ispcrg JH7110_ISPRST_ISPV2_TOP_WRAPPER_P>,
|
||||
<&ispcrg JH7110_ISPRST_ISPV2_TOP_WRAPPER_C>,
|
||||
<&ispcrg JH7110_ISPRST_VIN_P_AXI_RD>,
|
||||
<&ispcrg JH7110_ISPRST_VIN_P_AXI_WR>,
|
||||
<&syscrg JH7110_SYSRST_ISP_TOP>,
|
||||
<&syscrg JH7110_SYSRST_ISP_TOP_AXI>;
|
||||
reset-names = "wrapper_p", "wrapper_c", "axird",
|
||||
"axiwr", "isp_top_n", "isp_top_axi";
|
||||
power-domains = <&pwrc JH7110_PD_ISP>;
|
||||
interrupts = <92>, <87>, <90>, <88>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
voutcrg: clock-controller@295c0000 {
|
||||
compatible = "starfive,jh7110-voutcrg";
|
||||
reg = <0x0 0x295c0000 0x0 0x10000>;
|
||||
|
||||
@@ -14,5 +14,6 @@ generic-y += ticket_spinlock.h
|
||||
generic-y += qrwlock.h
|
||||
generic-y += qrwlock_types.h
|
||||
generic-y += qspinlock.h
|
||||
generic-y += ring_buffer.h
|
||||
generic-y += user.h
|
||||
generic-y += vmlinux.lds.h
|
||||
|
||||
@@ -415,7 +415,6 @@ int kvm_riscv_vcpu_mmio_load(struct kvm_vcpu *vcpu, struct kvm_run *run,
|
||||
shift = 8 * (sizeof(ulong) - len);
|
||||
} else if ((insn & INSN_MASK_LBU) == INSN_MATCH_LBU) {
|
||||
len = 1;
|
||||
shift = 8 * (sizeof(ulong) - len);
|
||||
#ifdef CONFIG_64BIT
|
||||
} else if ((insn & INSN_MASK_LD) == INSN_MATCH_LD) {
|
||||
len = 8;
|
||||
@@ -649,22 +648,22 @@ int kvm_riscv_vcpu_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
||||
case 1:
|
||||
data8 = *((u8 *)run->mmio.data);
|
||||
SET_RD(insn, &vcpu->arch.guest_context,
|
||||
(ulong)data8 << shift >> shift);
|
||||
(long)((ulong)data8 << shift) >> shift);
|
||||
break;
|
||||
case 2:
|
||||
data16 = *((u16 *)run->mmio.data);
|
||||
SET_RD(insn, &vcpu->arch.guest_context,
|
||||
(ulong)data16 << shift >> shift);
|
||||
(long)((ulong)data16 << shift) >> shift);
|
||||
break;
|
||||
case 4:
|
||||
data32 = *((u32 *)run->mmio.data);
|
||||
SET_RD(insn, &vcpu->arch.guest_context,
|
||||
(ulong)data32 << shift >> shift);
|
||||
(long)((ulong)data32 << shift) >> shift);
|
||||
break;
|
||||
case 8:
|
||||
data64 = *((u64 *)run->mmio.data);
|
||||
SET_RD(insn, &vcpu->arch.guest_context,
|
||||
(ulong)data64 << shift >> shift);
|
||||
(long)((ulong)data64 << shift) >> shift);
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
@@ -453,8 +453,10 @@ int kvm_riscv_vcpu_pmu_snapshot_set_shmem(struct kvm_vcpu *vcpu, unsigned long s
|
||||
}
|
||||
|
||||
kvpmu->sdata = kzalloc(snapshot_area_size, GFP_ATOMIC);
|
||||
if (!kvpmu->sdata)
|
||||
return -ENOMEM;
|
||||
if (!kvpmu->sdata) {
|
||||
sbiret = SBI_ERR_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* No need to check writable slot explicitly as kvm_vcpu_write_guest does it internally */
|
||||
if (kvm_vcpu_write_guest(vcpu, saddr, kvpmu->sdata, snapshot_area_size)) {
|
||||
@@ -499,8 +501,10 @@ int kvm_riscv_vcpu_pmu_event_info(struct kvm_vcpu *vcpu, unsigned long saddr_low
|
||||
}
|
||||
|
||||
einfo = kzalloc(shmem_size, GFP_KERNEL);
|
||||
if (!einfo)
|
||||
return -ENOMEM;
|
||||
if (!einfo) {
|
||||
ret = SBI_ERR_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = kvm_vcpu_read_guest(vcpu, shmem, einfo, shmem_size);
|
||||
if (ret) {
|
||||
|
||||
@@ -46,7 +46,7 @@ void kvm_riscv_vcpu_record_steal_time(struct kvm_vcpu *vcpu)
|
||||
gfn = shmem >> PAGE_SHIFT;
|
||||
hva = kvm_vcpu_gfn_to_hva(vcpu, gfn);
|
||||
|
||||
if (WARN_ON(kvm_is_error_hva(hva))) {
|
||||
if (kvm_is_error_hva(hva)) {
|
||||
vcpu->arch.sta.shmem = INVALID_GPA;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -55,6 +55,8 @@ static int kvm_sbi_ext_v01_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
|
||||
|
||||
for_each_set_bit(i, &hmask, BITS_PER_LONG) {
|
||||
rvcpu = kvm_get_vcpu_by_id(vcpu->kvm, i);
|
||||
if (!rvcpu)
|
||||
continue;
|
||||
ret = kvm_riscv_vcpu_set_interrupt(rvcpu, IRQ_VS_SOFT);
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
@@ -7,3 +7,4 @@ generated-y += unistd_nr.h
|
||||
generic-y += asm-offsets.h
|
||||
generic-y += mcs_spinlock.h
|
||||
generic-y += mmzone.h
|
||||
generic-y += ring_buffer.h
|
||||
|
||||
@@ -186,6 +186,13 @@ static u64 pai_getctr(unsigned long *page, int nr, unsigned long offset)
|
||||
return page[nr];
|
||||
}
|
||||
|
||||
static void pai_setctr(unsigned long *page, int nr, unsigned long offset, u64 v)
|
||||
{
|
||||
if (offset)
|
||||
nr += offset / sizeof(*page);
|
||||
page[nr] = v;
|
||||
}
|
||||
|
||||
/* Read the counter values. Return value from location in CMP. For base
|
||||
* event xxx_ALL sum up all events. Returns counter value.
|
||||
*/
|
||||
@@ -551,6 +558,8 @@ static void paicrypt_del(struct perf_event *event, int flags)
|
||||
/* Create raw data and save it in buffer. Calculate the delta for each
|
||||
* counter between this invocation and the last invocation.
|
||||
* Returns number of bytes copied.
|
||||
* After reading from PAI counter page, save the read value to the old
|
||||
* page to calculate PAI counter deltas.
|
||||
* Saves only entries with positive counter difference of the form
|
||||
* 2 bytes: Number of counter
|
||||
* 8 bytes: Value of counter
|
||||
@@ -562,16 +571,22 @@ static size_t pai_copy(struct pai_userdata *userdata, unsigned long *page,
|
||||
int i, outidx = 0;
|
||||
|
||||
for (i = 1; i <= pp->num_avail; i++) {
|
||||
u64 val = 0, val_old = 0;
|
||||
u64 val = 0, val_old = 0, val_k = 0, val_old_k = 0;
|
||||
|
||||
if (!exclude_kernel) {
|
||||
val += pai_getctr(page, i, pp->kernel_offset);
|
||||
val_old += pai_getctr(page_old, i, pp->kernel_offset);
|
||||
val_k = pai_getctr(page, i, pp->kernel_offset);
|
||||
val_old_k = pai_getctr(page_old, i, pp->kernel_offset);
|
||||
if (val_k != val_old_k)
|
||||
pai_setctr(page_old, i, pp->kernel_offset, val_k);
|
||||
}
|
||||
if (!exclude_user) {
|
||||
val += pai_getctr(page, i, 0);
|
||||
val_old += pai_getctr(page_old, i, 0);
|
||||
val = pai_getctr(page, i, 0);
|
||||
val_old = pai_getctr(page_old, i, 0);
|
||||
if (val != val_old)
|
||||
pai_setctr(page_old, i, 0, val);
|
||||
}
|
||||
val += val_k;
|
||||
val_old += val_old_k;
|
||||
if (val >= val_old)
|
||||
val -= val_old;
|
||||
else
|
||||
@@ -602,8 +617,6 @@ static size_t pai_copy(struct pai_userdata *userdata, unsigned long *page,
|
||||
static int pai_push_sample(size_t rawsize, struct pai_map *cpump,
|
||||
struct perf_event *event)
|
||||
{
|
||||
int idx = PAI_PMU_IDX(event);
|
||||
struct pai_pmu *pp = &pai_pmu[idx];
|
||||
struct perf_sample_data data;
|
||||
struct perf_raw_record raw;
|
||||
struct pt_regs regs;
|
||||
@@ -634,8 +647,6 @@ static int pai_push_sample(size_t rawsize, struct pai_map *cpump,
|
||||
|
||||
overflow = perf_event_overflow(event, &data, ®s);
|
||||
perf_event_update_userpage(event);
|
||||
/* Save crypto counter lowcore page after reading event data. */
|
||||
memcpy((void *)PAI_SAVE_AREA(event), cpump->area, pp->area_size);
|
||||
return overflow;
|
||||
}
|
||||
|
||||
@@ -651,7 +662,7 @@ static void pai_have_sample(struct perf_event *event, struct pai_map *cpump)
|
||||
rawsize = pai_copy(cpump->save, cpump->area, pp,
|
||||
(unsigned long *)PAI_SAVE_AREA(event),
|
||||
event->attr.exclude_user,
|
||||
event->attr.exclude_kernel);
|
||||
!pp->kernel_offset ? true : event->attr.exclude_kernel);
|
||||
if (rawsize) /* No incremented counters */
|
||||
pai_push_sample(rawsize, cpump, event);
|
||||
}
|
||||
|
||||
@@ -192,17 +192,21 @@ static void tl_to_masks(struct sysinfo_15_1_x *info)
|
||||
end = (union topology_entry *)((unsigned long)info + info->length);
|
||||
while (tle < end) {
|
||||
switch (tle->nl) {
|
||||
/*
|
||||
* Adjust drawer_id, book_id, and socked_id so they match the
|
||||
* numbering scheme of e.g. the hardware management console.
|
||||
*/
|
||||
case 3:
|
||||
drawer = drawer->next;
|
||||
drawer->id = tle->container.id;
|
||||
drawer->id = tle->container.id - 1;
|
||||
break;
|
||||
case 2:
|
||||
book = book->next;
|
||||
book->id = tle->container.id;
|
||||
book->id = tle->container.id - 1;
|
||||
break;
|
||||
case 1:
|
||||
socket = socket->next;
|
||||
socket->id = tle->container.id;
|
||||
socket->id = tle->container.id - 1;
|
||||
break;
|
||||
case 0:
|
||||
add_cpus_to_mask(&tle->cpu, drawer, book, socket);
|
||||
|
||||
@@ -267,6 +267,7 @@ static int dat_split_ste(struct kvm_s390_mmu_cache *mc, union pmd *pmdp, gfn_t g
|
||||
/* No need to take locks as the page table is not installed yet. */
|
||||
pgste_init.prefix_notif = old.s.fc1.prefix_notif;
|
||||
pgste_init.vsie_notif = old.s.fc1.vsie_notif;
|
||||
pgste_init.vsie_gmem = old.s.fc1.vsie_notif;
|
||||
pgste_init.pcl = uses_skeys && init.h.i;
|
||||
dat_init_pgstes(pt, pgste_init.val);
|
||||
} else {
|
||||
|
||||
@@ -145,7 +145,8 @@ union pgste {
|
||||
unsigned long cmma_d : 1; /* Dirty flag for CMMA bits */
|
||||
unsigned long prefix_notif : 1; /* Guest prefix invalidation notification */
|
||||
unsigned long vsie_notif : 1; /* Referenced in a shadow table */
|
||||
unsigned long : 5;
|
||||
unsigned long vsie_gmem : 1; /* Contains nested guest memory */
|
||||
unsigned long : 4;
|
||||
unsigned long : 8;
|
||||
};
|
||||
struct {
|
||||
|
||||
@@ -1445,6 +1445,7 @@ static int _do_shadow_pte(struct gmap *sg, gpa_t raddr, union pte *ptep_h, union
|
||||
} else {
|
||||
pgste = _gmap_ptep_xchg(sg->parent, ptep_h, newpte, pgste, f->gfn, false);
|
||||
pgste.vsie_notif = 1;
|
||||
pgste.vsie_gmem = 1;
|
||||
}
|
||||
pgste_set_unlock(ptep_h, pgste);
|
||||
if (rc)
|
||||
|
||||
@@ -125,7 +125,7 @@ struct gmap *gmap_new_child(struct gmap *parent, gfn_t limit)
|
||||
|
||||
int gmap_set_limit(struct gmap *gmap, gfn_t limit)
|
||||
{
|
||||
struct kvm_s390_mmu_cache *mc;
|
||||
struct kvm_s390_mmu_cache *mc __free(kvm_s390_mmu_cache) = NULL;
|
||||
int rc, type;
|
||||
|
||||
type = gmap_limit_to_type(limit);
|
||||
@@ -142,7 +142,6 @@ int gmap_set_limit(struct gmap *gmap, gfn_t limit)
|
||||
rc = dat_set_asce_limit(mc, &gmap->asce, type);
|
||||
} while (rc == -ENOMEM);
|
||||
|
||||
kvm_s390_free_mmu_cache(mc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -822,8 +821,8 @@ int gmap_ucas_translate(struct kvm_s390_mmu_cache *mc, struct gmap *gmap, gpa_t
|
||||
|
||||
int gmap_ucas_map(struct gmap *gmap, gfn_t p_gfn, gfn_t c_gfn, unsigned long count)
|
||||
{
|
||||
struct kvm_s390_mmu_cache *mc;
|
||||
int rc;
|
||||
struct kvm_s390_mmu_cache *mc __free(kvm_s390_mmu_cache) = NULL;
|
||||
int rc = 0;
|
||||
|
||||
mc = kvm_s390_new_mmu_cache();
|
||||
if (!mc)
|
||||
@@ -1026,13 +1025,15 @@ int gmap_insert_rmap(struct gmap *sg, gfn_t p_gfn, gfn_t r_gfn, int level)
|
||||
int gmap_protect_rmap(struct kvm_s390_mmu_cache *mc, struct gmap *sg, gfn_t p_gfn, gfn_t r_gfn,
|
||||
kvm_pfn_t pfn, int level, bool wr)
|
||||
{
|
||||
unsigned long bitmask;
|
||||
union crste *crstep;
|
||||
union pgste pgste;
|
||||
union pte *ptep;
|
||||
union pte pte;
|
||||
int flags, rc;
|
||||
|
||||
KVM_BUG_ON(!is_shadow(sg), sg->kvm);
|
||||
if (KVM_BUG_ON(!is_shadow(sg) || level <= TABLE_TYPE_PAGE_TABLE, sg->kvm))
|
||||
return -EINVAL;
|
||||
lockdep_assert_held(&sg->parent->children_lock);
|
||||
|
||||
flags = DAT_WALK_SPLIT_ALLOC | (uses_skeys(sg->parent) ? DAT_WALK_USES_SKEYS : 0);
|
||||
@@ -1041,8 +1042,9 @@ int gmap_protect_rmap(struct kvm_s390_mmu_cache *mc, struct gmap *sg, gfn_t p_gf
|
||||
if (rc)
|
||||
return rc;
|
||||
if (level <= TABLE_TYPE_REGION1) {
|
||||
bitmask = -1UL << (8 + 11 * level);
|
||||
scoped_guard(spinlock, &sg->host_to_rmap_lock)
|
||||
rc = gmap_insert_rmap(sg, p_gfn, r_gfn, level);
|
||||
rc = gmap_insert_rmap(sg, p_gfn, r_gfn & bitmask, level);
|
||||
}
|
||||
if (rc)
|
||||
return rc;
|
||||
@@ -1143,8 +1145,10 @@ void _gmap_handle_vsie_unshadow_event(struct gmap *parent, gfn_t gfn)
|
||||
}
|
||||
scoped_guard(spinlock, &sg->host_to_rmap_lock)
|
||||
head = radix_tree_delete(&sg->host_to_rmap, gfn);
|
||||
gmap_for_each_rmap_safe(rmap, rnext, head)
|
||||
gmap_for_each_rmap_safe(rmap, rnext, head) {
|
||||
gmap_unshadow_level(sg, rmap->r_gfn, rmap->level);
|
||||
kfree(rmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -167,6 +167,36 @@ static inline bool gmap_unmap_prefix(struct gmap *gmap, gfn_t gfn, gfn_t end)
|
||||
return _gmap_unmap_prefix(gmap, gfn, end, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* pte_needs_unshadow() -- Check if the pte operations triggers unshadowing.
|
||||
* @oldpte: the previous value for the guest pte.
|
||||
* @newpte: the new pte being set.
|
||||
* @pgste: the pgste for the pte entry.
|
||||
*
|
||||
* If the pgste.vsie_notif bit is not set, return false: the page is not
|
||||
* involved in vsie and thus should not trigger an unshadow operation.
|
||||
*
|
||||
* If the pgste.vsie_gmem bit is set, this pte represents shadowed guest
|
||||
* memory. The access rights on g3's memory should be synchronized with g1's
|
||||
* and g2's. Therefore unshadowing is triggered if the new and old pte
|
||||
* differ in protection, or if the new pte is invalid.
|
||||
*
|
||||
* If the pgste.vsie_gmem bit is not set, this pte maps the g2 dat tables
|
||||
* for g3. If the entry becomes writable or absent, it becomes impossible to
|
||||
* guarantee that the shadow mapping will match g2's mapping. In that case,
|
||||
* trigger an unshadow event.
|
||||
*
|
||||
* Return: true if an unshadow event should be triggered, otherwise false.
|
||||
*/
|
||||
static inline bool pte_needs_unshadow(union pte oldpte, union pte newpte, union pgste pgste)
|
||||
{
|
||||
if (!pgste.vsie_notif)
|
||||
return false;
|
||||
if (pgste.vsie_gmem)
|
||||
return (oldpte.h.p != newpte.h.p) || newpte.h.i;
|
||||
return !newpte.h.p || !newpte.s.pr;
|
||||
}
|
||||
|
||||
static inline union pgste _gmap_ptep_xchg(struct gmap *gmap, union pte *ptep, union pte newpte,
|
||||
union pgste pgste, gfn_t gfn, bool needs_lock)
|
||||
{
|
||||
@@ -180,8 +210,9 @@ static inline union pgste _gmap_ptep_xchg(struct gmap *gmap, union pte *ptep, un
|
||||
pgste.prefix_notif = 0;
|
||||
gmap_unmap_prefix(gmap, gfn, gfn + 1);
|
||||
}
|
||||
if (pgste.vsie_notif && (ptep->h.p != newpte.h.p || newpte.h.i)) {
|
||||
if (pte_needs_unshadow(*ptep, newpte, pgste)) {
|
||||
pgste.vsie_notif = 0;
|
||||
pgste.vsie_gmem = 0;
|
||||
if (needs_lock)
|
||||
gmap_handle_vsie_unshadow_event(gmap, gfn);
|
||||
else
|
||||
@@ -189,6 +220,7 @@ static inline union pgste _gmap_ptep_xchg(struct gmap *gmap, union pte *ptep, un
|
||||
}
|
||||
if (!ptep->s.d && newpte.s.d && !newpte.s.s)
|
||||
SetPageDirty(pfn_to_page(newpte.h.pfra));
|
||||
pgste.zero = 0;
|
||||
return __dat_ptep_xchg(ptep, pgste, newpte, gfn, gmap->asce, uses_skeys(gmap));
|
||||
}
|
||||
|
||||
@@ -198,6 +230,30 @@ static inline union pgste gmap_ptep_xchg(struct gmap *gmap, union pte *ptep, uni
|
||||
return _gmap_ptep_xchg(gmap, ptep, newpte, pgste, gfn, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* crste_needs_unshadow() -- Check if the crste operations triggers unshadowing.
|
||||
* @oldcrste: the previous value for the crste.
|
||||
* @newcrste: the new value for the crste.
|
||||
*
|
||||
* If the old crste did not have the vsie_notif bit set, return false: the
|
||||
* page is not involved in vsie and thus should not trigger an unshadow
|
||||
* operation. Conversely, if the bit is set, it can only be g3 memory, since
|
||||
* dat tables are never mapped using large pages.
|
||||
*
|
||||
* Similar to the pgste.vsie_gmem case of pte_needs_unshadow(), if the
|
||||
* protection bit is changing or the new page is invalid, trigger an
|
||||
* unshadow event. Also trigger an unshadow event if the new crste does not
|
||||
* have the vsie_notif bit set.
|
||||
*
|
||||
* Return: true if an unshadow event should be triggered, otherwise false.
|
||||
*/
|
||||
static inline bool crste_needs_unshadow(union crste oldcrste, union crste newcrste)
|
||||
{
|
||||
if (!oldcrste.s.fc1.vsie_notif)
|
||||
return false;
|
||||
return (newcrste.h.p != oldcrste.h.p) || newcrste.h.i || !newcrste.s.fc1.vsie_notif;
|
||||
}
|
||||
|
||||
static inline bool __must_check _gmap_crstep_xchg_atomic(struct gmap *gmap, union crste *crstep,
|
||||
union crste oldcrste, union crste newcrste,
|
||||
gfn_t gfn, bool needs_lock)
|
||||
@@ -216,8 +272,7 @@ static inline bool __must_check _gmap_crstep_xchg_atomic(struct gmap *gmap, unio
|
||||
newcrste.s.fc1.prefix_notif = 0;
|
||||
gmap_unmap_prefix(gmap, gfn, gfn + align);
|
||||
}
|
||||
if (crste_leaf(oldcrste) && oldcrste.s.fc1.vsie_notif &&
|
||||
(newcrste.h.p || newcrste.h.i || !newcrste.s.fc1.vsie_notif)) {
|
||||
if (crste_leaf(oldcrste) && crste_needs_unshadow(oldcrste, newcrste)) {
|
||||
newcrste.s.fc1.vsie_notif = 0;
|
||||
if (needs_lock)
|
||||
gmap_handle_vsie_unshadow_event(gmap, gfn);
|
||||
|
||||
@@ -3,4 +3,5 @@ generated-y += syscall_table.h
|
||||
generic-y += kvm_para.h
|
||||
generic-y += mcs_spinlock.h
|
||||
generic-y += parport.h
|
||||
generic-y += ring_buffer.h
|
||||
generic-y += text-patching.h
|
||||
|
||||
@@ -4,4 +4,5 @@ generated-y += syscall_table_64.h
|
||||
generic-y += agp.h
|
||||
generic-y += kvm_para.h
|
||||
generic-y += mcs_spinlock.h
|
||||
generic-y += ring_buffer.h
|
||||
generic-y += text-patching.h
|
||||
|
||||
@@ -17,6 +17,7 @@ generic-y += module.lds.h
|
||||
generic-y += parport.h
|
||||
generic-y += percpu.h
|
||||
generic-y += preempt.h
|
||||
generic-y += ring_buffer.h
|
||||
generic-y += runtime-const.h
|
||||
generic-y += softirq_stack.h
|
||||
generic-y += switch_to.h
|
||||
|
||||
@@ -13,7 +13,7 @@ CFLAGS_REMOVE_syscall_64.o = $(CC_FLAGS_FTRACE)
|
||||
CFLAGS_syscall_32.o += -fno-stack-protector
|
||||
CFLAGS_syscall_64.o += -fno-stack-protector
|
||||
|
||||
obj-y := entry.o entry_$(BITS).o syscall_$(BITS).o
|
||||
obj-y := entry.o entry_$(BITS).o syscall_$(BITS).o common.o
|
||||
|
||||
obj-y += vdso/
|
||||
obj-y += vsyscall/
|
||||
|
||||
61
arch/x86/entry/common.c
Normal file
61
arch/x86/entry/common.c
Normal file
@@ -0,0 +1,61 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#include <linux/entry-common.h>
|
||||
#include <linux/kvm_types.h>
|
||||
#include <linux/hrtimer_rearm.h>
|
||||
#include <asm/fred.h>
|
||||
#include <asm/desc.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_KVM_INTEL)
|
||||
/*
|
||||
* On VMX, NMIs and IRQs (as configured by KVM) are acknowledged by hardware as
|
||||
* part of the VM-Exit, i.e. the event itself is consumed as part the VM-Exit.
|
||||
* x86_entry_from_kvm() is invoked by KVM to effectively forward NMIs and IRQs
|
||||
* to the kernel for servicing. On SVM, a.k.a. AMD, the NMI/IRQ VM-Exit is
|
||||
* purely a signal that an NMI/IRQ is pending, i.e. the event that triggered
|
||||
* the VM-Exit is held pending until it's unblocked in the host.
|
||||
*/
|
||||
noinstr void x86_entry_from_kvm(unsigned int event_type, unsigned int vector)
|
||||
{
|
||||
if (event_type == EVENT_TYPE_EXTINT) {
|
||||
#ifdef CONFIG_X86_64
|
||||
/*
|
||||
* Use FRED dispatch, even when running IDT. The dispatch
|
||||
* tables are kept in sync between FRED and IDT, and the FRED
|
||||
* dispatch works well with CFI.
|
||||
*/
|
||||
fred_entry_from_kvm(event_type, vector);
|
||||
#else
|
||||
idt_entry_from_kvm(vector);
|
||||
#endif
|
||||
/*
|
||||
* Strictly speaking, only the NMI path requires noinstr.
|
||||
*/
|
||||
instrumentation_begin();
|
||||
/*
|
||||
* KVM/VMX will dispatch from IRQ-disabled but for a context
|
||||
* that will have IRQs-enabled. This confuses the entry code
|
||||
* and it will not have reprogrammed the timer. Do so now.
|
||||
*/
|
||||
hrtimer_rearm_deferred();
|
||||
instrumentation_end();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
WARN_ON_ONCE(event_type != EVENT_TYPE_NMI);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
if (cpu_feature_enabled(X86_FEATURE_FRED))
|
||||
return fred_entry_from_kvm(event_type, vector);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Notably, we must use IDT dispatch for NMI when running in IDT mode.
|
||||
* The FRED NMI context is significantly different and will not work
|
||||
* right (specifically FRED fixed the NMI recursion issue).
|
||||
*/
|
||||
idt_entry_from_kvm(vector);
|
||||
}
|
||||
EXPORT_SYMBOL_FOR_KVM(x86_entry_from_kvm);
|
||||
#endif
|
||||
@@ -75,3 +75,49 @@ THUNK warn_thunk_thunk, __warn_thunk
|
||||
#if defined(CONFIG_STACKPROTECTOR) && defined(CONFIG_SMP)
|
||||
EXPORT_SYMBOL(__ref_stack_chk_guard);
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_KVM_INTEL)
|
||||
.macro IDT_DO_EVENT_IRQOFF call_insn call_target
|
||||
/*
|
||||
* Unconditionally create a stack frame, getting the correct RSP on the
|
||||
* stack (for x86-64) would take two instructions anyways, and RBP can
|
||||
* be used to restore RSP to make objtool happy (see below).
|
||||
*/
|
||||
push %_ASM_BP
|
||||
mov %_ASM_SP, %_ASM_BP
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
/*
|
||||
* Align RSP to a 16-byte boundary (to emulate CPU behavior) before
|
||||
* creating the synthetic interrupt stack frame for the IRQ/NMI.
|
||||
*/
|
||||
and $-16, %rsp
|
||||
push $__KERNEL_DS
|
||||
push %rbp
|
||||
#endif
|
||||
pushf
|
||||
push $__KERNEL_CS
|
||||
\call_insn \call_target
|
||||
|
||||
/*
|
||||
* "Restore" RSP from RBP, even though IRET has already unwound RSP to
|
||||
* the correct value. objtool doesn't know the callee will IRET and,
|
||||
* without the explicit restore, thinks the stack is getting walloped.
|
||||
* Using an unwind hint is problematic due to x86-64's dynamic alignment.
|
||||
*/
|
||||
leave
|
||||
RET
|
||||
.endm
|
||||
|
||||
.pushsection .text, "ax"
|
||||
SYM_FUNC_START(idt_do_interrupt_irqoff)
|
||||
IDT_DO_EVENT_IRQOFF CALL_NOSPEC _ASM_ARG1
|
||||
SYM_FUNC_END(idt_do_interrupt_irqoff)
|
||||
.popsection
|
||||
|
||||
.pushsection .noinstr.text, "ax"
|
||||
SYM_FUNC_START(idt_do_nmi_irqoff)
|
||||
IDT_DO_EVENT_IRQOFF call asm_exc_nmi_kvm_vmx
|
||||
SYM_FUNC_END(idt_do_nmi_irqoff)
|
||||
.popsection
|
||||
#endif
|
||||
|
||||
@@ -147,5 +147,4 @@ SYM_FUNC_START(asm_fred_entry_from_kvm)
|
||||
RET
|
||||
|
||||
SYM_FUNC_END(asm_fred_entry_from_kvm)
|
||||
EXPORT_SYMBOL_FOR_KVM(asm_fred_entry_from_kvm);
|
||||
#endif
|
||||
|
||||
@@ -178,7 +178,7 @@ static int map_vdso(const struct vdso_image *image, unsigned long addr)
|
||||
if (IS_ERR(vma)) {
|
||||
ret = PTR_ERR(vma);
|
||||
do_munmap(mm, text_start, image->size, NULL);
|
||||
do_munmap(mm, addr, image->size, NULL);
|
||||
do_munmap(mm, addr, VDSO_NR_PAGES * PAGE_SIZE, NULL);
|
||||
goto up_fail;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,3 +14,4 @@ generic-y += early_ioremap.h
|
||||
generic-y += fprobe.h
|
||||
generic-y += mcs_spinlock.h
|
||||
generic-y += mmzone.h
|
||||
generic-y += ring_buffer.h
|
||||
|
||||
@@ -438,6 +438,10 @@ extern void idt_setup_traps(void);
|
||||
extern void idt_setup_apic_and_irq_gates(void);
|
||||
extern bool idt_is_f00f_address(unsigned long address);
|
||||
|
||||
extern void idt_do_interrupt_irqoff(unsigned long address);
|
||||
extern void idt_do_nmi_irqoff(void);
|
||||
extern void idt_entry_from_kvm(unsigned int vector);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
extern void idt_setup_early_pf(void);
|
||||
#else
|
||||
|
||||
@@ -145,7 +145,7 @@ struct gate_struct {
|
||||
typedef struct gate_struct gate_desc;
|
||||
|
||||
#ifndef _SETUP
|
||||
static inline unsigned long gate_offset(const gate_desc *g)
|
||||
static __always_inline unsigned long gate_offset(const gate_desc *g)
|
||||
{
|
||||
#ifdef CONFIG_X86_64
|
||||
return g->offset_low | ((unsigned long)g->offset_middle << 16) |
|
||||
|
||||
@@ -97,4 +97,6 @@ static __always_inline void arch_exit_to_user_mode(void)
|
||||
}
|
||||
#define arch_exit_to_user_mode arch_exit_to_user_mode
|
||||
|
||||
extern void x86_entry_from_kvm(unsigned int entry_type, unsigned int vector);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -110,7 +110,6 @@ static __always_inline unsigned long fred_event_data(struct pt_regs *regs) { ret
|
||||
static inline void cpu_init_fred_exceptions(void) { }
|
||||
static inline void cpu_init_fred_rsps(void) { }
|
||||
static inline void fred_complete_exception_setup(void) { }
|
||||
static inline void fred_entry_from_kvm(unsigned int type, unsigned int vector) { }
|
||||
static inline void fred_sync_rsp0(unsigned long rsp0) { }
|
||||
static inline void fred_update_rsp0(void) { }
|
||||
#endif /* CONFIG_X86_FRED */
|
||||
|
||||
@@ -92,6 +92,7 @@ static const struct cpuid_dep cpuid_deps[] = {
|
||||
{ X86_FEATURE_FRED, X86_FEATURE_LKGS },
|
||||
{ X86_FEATURE_SPEC_CTRL_SSBD, X86_FEATURE_SPEC_CTRL },
|
||||
{ X86_FEATURE_LASS, X86_FEATURE_SMAP },
|
||||
{ X86_FEATURE_INVLPGB, X86_FEATURE_PCID },
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -268,6 +268,21 @@ void __init idt_setup_early_pf(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_KVM_INTEL)
|
||||
noinstr void idt_entry_from_kvm(unsigned int vector)
|
||||
{
|
||||
if (vector == NMI_VECTOR)
|
||||
return idt_do_nmi_irqoff();
|
||||
|
||||
/*
|
||||
* Only the NMI path requires noinstr.
|
||||
*/
|
||||
instrumentation_begin();
|
||||
idt_do_interrupt_irqoff(gate_offset(idt_table + vector));
|
||||
instrumentation_end();
|
||||
}
|
||||
#endif
|
||||
|
||||
static void __init idt_map_in_cea(void)
|
||||
{
|
||||
/*
|
||||
|
||||
@@ -614,7 +614,6 @@ DEFINE_IDTENTRY_RAW(exc_nmi_kvm_vmx)
|
||||
{
|
||||
exc_nmi(regs);
|
||||
}
|
||||
EXPORT_SYMBOL_FOR_KVM(asm_exc_nmi_kvm_vmx);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NMI_CHECK_CPU
|
||||
|
||||
@@ -1300,12 +1300,14 @@ bool __init avic_hardware_setup(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable IPI virtualization for AMD Family 17h CPUs (Zen1 and Zen2)
|
||||
* due to erratum 1235, which results in missed VM-Exits on the sender
|
||||
* and thus missed wake events for blocking vCPUs due to the CPU
|
||||
* failing to see a software update to clear IsRunning.
|
||||
* Disable IPI virtualization for AMD Family 17h (Zen1 and Zen2) and
|
||||
* Hygon Family 18h (derived from AMD Zen1) CPUs due to erratum 1235,
|
||||
* which results in missed VM-Exits on the sender and thus missed wake
|
||||
* events for blocking vCPUs due to the CPU failing to see a software
|
||||
* update to clear IsRunning.
|
||||
*/
|
||||
enable_ipiv = enable_ipiv && boot_cpu_data.x86 != 0x17;
|
||||
if (boot_cpu_data.x86 == 0x17 || boot_cpu_data.x86 == 0x18)
|
||||
enable_ipiv = false;
|
||||
|
||||
amd_iommu_register_ga_log_notifier(&avic_ga_log_notifier);
|
||||
|
||||
|
||||
@@ -31,38 +31,6 @@
|
||||
#define VCPU_R15 __VCPU_REGS_R15 * WORD_SIZE
|
||||
#endif
|
||||
|
||||
.macro VMX_DO_EVENT_IRQOFF call_insn call_target
|
||||
/*
|
||||
* Unconditionally create a stack frame, getting the correct RSP on the
|
||||
* stack (for x86-64) would take two instructions anyways, and RBP can
|
||||
* be used to restore RSP to make objtool happy (see below).
|
||||
*/
|
||||
push %_ASM_BP
|
||||
mov %_ASM_SP, %_ASM_BP
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
/*
|
||||
* Align RSP to a 16-byte boundary (to emulate CPU behavior) before
|
||||
* creating the synthetic interrupt stack frame for the IRQ/NMI.
|
||||
*/
|
||||
and $-16, %rsp
|
||||
push $__KERNEL_DS
|
||||
push %rbp
|
||||
#endif
|
||||
pushf
|
||||
push $__KERNEL_CS
|
||||
\call_insn \call_target
|
||||
|
||||
/*
|
||||
* "Restore" RSP from RBP, even though IRET has already unwound RSP to
|
||||
* the correct value. objtool doesn't know the callee will IRET and,
|
||||
* without the explicit restore, thinks the stack is getting walloped.
|
||||
* Using an unwind hint is problematic due to x86-64's dynamic alignment.
|
||||
*/
|
||||
leave
|
||||
RET
|
||||
.endm
|
||||
|
||||
.section .noinstr.text, "ax"
|
||||
|
||||
/**
|
||||
@@ -320,10 +288,6 @@ SYM_INNER_LABEL_ALIGN(vmx_vmexit, SYM_L_GLOBAL)
|
||||
|
||||
SYM_FUNC_END(__vmx_vcpu_run)
|
||||
|
||||
SYM_FUNC_START(vmx_do_nmi_irqoff)
|
||||
VMX_DO_EVENT_IRQOFF call asm_exc_nmi_kvm_vmx
|
||||
SYM_FUNC_END(vmx_do_nmi_irqoff)
|
||||
|
||||
#ifndef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
|
||||
|
||||
/**
|
||||
@@ -375,13 +339,3 @@ SYM_FUNC_START(vmread_error_trampoline)
|
||||
RET
|
||||
SYM_FUNC_END(vmread_error_trampoline)
|
||||
#endif
|
||||
|
||||
.section .text, "ax"
|
||||
|
||||
#ifndef CONFIG_X86_FRED
|
||||
|
||||
SYM_FUNC_START(vmx_do_interrupt_irqoff)
|
||||
VMX_DO_EVENT_IRQOFF CALL_NOSPEC _ASM_ARG1
|
||||
SYM_FUNC_END(vmx_do_interrupt_irqoff)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7117,9 +7117,6 @@ void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
|
||||
vmcs_write64(EOI_EXIT_BITMAP3, eoi_exit_bitmap[3]);
|
||||
}
|
||||
|
||||
void vmx_do_interrupt_irqoff(unsigned long entry);
|
||||
void vmx_do_nmi_irqoff(void);
|
||||
|
||||
static void handle_nm_fault_irqoff(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
/*
|
||||
@@ -7161,17 +7158,8 @@ static void handle_external_interrupt_irqoff(struct kvm_vcpu *vcpu,
|
||||
"unexpected VM-Exit interrupt info: 0x%x", intr_info))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Invoke the kernel's IRQ handler for the vector. Use the FRED path
|
||||
* when it's available even if FRED isn't fully enabled, e.g. even if
|
||||
* FRED isn't supported in hardware, in order to avoid the indirect
|
||||
* CALL in the non-FRED path.
|
||||
*/
|
||||
kvm_before_interrupt(vcpu, KVM_HANDLING_IRQ);
|
||||
if (IS_ENABLED(CONFIG_X86_FRED))
|
||||
fred_entry_from_kvm(EVENT_TYPE_EXTINT, vector);
|
||||
else
|
||||
vmx_do_interrupt_irqoff(gate_offset((gate_desc *)host_idt_base + vector));
|
||||
x86_entry_from_kvm(EVENT_TYPE_EXTINT, vector);
|
||||
kvm_after_interrupt(vcpu);
|
||||
|
||||
vcpu->arch.at_instruction_boundary = true;
|
||||
@@ -7481,10 +7469,7 @@ noinstr void vmx_handle_nmi(struct kvm_vcpu *vcpu)
|
||||
return;
|
||||
|
||||
kvm_before_interrupt(vcpu, KVM_HANDLING_NMI);
|
||||
if (cpu_feature_enabled(X86_FEATURE_FRED))
|
||||
fred_entry_from_kvm(EVENT_TYPE_NMI, NMI_VECTOR);
|
||||
else
|
||||
vmx_do_nmi_irqoff();
|
||||
x86_entry_from_kvm(EVENT_TYPE_NMI, NMI_VECTOR);
|
||||
kvm_after_interrupt(vcpu);
|
||||
}
|
||||
|
||||
|
||||
@@ -4876,7 +4876,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
|
||||
r = tdp_enabled;
|
||||
break;
|
||||
case KVM_CAP_X86_APIC_BUS_CYCLES_NS:
|
||||
r = APIC_BUS_CYCLE_NS_DEFAULT;
|
||||
r = kvm ? kvm->arch.apic_bus_cycle_ns : APIC_BUS_CYCLE_NS_DEFAULT;
|
||||
break;
|
||||
case KVM_CAP_EXIT_HYPERCALL:
|
||||
r = KVM_EXIT_HYPERCALL_VALID_MASK;
|
||||
|
||||
@@ -6,5 +6,6 @@ generic-y += mcs_spinlock.h
|
||||
generic-y += parport.h
|
||||
generic-y += qrwlock.h
|
||||
generic-y += qspinlock.h
|
||||
generic-y += ring_buffer.h
|
||||
generic-y += user.h
|
||||
generic-y += text-patching.h
|
||||
|
||||
@@ -55,6 +55,10 @@ int fs_bio_integrity_verify(struct bio *bio, sector_t sector, unsigned int size)
|
||||
{
|
||||
struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
|
||||
struct bio_integrity_payload *bip = bio_integrity(bio);
|
||||
struct bvec_iter data_iter = {
|
||||
.bi_sector = sector,
|
||||
.bi_size = size,
|
||||
};
|
||||
|
||||
/*
|
||||
* Reinitialize bip->bip_iter.
|
||||
@@ -65,7 +69,7 @@ int fs_bio_integrity_verify(struct bio *bio, sector_t sector, unsigned int size)
|
||||
memset(&bip->bip_iter, 0, sizeof(bip->bip_iter));
|
||||
bip->bip_iter.bi_sector = sector;
|
||||
bip->bip_iter.bi_size = bio_integrity_bytes(bi, size >> SECTOR_SHIFT);
|
||||
return blk_status_to_errno(bio_integrity_verify(bio, &bip->bip_iter));
|
||||
return blk_status_to_errno(bio_integrity_verify(bio, &data_iter));
|
||||
}
|
||||
|
||||
static int __init fs_bio_integrity_init(void)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user