mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
regulator: pca9450: add input supply links
Merge series from Oleksij Rempel <o.rempel@pengutronix.de>: This series adds input supply definitions for the NXP PCA9450 PMIC. Some systems detect power events such as undervoltage before the PMIC. To allow correct propagation of such events, each regulator must define its upstream input supply. The first patch updates the devicetree binding to document new *-supply properties, and the second patch adds matching .supply_name entries in the driver. Changes in this series: - Document INL1, INB13, INB26 and INB45 supply properties - Link all LDO and BUCK regulators to their corresponding input groups
This commit is contained in:
2
.mailmap
2
.mailmap
@@ -27,6 +27,7 @@ Alan Cox <alan@lxorguk.ukuu.org.uk>
|
||||
Alan Cox <root@hraefn.swansea.linux.org.uk>
|
||||
Aleksandar Markovic <aleksandar.markovic@mips.com> <aleksandar.markovic@imgtec.com>
|
||||
Aleksey Gorelov <aleksey_gorelov@phoenix.com>
|
||||
Alex Williamson <alex@shazbot.org> <alex.williamson@redhat.com>
|
||||
Alexander Lobakin <alobakin@pm.me> <alobakin@dlink.ru>
|
||||
Alexander Lobakin <alobakin@pm.me> <alobakin@marvell.com>
|
||||
Alexander Lobakin <alobakin@pm.me> <bloodyreaper@yandex.ru>
|
||||
@@ -227,6 +228,7 @@ Dmitry Safonov <0x7f454c46@gmail.com> <dima@arista.com>
|
||||
Dmitry Safonov <0x7f454c46@gmail.com> <d.safonov@partner.samsung.com>
|
||||
Dmitry Safonov <0x7f454c46@gmail.com> <dsafonov@virtuozzo.com>
|
||||
Domen Puncer <domen@coderock.org>
|
||||
Dong Aisheng <aisheng.dong@nxp.com> <b29396@freescale.com>
|
||||
Douglas Gilbert <dougg@torque.net>
|
||||
Drew Fustini <fustini@kernel.org> <drew@pdp7.com>
|
||||
<duje@dujemihanovic.xyz> <duje.mihanovic@skole.hr>
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/i2c/apm,xgene-slimpro-i2c.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: APM X-Gene SLIMpro Mailbox I2C
|
||||
|
||||
maintainers:
|
||||
- Khuong Dinh <khuong@os.amperecomputing.com>
|
||||
|
||||
description:
|
||||
An I2C controller accessed over the "SLIMpro" mailbox.
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/i2c/i2c-controller.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: apm,xgene-slimpro-i2c
|
||||
|
||||
mboxes:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- mboxes
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
compatible = "apm,xgene-slimpro-i2c";
|
||||
mboxes = <&mailbox 0>;
|
||||
};
|
||||
@@ -1,15 +0,0 @@
|
||||
APM X-Gene SLIMpro Mailbox I2C Driver
|
||||
|
||||
An I2C controller accessed over the "SLIMpro" mailbox.
|
||||
|
||||
Required properties :
|
||||
|
||||
- compatible : should be "apm,xgene-slimpro-i2c"
|
||||
- mboxes : use the label reference for the mailbox as the first parameter.
|
||||
The second parameter is the channel number.
|
||||
|
||||
Example :
|
||||
i2cslimpro {
|
||||
compatible = "apm,xgene-slimpro-i2c";
|
||||
mboxes = <&mailbox 0>;
|
||||
};
|
||||
@@ -142,7 +142,9 @@ allOf:
|
||||
required:
|
||||
- orientation-switch
|
||||
then:
|
||||
$ref: /schemas/usb/usb-switch.yaml#
|
||||
allOf:
|
||||
- $ref: /schemas/usb/usb-switch.yaml#
|
||||
- $ref: /schemas/usb/usb-switch-ports.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
|
||||
@@ -24,6 +24,10 @@ properties:
|
||||
- enum:
|
||||
- qcom,qcs8300-qmp-ufs-phy
|
||||
- const: qcom,sa8775p-qmp-ufs-phy
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,kaanapali-qmp-ufs-phy
|
||||
- const: qcom,sm8750-qmp-ufs-phy
|
||||
- enum:
|
||||
- qcom,msm8996-qmp-ufs-phy
|
||||
- qcom,msm8998-qmp-ufs-phy
|
||||
|
||||
@@ -125,7 +125,9 @@ allOf:
|
||||
contains:
|
||||
const: google,gs101-usb31drd-phy
|
||||
then:
|
||||
$ref: /schemas/usb/usb-switch.yaml#
|
||||
allOf:
|
||||
- $ref: /schemas/usb/usb-switch.yaml#
|
||||
- $ref: /schemas/usb/usb-switch-ports.yaml#
|
||||
|
||||
properties:
|
||||
clocks:
|
||||
|
||||
@@ -41,6 +41,21 @@ properties:
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
inl1-supply:
|
||||
description: Regulator supply for the INL1 pin group, powering LDOx
|
||||
|
||||
inb13-supply:
|
||||
description:
|
||||
Regulator supply for the INB13 pin group, powering BUCK1 and BUCK3.
|
||||
|
||||
inb26-supply:
|
||||
description:
|
||||
Regulator supply for the INB26 pin group, powering BUCK2 and BUCK6.
|
||||
|
||||
inb45-supply:
|
||||
description:
|
||||
Regulator supply for the INB45 pin group, powering BUCK4 and BUCK5.
|
||||
|
||||
regulators:
|
||||
type: object
|
||||
description: |
|
||||
|
||||
@@ -197,6 +197,7 @@ allOf:
|
||||
- renesas,rcar-gen2-scif
|
||||
- renesas,rcar-gen3-scif
|
||||
- renesas,rcar-gen4-scif
|
||||
- renesas,rcar-gen5-scif
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
|
||||
@@ -79,6 +79,7 @@ properties:
|
||||
- fsl,imx-audio-nau8822
|
||||
- fsl,imx-audio-sgtl5000
|
||||
- fsl,imx-audio-si476x
|
||||
- fsl,imx-audio-tlv320
|
||||
- fsl,imx-audio-tlv320aic31xx
|
||||
- fsl,imx-audio-tlv320aic32x4
|
||||
- fsl,imx-audio-wm8524
|
||||
|
||||
@@ -33,6 +33,7 @@ properties:
|
||||
- qcom,apq8096-sndcard
|
||||
- qcom,glymur-sndcard
|
||||
- qcom,qcm6490-idp-sndcard
|
||||
- qcom,qcs615-sndcard
|
||||
- qcom,qcs6490-rb3gen2-sndcard
|
||||
- qcom,qcs8275-sndcard
|
||||
- qcom,qcs9075-sndcard
|
||||
|
||||
@@ -24,10 +24,10 @@ description: |
|
||||
Instruments Smart Amp speaker protection algorithm. The
|
||||
integrated speaker voltage and current sense provides for real time
|
||||
monitoring of loudspeaker behavior.
|
||||
The TAS5825/TAS5827 is a stereo, digital input Class-D audio
|
||||
amplifier optimized for efficiently driving high peak power into
|
||||
small loudspeakers. An integrated on-chip DSP supports Texas
|
||||
Instruments Smart Amp speaker protection algorithm.
|
||||
The TAS5802/TAS5815/TAS5825/TAS5827/TAS5828 is a stereo, digital input
|
||||
Class-D audio amplifier optimized for efficiently driving high peak
|
||||
power into small loudspeakers. An integrated on-chip DSP supports
|
||||
Texas Instruments Smart Amp speaker protection algorithm.
|
||||
|
||||
Specifications about the audio amplifier can be found at:
|
||||
https://www.ti.com/lit/gpn/tas2120
|
||||
@@ -35,8 +35,10 @@ description: |
|
||||
https://www.ti.com/lit/gpn/tas2563
|
||||
https://www.ti.com/lit/gpn/tas2572
|
||||
https://www.ti.com/lit/gpn/tas2781
|
||||
https://www.ti.com/lit/gpn/tas5815
|
||||
https://www.ti.com/lit/gpn/tas5825m
|
||||
https://www.ti.com/lit/gpn/tas5827
|
||||
https://www.ti.com/lit/gpn/tas5828m
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
@@ -65,11 +67,21 @@ properties:
|
||||
Protection and Audio Processing, 16/20/24/32bit stereo I2S or
|
||||
multichannel TDM.
|
||||
|
||||
ti,tas5802: 22-W, Inductor-Less, Digital Input, Closed-Loop Class-D
|
||||
Audio Amplifier with 96-Khz Extended Processing and Low Idle Power
|
||||
Dissipation.
|
||||
|
||||
ti,tas5815: 30-W, Digital Input, Stereo, Closed-loop Class-D Audio
|
||||
Amplifier with 96 kHz Enhanced Processing
|
||||
|
||||
ti,tas5825: 38-W Stereo, Inductor-Less, Digital Input, Closed-Loop 4.5V
|
||||
to 26.4V Class-D Audio Amplifier with 192-kHz Extended Audio Processing.
|
||||
|
||||
ti,tas5827: 47-W Stereo, Digital Input, High Efficiency Closed-Loop Class-D
|
||||
Amplifier with Class-H Algorithm
|
||||
ti,tas5827: 47-W Stereo, Digital Input, High Efficiency Closed-Loop
|
||||
Class-D Amplifier with Class-H Algorithm
|
||||
|
||||
ti,tas5828: 50-W Stereo, Digital Input, High Efficiency Closed-Loop
|
||||
Class-D Amplifier with Hybrid-Pro Algorithm
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
@@ -80,8 +92,11 @@ properties:
|
||||
- ti,tas2563
|
||||
- ti,tas2570
|
||||
- ti,tas2572
|
||||
- ti,tas5802
|
||||
- ti,tas5815
|
||||
- ti,tas5825
|
||||
- ti,tas5827
|
||||
- ti,tas5828
|
||||
- const: ti,tas2781
|
||||
- enum:
|
||||
- ti,tas2781
|
||||
@@ -177,12 +192,28 @@ allOf:
|
||||
minimum: 0x38
|
||||
maximum: 0x3f
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- ti,tas5802
|
||||
- ti,tas5815
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
maxItems: 4
|
||||
items:
|
||||
minimum: 0x54
|
||||
maximum: 0x57
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- ti,tas5827
|
||||
- ti,tas5828
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
|
||||
@@ -14,9 +14,14 @@ allOf:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- cdns,spi-r1p6
|
||||
- xlnx,zynq-spi-r1p6
|
||||
oneOf:
|
||||
- enum:
|
||||
- xlnx,zynq-spi-r1p6
|
||||
- items:
|
||||
- enum:
|
||||
- xlnx,zynqmp-spi-r1p6
|
||||
- xlnx,versal-net-spi-r1p6
|
||||
- const: cdns,spi-r1p6
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
@@ -34,6 +34,7 @@ properties:
|
||||
- rockchip,rk3328-spi
|
||||
- rockchip,rk3368-spi
|
||||
- rockchip,rk3399-spi
|
||||
- rockchip,rk3506-spi
|
||||
- rockchip,rk3528-spi
|
||||
- rockchip,rk3562-spi
|
||||
- rockchip,rk3568-spi
|
||||
|
||||
@@ -15,6 +15,7 @@ select:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,kaanapali-ufshc
|
||||
- qcom,sm8650-ufshc
|
||||
- qcom,sm8750-ufshc
|
||||
required:
|
||||
@@ -24,6 +25,7 @@ properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- qcom,kaanapali-ufshc
|
||||
- qcom,sm8650-ufshc
|
||||
- qcom,sm8750-ufshc
|
||||
- const: qcom,ufshc
|
||||
|
||||
@@ -76,6 +76,7 @@ required:
|
||||
|
||||
allOf:
|
||||
- $ref: usb-switch.yaml#
|
||||
- $ref: usb-switch-ports.yaml#
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
|
||||
@@ -89,13 +89,21 @@ required:
|
||||
- reg
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
- dma-ranges
|
||||
- ranges
|
||||
- clocks
|
||||
- clock-names
|
||||
- interrupts
|
||||
- power-domains
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
const: fsl,imx8mp-dwc3
|
||||
then:
|
||||
required:
|
||||
- dma-ranges
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
|
||||
@@ -52,6 +52,7 @@ required:
|
||||
|
||||
allOf:
|
||||
- $ref: usb-switch.yaml#
|
||||
- $ref: usb-switch-ports.yaml#
|
||||
- if:
|
||||
required:
|
||||
- mode-switch
|
||||
|
||||
@@ -46,6 +46,7 @@ required:
|
||||
|
||||
allOf:
|
||||
- $ref: usb-switch.yaml#
|
||||
- $ref: usb-switch-ports.yaml#
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
|
||||
@@ -91,6 +91,7 @@ required:
|
||||
|
||||
allOf:
|
||||
- $ref: usb-switch.yaml#
|
||||
- $ref: usb-switch-ports.yaml#
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@ required:
|
||||
|
||||
allOf:
|
||||
- $ref: usb-switch.yaml#
|
||||
- $ref: usb-switch-ports.yaml#
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ properties:
|
||||
- qcom,sm8550-dwc3
|
||||
- qcom,sm8650-dwc3
|
||||
- qcom,x1e80100-dwc3
|
||||
- qcom,x1e80100-dwc3-mp
|
||||
- const: qcom,snps-dwc3
|
||||
|
||||
reg:
|
||||
@@ -460,8 +461,10 @@ allOf:
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 4
|
||||
maxItems: 5
|
||||
interrupt-names:
|
||||
minItems: 4
|
||||
items:
|
||||
- const: dwc_usb3
|
||||
- const: pwr_event
|
||||
|
||||
@@ -60,6 +60,7 @@ required:
|
||||
|
||||
allOf:
|
||||
- $ref: usb-switch.yaml#
|
||||
- $ref: usb-switch-ports.yaml#
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ maintainers:
|
||||
|
||||
allOf:
|
||||
- $ref: usb-switch.yaml#
|
||||
- $ref: usb-switch-ports.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
|
||||
68
Documentation/devicetree/bindings/usb/usb-switch-ports.yaml
Normal file
68
Documentation/devicetree/bindings/usb/usb-switch-ports.yaml
Normal file
@@ -0,0 +1,68 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/usb/usb-switch-ports.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: USB Orientation and Mode Switches Ports Graph Properties
|
||||
|
||||
maintainers:
|
||||
- Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
|
||||
description:
|
||||
Ports Graph properties for devices handling USB mode and orientation switching.
|
||||
|
||||
properties:
|
||||
port:
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
description:
|
||||
A port node to link the device to a TypeC controller for the purpose of
|
||||
handling altmode muxing and orientation switching.
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: /schemas/graph.yaml#/$defs/endpoint-base
|
||||
unevaluatedProperties: false
|
||||
properties:
|
||||
data-lanes:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 8
|
||||
uniqueItems: true
|
||||
items:
|
||||
maximum: 8
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description:
|
||||
Super Speed (SS) Output endpoint to the Type-C connector
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
description:
|
||||
Super Speed (SS) Input endpoint from the Super-Speed PHY
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: /schemas/graph.yaml#/$defs/endpoint-base
|
||||
unevaluatedProperties: false
|
||||
properties:
|
||||
data-lanes:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 8
|
||||
uniqueItems: true
|
||||
items:
|
||||
maximum: 8
|
||||
|
||||
oneOf:
|
||||
- required:
|
||||
- port
|
||||
- required:
|
||||
- ports
|
||||
|
||||
additionalProperties: true
|
||||
@@ -25,56 +25,4 @@ properties:
|
||||
description: Possible handler of SuperSpeed signals retiming
|
||||
type: boolean
|
||||
|
||||
port:
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
description:
|
||||
A port node to link the device to a TypeC controller for the purpose of
|
||||
handling altmode muxing and orientation switching.
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: /schemas/graph.yaml#/$defs/endpoint-base
|
||||
unevaluatedProperties: false
|
||||
properties:
|
||||
data-lanes:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 8
|
||||
uniqueItems: true
|
||||
items:
|
||||
maximum: 8
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description:
|
||||
Super Speed (SS) Output endpoint to the Type-C connector
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
description:
|
||||
Super Speed (SS) Input endpoint from the Super-Speed PHY
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: /schemas/graph.yaml#/$defs/endpoint-base
|
||||
unevaluatedProperties: false
|
||||
properties:
|
||||
data-lanes:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 8
|
||||
uniqueItems: true
|
||||
items:
|
||||
maximum: 8
|
||||
|
||||
oneOf:
|
||||
- required:
|
||||
- port
|
||||
- required:
|
||||
- ports
|
||||
|
||||
additionalProperties: true
|
||||
|
||||
@@ -183,10 +183,10 @@ in the place where the name normally goes. The structure is
|
||||
- det_checksum
|
||||
- Directory leaf block checksum.
|
||||
|
||||
The leaf directory block checksum is calculated against the FS UUID, the
|
||||
directory's inode number, the directory's inode generation number, and
|
||||
the entire directory entry block up to (but not including) the fake
|
||||
directory entry.
|
||||
The leaf directory block checksum is calculated against the FS UUID (or
|
||||
the checksum seed, if that feature is enabled for the fs), the directory's
|
||||
inode number, the directory's inode generation number, and the entire
|
||||
directory entry block up to (but not including) the fake directory entry.
|
||||
|
||||
Hash Tree Directories
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -196,12 +196,12 @@ new feature was added to ext3 to provide a faster (but peculiar)
|
||||
balanced tree keyed off a hash of the directory entry name. If the
|
||||
EXT4_INDEX_FL (0x1000) flag is set in the inode, this directory uses a
|
||||
hashed btree (htree) to organize and find directory entries. For
|
||||
backwards read-only compatibility with ext2, this tree is actually
|
||||
hidden inside the directory file, masquerading as “empty” directory data
|
||||
blocks! It was stated previously that the end of the linear directory
|
||||
entry table was signified with an entry pointing to inode 0; this is
|
||||
(ab)used to fool the old linear-scan algorithm into thinking that the
|
||||
rest of the directory block is empty so that it moves on.
|
||||
backwards read-only compatibility with ext2, interior tree nodes are actually
|
||||
hidden inside the directory file, masquerading as “empty” directory entries
|
||||
spanning the whole block. It was stated previously that directory entries
|
||||
with the inode set to 0 are treated as unused entries; this is (ab)used to
|
||||
fool the old linear-scan algorithm into skipping over those blocks containing
|
||||
the interior tree node data.
|
||||
|
||||
The root of the tree always lives in the first data block of the
|
||||
directory. By ext2 custom, the '.' and '..' entries must appear at the
|
||||
@@ -209,24 +209,24 @@ beginning of this first block, so they are put here as two
|
||||
``struct ext4_dir_entry_2`` s and not stored in the tree. The rest of
|
||||
the root node contains metadata about the tree and finally a hash->block
|
||||
map to find nodes that are lower in the htree. If
|
||||
``dx_root.info.indirect_levels`` is non-zero then the htree has two
|
||||
levels; the data block pointed to by the root node's map is an interior
|
||||
node, which is indexed by a minor hash. Interior nodes in this tree
|
||||
contains a zeroed out ``struct ext4_dir_entry_2`` followed by a
|
||||
minor_hash->block map to find leafe nodes. Leaf nodes contain a linear
|
||||
array of all ``struct ext4_dir_entry_2``; all of these entries
|
||||
(presumably) hash to the same value. If there is an overflow, the
|
||||
entries simply overflow into the next leaf node, and the
|
||||
least-significant bit of the hash (in the interior node map) that gets
|
||||
us to this next leaf node is set.
|
||||
``dx_root.info.indirect_levels`` is non-zero then the htree has that many
|
||||
levels and the blocks pointed to by the root node's map are interior nodes.
|
||||
These interior nodes have a zeroed out ``struct ext4_dir_entry_2`` followed by
|
||||
a hash->block map to find nodes of the next level. Leaf nodes look like
|
||||
classic linear directory blocks, but all of its entries have a hash value
|
||||
equal or greater than the indicated hash of the parent node.
|
||||
|
||||
To traverse the directory as a htree, the code calculates the hash of
|
||||
the desired file name and uses it to find the corresponding block
|
||||
number. If the tree is flat, the block is a linear array of directory
|
||||
entries that can be searched; otherwise, the minor hash of the file name
|
||||
is computed and used against this second block to find the corresponding
|
||||
third block number. That third block number will be a linear array of
|
||||
directory entries.
|
||||
The actual hash value for an entry name is only 31 bits, the least-significant
|
||||
bit is set to 0. However, if there is a hash collision between directory
|
||||
entries, the least-significant bit may get set to 1 on interior nodes in the
|
||||
case where these two (or more) hash-colliding entries do not fit into one leaf
|
||||
node and must be split across multiple nodes.
|
||||
|
||||
To look up a name in such a htree, the code calculates the hash of the desired
|
||||
file name and uses it to find the leaf node with the range of hash values the
|
||||
calculated hash falls into (in other words, a lookup works basically the same
|
||||
as it would in a B-Tree keyed by the hash value), and possibly also scanning
|
||||
the leaf nodes that follow (in tree order) in case of hash collisions.
|
||||
|
||||
To traverse the directory as a linear array (such as the old code does),
|
||||
the code simply reads every data block in the directory. The blocks used
|
||||
@@ -319,7 +319,8 @@ of a data block:
|
||||
* - 0x24
|
||||
- __le32
|
||||
- block
|
||||
- The block number (within the directory file) that goes with hash=0.
|
||||
- The block number (within the directory file) that lead to the left-most
|
||||
leaf node, i.e. the leaf containing entries with the lowest hash values.
|
||||
* - 0x28
|
||||
- struct dx_entry
|
||||
- entries[0]
|
||||
@@ -442,7 +443,7 @@ The dx_tail structure is 8 bytes long and looks like this:
|
||||
* - 0x0
|
||||
- u32
|
||||
- dt_reserved
|
||||
- Zero.
|
||||
- Unused (but still part of the checksum curiously).
|
||||
* - 0x4
|
||||
- __le32
|
||||
- dt_checksum
|
||||
@@ -450,4 +451,4 @@ The dx_tail structure is 8 bytes long and looks like this:
|
||||
|
||||
The checksum is calculated against the FS UUID, the htree index header
|
||||
(dx_root or dx_node), all of the htree indices (dx_entry) that are in
|
||||
use, and the tail block (dx_tail).
|
||||
use, and the tail block (dx_tail) with the dt_checksum initially set to 0.
|
||||
|
||||
@@ -11,6 +11,7 @@ found on https://linux-ax25.in-berlin.de.
|
||||
|
||||
There is a mailing list for discussing Linux amateur radio matters
|
||||
called linux-hams@vger.kernel.org. To subscribe to it, send a message to
|
||||
majordomo@vger.kernel.org with the words "subscribe linux-hams" in the body
|
||||
of the message, the subject field is ignored. You don't need to be
|
||||
subscribed to post but of course that means you might miss an answer.
|
||||
linux-hams+subscribe@vger.kernel.org or use the web interface at
|
||||
https://vger.kernel.org. The subject and body of the message are
|
||||
ignored. You don't need to be subscribed to post but of course that
|
||||
means you might miss an answer.
|
||||
|
||||
@@ -1398,10 +1398,9 @@ second bit timing has to be specified in order to enable the CAN FD bitrate.
|
||||
Additionally CAN FD capable CAN controllers support up to 64 bytes of
|
||||
payload. The representation of this length in can_frame.len and
|
||||
canfd_frame.len for userspace applications and inside the Linux network
|
||||
layer is a plain value from 0 .. 64 instead of the CAN 'data length code'.
|
||||
The data length code was a 1:1 mapping to the payload length in the Classical
|
||||
CAN frames anyway. The payload length to the bus-relevant DLC mapping is
|
||||
only performed inside the CAN drivers, preferably with the helper
|
||||
layer is a plain value from 0 .. 64 instead of the Classical CAN length
|
||||
which ranges from 0 to 8. The payload length to the bus-relevant DLC mapping
|
||||
is only performed inside the CAN drivers, preferably with the helper
|
||||
functions can_fd_dlc2len() and can_fd_len2dlc().
|
||||
|
||||
The CAN netdevice driver capabilities can be distinguished by the network
|
||||
@@ -1465,6 +1464,70 @@ Example when 'fd-non-iso on' is added on this switchable CAN FD adapter::
|
||||
can <FD,FD-NON-ISO> state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
|
||||
|
||||
|
||||
Transmitter Delay Compensation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
At high bit rates, the propagation delay from the TX pin to the RX pin of
|
||||
the transceiver might become greater than the actual bit time causing
|
||||
measurement errors: the RX pin would still be measuring the previous bit.
|
||||
|
||||
The Transmitter Delay Compensation (thereafter, TDC) resolves this problem
|
||||
by introducing a Secondary Sample Point (SSP) equal to the distance, in
|
||||
minimum time quantum, from the start of the bit time on the TX pin to the
|
||||
actual measurement on the RX pin. The SSP is calculated as the sum of two
|
||||
configurable values: the TDC Value (TDCV) and the TDC offset (TDCO).
|
||||
|
||||
TDC, if supported by the device, can be configured together with CAN-FD
|
||||
using the ip tool's "tdc-mode" argument as follow:
|
||||
|
||||
**omitted**
|
||||
When no "tdc-mode" option is provided, the kernel will automatically
|
||||
decide whether TDC should be turned on, in which case it will
|
||||
calculate a default TDCO and use the TDCV as measured by the
|
||||
device. This is the recommended method to use TDC.
|
||||
|
||||
**"tdc-mode off"**
|
||||
TDC is explicitly disabled.
|
||||
|
||||
**"tdc-mode auto"**
|
||||
The user must provide the "tdco" argument. The TDCV will be
|
||||
automatically calculated by the device. This option is only
|
||||
available if the device supports the TDC-AUTO CAN controller mode.
|
||||
|
||||
**"tdc-mode manual"**
|
||||
The user must provide both the "tdco" and "tdcv" arguments. This
|
||||
option is only available if the device supports the TDC-MANUAL CAN
|
||||
controller mode.
|
||||
|
||||
Note that some devices may offer an additional parameter: "tdcf" (TDC Filter
|
||||
window). If supported by your device, this can be added as an optional
|
||||
argument to either "tdc-mode auto" or "tdc-mode manual".
|
||||
|
||||
Example configuring a 500 kbit/s arbitration bitrate, a 5 Mbit/s data
|
||||
bitrate, a TDCO of 15 minimum time quantum and a TDCV automatically measured
|
||||
by the device::
|
||||
|
||||
$ ip link set can0 up type can bitrate 500000 \
|
||||
fd on dbitrate 4000000 \
|
||||
tdc-mode auto tdco 15
|
||||
$ ip -details link show can0
|
||||
5: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 72 qdisc pfifo_fast state UP \
|
||||
mode DEFAULT group default qlen 10
|
||||
link/can promiscuity 0 allmulti 0 minmtu 72 maxmtu 72
|
||||
can <FD,TDC-AUTO> state ERROR-ACTIVE restart-ms 0
|
||||
bitrate 500000 sample-point 0.875
|
||||
tq 12 prop-seg 69 phase-seg1 70 phase-seg2 20 sjw 10 brp 1
|
||||
ES582.1/ES584.1: tseg1 2..256 tseg2 2..128 sjw 1..128 brp 1..512 \
|
||||
brp_inc 1
|
||||
dbitrate 4000000 dsample-point 0.750
|
||||
dtq 12 dprop-seg 7 dphase-seg1 7 dphase-seg2 5 dsjw 2 dbrp 1
|
||||
tdco 15 tdcf 0
|
||||
ES582.1/ES584.1: dtseg1 2..32 dtseg2 1..16 dsjw 1..8 dbrp 1..32 \
|
||||
dbrp_inc 1
|
||||
tdco 0..127 tdcf 0..127
|
||||
clock 80000000
|
||||
|
||||
|
||||
Supported CAN Hardware
|
||||
----------------------
|
||||
|
||||
|
||||
@@ -137,16 +137,20 @@ d. Checksum offload header v5
|
||||
|
||||
Checksum offload header fields are in big endian format.
|
||||
|
||||
Packet format::
|
||||
|
||||
Bit 0 - 6 7 8-15 16-31
|
||||
Function Header Type Next Header Checksum Valid Reserved
|
||||
|
||||
Header Type is to indicate the type of header, this usually is set to CHECKSUM
|
||||
|
||||
Header types
|
||||
= ==========================================
|
||||
|
||||
= ===============
|
||||
0 Reserved
|
||||
1 Reserved
|
||||
2 checksum header
|
||||
= ===============
|
||||
|
||||
Checksum Valid is to indicate whether the header checksum is valid. Value of 1
|
||||
implies that checksum is calculated on this packet and is valid, value of 0
|
||||
@@ -183,9 +187,11 @@ rmnet in a single linear skb. rmnet will process the individual
|
||||
packets and either ACK the MAP command or deliver the IP packet to the
|
||||
network stack as needed
|
||||
|
||||
MAP header|IP Packet|Optional padding|MAP header|IP Packet|Optional padding....
|
||||
Packet format::
|
||||
|
||||
MAP header|IP Packet|Optional padding|MAP header|Command Packet|Optional pad...
|
||||
MAP header|IP Packet|Optional padding|MAP header|IP Packet|Optional padding....
|
||||
|
||||
MAP header|IP Packet|Optional padding|MAP header|Command Packet|Optional pad...
|
||||
|
||||
3. Userspace configuration
|
||||
==========================
|
||||
|
||||
@@ -96,9 +96,8 @@ needed to these network configuration daemons to make sure that an IP is
|
||||
received only on the 'failover' device.
|
||||
|
||||
Below is the patch snippet used with 'cloud-ifupdown-helper' script found on
|
||||
Debian cloud images:
|
||||
Debian cloud images::
|
||||
|
||||
::
|
||||
@@ -27,6 +27,8 @@ do_setup() {
|
||||
local working="$cfgdir/.$INTERFACE"
|
||||
local final="$cfgdir/$INTERFACE"
|
||||
@@ -172,9 +171,8 @@ appropriate FDB entry is added.
|
||||
|
||||
The following script is executed on the destination hypervisor once migration
|
||||
completes, and it reattaches the VF to the VM and brings down the virtio-net
|
||||
interface.
|
||||
interface::
|
||||
|
||||
::
|
||||
# reattach-vf.sh
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
@@ -25,6 +25,9 @@ seg6_require_hmac - INTEGER
|
||||
|
||||
Default is 0.
|
||||
|
||||
/proc/sys/net/ipv6/seg6_* variables:
|
||||
====================================
|
||||
|
||||
seg6_flowlabel - INTEGER
|
||||
Controls the behaviour of computing the flowlabel of outer
|
||||
IPv6 header in case of SR T.encaps
|
||||
|
||||
@@ -38,6 +38,81 @@ Like ``clang-format`` for the rest of the kernel, ``rustfmt`` works on
|
||||
individual files, and does not require a kernel configuration. Sometimes it may
|
||||
even work with broken code.
|
||||
|
||||
Imports
|
||||
~~~~~~~
|
||||
|
||||
``rustfmt``, by default, formats imports in a way that is prone to conflicts
|
||||
while merging and rebasing, since in some cases it condenses several items into
|
||||
the same line. For instance:
|
||||
|
||||
.. code-block:: rust
|
||||
|
||||
// Do not use this style.
|
||||
use crate::{
|
||||
example1,
|
||||
example2::{example3, example4, example5},
|
||||
example6, example7,
|
||||
example8::example9,
|
||||
};
|
||||
|
||||
Instead, the kernel uses a vertical layout that looks like this:
|
||||
|
||||
.. code-block:: rust
|
||||
|
||||
use crate::{
|
||||
example1,
|
||||
example2::{
|
||||
example3,
|
||||
example4,
|
||||
example5, //
|
||||
},
|
||||
example6,
|
||||
example7,
|
||||
example8::example9, //
|
||||
};
|
||||
|
||||
That is, each item goes into its own line, and braces are used as soon as there
|
||||
is more than one item in a list.
|
||||
|
||||
The trailing empty comment allows to preserve this formatting. Not only that,
|
||||
``rustfmt`` will actually reformat imports vertically when the empty comment is
|
||||
added. That is, it is possible to easily reformat the original example into the
|
||||
expected style by running ``rustfmt`` on an input like:
|
||||
|
||||
.. code-block:: rust
|
||||
|
||||
// Do not use this style.
|
||||
use crate::{
|
||||
example1,
|
||||
example2::{example3, example4, example5, //
|
||||
},
|
||||
example6, example7,
|
||||
example8::example9, //
|
||||
};
|
||||
|
||||
The trailing empty comment works for nested imports, as shown above, as well as
|
||||
for single item imports -- this can be useful to minimize diffs within patch
|
||||
series:
|
||||
|
||||
.. code-block:: rust
|
||||
|
||||
use crate::{
|
||||
example1, //
|
||||
};
|
||||
|
||||
The trailing empty comment works in any of the lines within the braces, but it
|
||||
is preferred to keep it in the last item, since it is reminiscent of the
|
||||
trailing comma in other formatters. Sometimes it may be simpler to avoid moving
|
||||
the comment several times within a patch series due to changes in the list.
|
||||
|
||||
There may be cases where exceptions may need to be made, i.e. none of this is
|
||||
a hard rule. There is also code that is not migrated to this style yet, but
|
||||
please do not introduce code in other styles.
|
||||
|
||||
Eventually, the goal is to get ``rustfmt`` to support this formatting style (or
|
||||
a similar one) automatically in a stable release without requiring the trailing
|
||||
empty comment. Thus, at some point, the goal is to remove those comments.
|
||||
|
||||
|
||||
Comments
|
||||
--------
|
||||
|
||||
@@ -1229,6 +1229,9 @@ It is not possible to read back a pending external abort (injected via
|
||||
KVM_SET_VCPU_EVENTS or otherwise) because such an exception is always delivered
|
||||
directly to the virtual CPU).
|
||||
|
||||
Calling this ioctl on a vCPU that hasn't been initialized will return
|
||||
-ENOEXEC.
|
||||
|
||||
::
|
||||
|
||||
struct kvm_vcpu_events {
|
||||
@@ -1309,6 +1312,8 @@ exceptions by manipulating individual registers using the KVM_SET_ONE_REG API.
|
||||
|
||||
See KVM_GET_VCPU_EVENTS for the data structure.
|
||||
|
||||
Calling this ioctl on a vCPU that hasn't been initialized will return
|
||||
-ENOEXEC.
|
||||
|
||||
4.33 KVM_GET_DEBUGREGS
|
||||
----------------------
|
||||
@@ -6432,9 +6437,18 @@ most one mapping per page, i.e. binding multiple memory regions to a single
|
||||
guest_memfd range is not allowed (any number of memory regions can be bound to
|
||||
a single guest_memfd file, but the bound ranges must not overlap).
|
||||
|
||||
When the capability KVM_CAP_GUEST_MEMFD_MMAP is supported, the 'flags' field
|
||||
supports GUEST_MEMFD_FLAG_MMAP. Setting this flag on guest_memfd creation
|
||||
enables mmap() and faulting of guest_memfd memory to host userspace.
|
||||
The capability KVM_CAP_GUEST_MEMFD_FLAGS enumerates the `flags` that can be
|
||||
specified via KVM_CREATE_GUEST_MEMFD. Currently defined flags:
|
||||
|
||||
============================ ================================================
|
||||
GUEST_MEMFD_FLAG_MMAP Enable using mmap() on the guest_memfd file
|
||||
descriptor.
|
||||
GUEST_MEMFD_FLAG_INIT_SHARED Make all memory in the file shared during
|
||||
KVM_CREATE_GUEST_MEMFD (memory files created
|
||||
without INIT_SHARED will be marked private).
|
||||
Shared memory can be faulted into host userspace
|
||||
page tables. Private memory cannot.
|
||||
============================ ================================================
|
||||
|
||||
When the KVM MMU performs a PFN lookup to service a guest fault and the backing
|
||||
guest_memfd has the GUEST_MEMFD_FLAG_MMAP set, then the fault will always be
|
||||
|
||||
@@ -13,7 +13,8 @@ will act as the VM interrupt controller, requiring emulated user-space devices
|
||||
to inject interrupts to the VGIC instead of directly to CPUs. It is not
|
||||
possible to create both a GICv3 and GICv2 on the same VM.
|
||||
|
||||
Creating a guest GICv3 device requires a host GICv3 as well.
|
||||
Creating a guest GICv3 device requires a host GICv3 host, or a GICv5 host with
|
||||
support for FEAT_GCIE_LEGACY.
|
||||
|
||||
|
||||
Groups:
|
||||
|
||||
30
MAINTAINERS
30
MAINTAINERS
@@ -1997,6 +1997,10 @@ F: include/uapi/linux/if_arcnet.h
|
||||
|
||||
ARM AND ARM64 SoC SUB-ARCHITECTURES (COMMON PARTS)
|
||||
M: Arnd Bergmann <arnd@arndb.de>
|
||||
M: Krzysztof Kozlowski <krzk@kernel.org>
|
||||
M: Alexandre Belloni <alexandre.belloni@bootlin.com>
|
||||
M: Linus Walleij <linus.walleij@linaro.org>
|
||||
R: Drew Fustini <fustini@kernel.org>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
L: soc@lists.linux.dev
|
||||
S: Maintained
|
||||
@@ -3841,6 +3845,7 @@ F: drivers/hwmon/asus-ec-sensors.c
|
||||
ASUS NOTEBOOKS AND EEEPC ACPI/WMI EXTRAS DRIVERS
|
||||
M: Corentin Chary <corentin.chary@gmail.com>
|
||||
M: Luke D. Jones <luke@ljones.dev>
|
||||
M: Denis Benato <benato.denis96@gmail.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://asus-linux.org/
|
||||
@@ -4804,6 +4809,7 @@ F: drivers/net/ethernet/broadcom/b44.*
|
||||
|
||||
BROADCOM B53/SF2 ETHERNET SWITCH DRIVER
|
||||
M: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
M: Jonas Gorski <jonas.gorski@gmail.com>
|
||||
L: netdev@vger.kernel.org
|
||||
L: openwrt-devel@lists.openwrt.org (subscribers-only)
|
||||
S: Supported
|
||||
@@ -13110,6 +13116,15 @@ F: include/uapi/linux/io_uring.h
|
||||
F: include/uapi/linux/io_uring/
|
||||
F: io_uring/
|
||||
|
||||
IO_URING ZCRX
|
||||
M: Pavel Begunkov <asml.silence@gmail.com>
|
||||
L: io-uring@vger.kernel.org
|
||||
L: netdev@vger.kernel.org
|
||||
T: git https://github.com/isilence/linux.git zcrx/for-next
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux.git
|
||||
S: Maintained
|
||||
F: io_uring/zcrx.*
|
||||
|
||||
IPMI SUBSYSTEM
|
||||
M: Corey Minyard <corey@minyard.net>
|
||||
L: openipmi-developer@lists.sourceforge.net (moderated for non-subscribers)
|
||||
@@ -14393,6 +14408,7 @@ F: tools/memory-model/
|
||||
|
||||
LINUX-NEXT TREE
|
||||
M: Stephen Rothwell <sfr@canb.auug.org.au>
|
||||
M: Mark Brown <broonie@kernel.org>
|
||||
L: linux-next@vger.kernel.org
|
||||
S: Supported
|
||||
B: mailto:linux-next@vger.kernel.org and the appropriate development tree
|
||||
@@ -18013,6 +18029,16 @@ X: net/rfkill/
|
||||
X: net/wireless/
|
||||
X: tools/testing/selftests/net/can/
|
||||
|
||||
NETWORKING [IOAM]
|
||||
M: Justin Iurman <justin.iurman@uliege.be>
|
||||
S: Maintained
|
||||
F: Documentation/networking/ioam6*
|
||||
F: include/linux/ioam6*
|
||||
F: include/net/ioam6*
|
||||
F: include/uapi/linux/ioam6*
|
||||
F: net/ipv6/ioam6*
|
||||
F: tools/testing/selftests/net/ioam6*
|
||||
|
||||
NETWORKING [IPSEC]
|
||||
M: Steffen Klassert <steffen.klassert@secunet.com>
|
||||
M: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
@@ -26874,7 +26900,7 @@ S: Maintained
|
||||
F: drivers/vfio/cdx/*
|
||||
|
||||
VFIO DRIVER
|
||||
M: Alex Williamson <alex.williamson@redhat.com>
|
||||
M: Alex Williamson <alex@shazbot.org>
|
||||
L: kvm@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git https://github.com/awilliam/linux-vfio.git
|
||||
@@ -27037,7 +27063,7 @@ T: git git://linuxtv.org/media.git
|
||||
F: drivers/media/test-drivers/vimc/*
|
||||
|
||||
VIRT LIB
|
||||
M: Alex Williamson <alex.williamson@redhat.com>
|
||||
M: Alex Williamson <alex@shazbot.org>
|
||||
M: Paolo Bonzini <pbonzini@redhat.com>
|
||||
L: kvm@vger.kernel.org
|
||||
S: Supported
|
||||
|
||||
2
Makefile
2
Makefile
@@ -2,7 +2,7 @@
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 18
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc1
|
||||
EXTRAVERSION = -rc3
|
||||
NAME = Baby Opossum Posse
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
||||
@@ -965,6 +965,7 @@ config HAVE_CFI_ICALL_NORMALIZE_INTEGERS_RUSTC
|
||||
def_bool y
|
||||
depends on HAVE_CFI_ICALL_NORMALIZE_INTEGERS
|
||||
depends on RUSTC_VERSION >= 107900
|
||||
depends on ARM64 || X86_64
|
||||
# With GCOV/KASAN we need this fix: https://github.com/rust-lang/rust/pull/129373
|
||||
depends on (RUSTC_LLVM_VERSION >= 190103 && RUSTC_VERSION >= 108200) || \
|
||||
(!GCOV_KERNEL && !KASAN_GENERIC && !KASAN_SW_TAGS)
|
||||
|
||||
@@ -88,7 +88,7 @@ CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
CONFIG_MMC_DW=y
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_NTFS_FS=y
|
||||
|
||||
@@ -86,7 +86,7 @@ CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
CONFIG_MMC_DW=y
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_NTFS_FS=y
|
||||
|
||||
@@ -88,7 +88,7 @@ CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
CONFIG_MMC_DW=y
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_NTFS_FS=y
|
||||
|
||||
@@ -77,7 +77,7 @@ CONFIG_DMADEVICES=y
|
||||
CONFIG_DW_AXI_DMAC=y
|
||||
CONFIG_IIO=y
|
||||
CONFIG_TI_ADC108S102=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_NFS_FS=y
|
||||
|
||||
@@ -74,7 +74,7 @@ CONFIG_USB_OHCI_HCD_PLATFORM=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_SERIAL=y
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
|
||||
@@ -81,7 +81,7 @@ CONFIG_MMC_DW=y
|
||||
CONFIG_UIO=y
|
||||
CONFIG_UIO_PDRV_GENIRQ=y
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_NTFS_FS=y
|
||||
|
||||
@@ -77,6 +77,14 @@
|
||||
/delete-property/ pinctrl-0;
|
||||
};
|
||||
|
||||
&pm {
|
||||
clocks = <&firmware_clocks 5>,
|
||||
<&clocks BCM2835_CLOCK_PERI_IMAGE>,
|
||||
<&clocks BCM2835_CLOCK_H264>,
|
||||
<&clocks BCM2835_CLOCK_ISP>;
|
||||
clock-names = "v3d", "peri_image", "h264", "isp";
|
||||
};
|
||||
|
||||
&rmem {
|
||||
/*
|
||||
* RPi4's co-processor will copy the board's bootloader configuration
|
||||
|
||||
@@ -13,7 +13,16 @@
|
||||
clock-names = "pixel", "hdmi";
|
||||
};
|
||||
|
||||
&pm {
|
||||
clocks = <&firmware_clocks 5>,
|
||||
<&clocks BCM2835_CLOCK_PERI_IMAGE>,
|
||||
<&clocks BCM2835_CLOCK_H264>,
|
||||
<&clocks BCM2835_CLOCK_ISP>;
|
||||
clock-names = "v3d", "peri_image", "h264", "isp";
|
||||
};
|
||||
|
||||
&v3d {
|
||||
clocks = <&firmware_clocks 5>;
|
||||
power-domains = <&power RPI_POWER_DOMAIN_V3D>;
|
||||
};
|
||||
|
||||
|
||||
@@ -194,8 +194,7 @@ CONFIG_MAILBOX=y
|
||||
CONFIG_PL320_MBOX=y
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_AUTOFS_FS=y
|
||||
CONFIG_FUSE_FS=y
|
||||
|
||||
@@ -154,8 +154,8 @@ CONFIG_PWM_BCM2835=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT2_FS_XATTR=y
|
||||
CONFIG_EXT2_FS_POSIX_ACL=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT3_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_FANOTIFY=y
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
|
||||
@@ -228,7 +228,7 @@ CONFIG_PWM=y
|
||||
CONFIG_PWM_TIECAP=m
|
||||
CONFIG_PWM_TIEHRPWM=m
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_XFS_FS=m
|
||||
CONFIG_AUTOFS_FS=m
|
||||
|
||||
@@ -95,8 +95,8 @@ CONFIG_RTC_DRV_MV=y
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_MV_XOR=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
# CONFIG_EXT3_FS_XATTR is not set
|
||||
CONFIG_EXT4_FS=y
|
||||
# CONFIG_EXT4_FS_XATTR is not set
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_ISO9660_FS=y
|
||||
CONFIG_JOLIET=y
|
||||
|
||||
@@ -103,8 +103,8 @@ CONFIG_RTC_DRV_EP93XX=y
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_EP93XX_DMA=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
# CONFIG_EXT3_FS_XATTR is not set
|
||||
CONFIG_EXT4_FS=y
|
||||
# CONFIG_EXT4_FS_XATTR is not set
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
|
||||
@@ -436,9 +436,9 @@ CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT2_FS_XATTR=y
|
||||
CONFIG_EXT2_FS_POSIX_ACL=y
|
||||
CONFIG_EXT2_FS_SECURITY=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT3_FS_POSIX_ACL=y
|
||||
CONFIG_EXT3_FS_SECURITY=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_QUOTA=y
|
||||
CONFIG_QUOTA_NETLINK_INTERFACE=y
|
||||
CONFIG_AUTOFS_FS=y
|
||||
|
||||
@@ -158,8 +158,8 @@ CONFIG_IXP4XX_NPE=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT2_FS_XATTR=y
|
||||
CONFIG_EXT2_FS_POSIX_ACL=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT3_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_OVERLAY_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
|
||||
@@ -53,7 +53,7 @@ CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_MAX8925=y
|
||||
# CONFIG_RESET_CONTROLLER is not set
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
# CONFIG_DNOTIFY is not set
|
||||
CONFIG_MSDOS_FS=y
|
||||
|
||||
@@ -113,7 +113,7 @@ CONFIG_RTC_DRV_MOXART=y
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_MOXART_DMA=y
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_CONFIGFS_FS=y
|
||||
CONFIG_JFFS2_FS=y
|
||||
|
||||
@@ -268,7 +268,7 @@ CONFIG_PWM_ATMEL=m
|
||||
CONFIG_PWM_ATMEL_HLCDC_PWM=m
|
||||
CONFIG_PWM_ATMEL_TCB=m
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_ISO9660_FS=m
|
||||
CONFIG_JOLIET=y
|
||||
CONFIG_UDF_FS=m
|
||||
|
||||
@@ -91,8 +91,8 @@ CONFIG_RTC_DRV_DS1307=y
|
||||
CONFIG_RTC_DRV_RS5C372=y
|
||||
CONFIG_RTC_DRV_M41T80=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
# CONFIG_EXT3_FS_XATTR is not set
|
||||
CONFIG_EXT4_FS=y
|
||||
# CONFIG_EXT4_FS_XATTR is not set
|
||||
CONFIG_EXT4_FS=m
|
||||
CONFIG_ISO9660_FS=m
|
||||
CONFIG_JOLIET=y
|
||||
|
||||
@@ -168,7 +168,7 @@ CONFIG_MV_XOR=y
|
||||
CONFIG_STAGING=y
|
||||
CONFIG_FB_XGI=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_ISO9660_FS=m
|
||||
CONFIG_JOLIET=y
|
||||
CONFIG_UDF_FS=m
|
||||
|
||||
@@ -116,7 +116,7 @@ CONFIG_IIO_ST_ACCEL_3AXIS=y
|
||||
CONFIG_PWM=y
|
||||
CONFIG_PWM_STMPE=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_FUSE_FS=y
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
|
||||
@@ -184,7 +184,7 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_OMAP=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
# CONFIG_DNOTIFY is not set
|
||||
CONFIG_AUTOFS_FS=y
|
||||
CONFIG_ISO9660_FS=y
|
||||
|
||||
@@ -679,7 +679,7 @@ CONFIG_TWL4030_USB=m
|
||||
CONFIG_COUNTER=m
|
||||
CONFIG_TI_EQEP=m
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_FANOTIFY=y
|
||||
CONFIG_QUOTA=y
|
||||
|
||||
@@ -115,8 +115,8 @@ CONFIG_RTC_DRV_M48T86=y
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_MV_XOR=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
# CONFIG_EXT3_FS_XATTR is not set
|
||||
CONFIG_EXT4_FS=y
|
||||
# CONFIG_EXT4_FS_XATTR is not set
|
||||
CONFIG_EXT4_FS=m
|
||||
CONFIG_ISO9660_FS=m
|
||||
CONFIG_JOLIET=y
|
||||
|
||||
@@ -579,9 +579,9 @@ CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT2_FS_XATTR=y
|
||||
CONFIG_EXT2_FS_POSIX_ACL=y
|
||||
CONFIG_EXT2_FS_SECURITY=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT3_FS_POSIX_ACL=y
|
||||
CONFIG_EXT3_FS_SECURITY=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_XFS_FS=m
|
||||
CONFIG_AUTOFS_FS=m
|
||||
CONFIG_FUSE_FS=m
|
||||
|
||||
@@ -291,7 +291,7 @@ CONFIG_INTERCONNECT_QCOM_MSM8974=m
|
||||
CONFIG_INTERCONNECT_QCOM_SDX55=m
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT2_FS_XATTR=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_FUSE_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
|
||||
@@ -77,7 +77,7 @@ CONFIG_SOUND_VIDC=m
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_PCF8583=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_AUTOFS_FS=m
|
||||
CONFIG_ISO9660_FS=y
|
||||
CONFIG_JOLIET=y
|
||||
|
||||
@@ -52,9 +52,9 @@ CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_S3C=y
|
||||
CONFIG_PWM=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT3_FS_POSIX_ACL=y
|
||||
CONFIG_EXT3_FS_SECURITY=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_CRAMFS=y
|
||||
|
||||
@@ -201,7 +201,7 @@ CONFIG_MCHP_EIC=y
|
||||
CONFIG_RESET_CONTROLLER=y
|
||||
CONFIG_NVMEM_MICROCHIP_OTPC=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_FANOTIFY=y
|
||||
CONFIG_AUTOFS_FS=m
|
||||
CONFIG_VFAT_FS=y
|
||||
|
||||
@@ -136,7 +136,7 @@ CONFIG_FPGA_REGION=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT2_FS_XATTR=y
|
||||
CONFIG_EXT2_FS_POSIX_ACL=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_AUTOFS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_NTFS_FS=y
|
||||
|
||||
@@ -84,8 +84,8 @@ CONFIG_DMATEST=m
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT2_FS_XATTR=y
|
||||
CONFIG_EXT2_FS_SECURITY=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT3_FS_SECURITY=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_AUTOFS_FS=m
|
||||
CONFIG_FUSE_FS=y
|
||||
CONFIG_MSDOS_FS=m
|
||||
|
||||
@@ -67,8 +67,8 @@ CONFIG_DMATEST=m
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT2_FS_XATTR=y
|
||||
CONFIG_EXT2_FS_SECURITY=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT3_FS_SECURITY=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_AUTOFS_FS=m
|
||||
CONFIG_MSDOS_FS=m
|
||||
CONFIG_VFAT_FS=m
|
||||
|
||||
@@ -53,8 +53,8 @@ CONFIG_DMATEST=m
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT2_FS_XATTR=y
|
||||
CONFIG_EXT2_FS_SECURITY=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT3_FS_SECURITY=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_AUTOFS_FS=m
|
||||
CONFIG_MSDOS_FS=m
|
||||
CONFIG_VFAT_FS=m
|
||||
|
||||
@@ -193,8 +193,8 @@ CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT2_FS_XATTR=y
|
||||
CONFIG_EXT2_FS_POSIX_ACL=y
|
||||
CONFIG_EXT2_FS_SECURITY=y
|
||||
CONFIG_EXT3_FS=y
|
||||
# CONFIG_EXT3_FS_XATTR is not set
|
||||
CONFIG_EXT4_FS=y
|
||||
# CONFIG_EXT4_FS_XATTR is not set
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
|
||||
@@ -69,7 +69,7 @@ CONFIG_STM32_MDMA=y
|
||||
CONFIG_IIO=y
|
||||
CONFIG_STM32_ADC_CORE=y
|
||||
CONFIG_STM32_ADC=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
# CONFIG_FILE_LOCKING is not set
|
||||
# CONFIG_DNOTIFY is not set
|
||||
# CONFIG_INOTIFY_USER is not set
|
||||
|
||||
@@ -319,9 +319,9 @@ CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT2_FS_XATTR=y
|
||||
CONFIG_EXT2_FS_POSIX_ACL=y
|
||||
CONFIG_EXT2_FS_SECURITY=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT3_FS_POSIX_ACL=y
|
||||
CONFIG_EXT3_FS_SECURITY=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
# CONFIG_DNOTIFY is not set
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
|
||||
@@ -175,7 +175,7 @@ CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT2_FS_XATTR=y
|
||||
CONFIG_EXT2_FS_POSIX_ACL=y
|
||||
CONFIG_EXT2_FS_SECURITY=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
|
||||
@@ -120,7 +120,7 @@ CONFIG_VIRTIO_BALLOON=y
|
||||
CONFIG_VIRTIO_MMIO=y
|
||||
CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_JFFS2_FS=y
|
||||
|
||||
@@ -326,6 +326,8 @@
|
||||
<0x7fffe000 0x2000>;
|
||||
interrupt-controller;
|
||||
#address-cells = <0>;
|
||||
interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
|
||||
IRQ_TYPE_LEVEL_HIGH)>;
|
||||
#interrupt-cells = <3>;
|
||||
};
|
||||
|
||||
|
||||
@@ -24,22 +24,48 @@
|
||||
* ID_AA64MMFR4_EL1.E2H0 < 0. On such CPUs HCR_EL2.E2H is RES1, but it
|
||||
* can reset into an UNKNOWN state and might not read as 1 until it has
|
||||
* been initialized explicitly.
|
||||
*
|
||||
* Fruity CPUs seem to have HCR_EL2.E2H set to RAO/WI, but
|
||||
* don't advertise it (they predate this relaxation).
|
||||
*
|
||||
* Initalize HCR_EL2.E2H so that later code can rely upon HCR_EL2.E2H
|
||||
* indicating whether the CPU is running in E2H mode.
|
||||
*/
|
||||
mrs_s x1, SYS_ID_AA64MMFR4_EL1
|
||||
sbfx x1, x1, #ID_AA64MMFR4_EL1_E2H0_SHIFT, #ID_AA64MMFR4_EL1_E2H0_WIDTH
|
||||
cmp x1, #0
|
||||
b.ge .LnVHE_\@
|
||||
b.lt .LnE2H0_\@
|
||||
|
||||
/*
|
||||
* Unfortunately, HCR_EL2.E2H can be RES1 even if not advertised
|
||||
* as such via ID_AA64MMFR4_EL1.E2H0:
|
||||
*
|
||||
* - Fruity CPUs predate the !FEAT_E2H0 relaxation, and seem to
|
||||
* have HCR_EL2.E2H implemented as RAO/WI.
|
||||
*
|
||||
* - On CPUs that lack FEAT_FGT, a hypervisor can't trap guest
|
||||
* reads of ID_AA64MMFR4_EL1 to advertise !FEAT_E2H0. NV
|
||||
* guests on these hosts can write to HCR_EL2.E2H without
|
||||
* trapping to the hypervisor, but these writes have no
|
||||
* functional effect.
|
||||
*
|
||||
* Handle both cases by checking for an essential VHE property
|
||||
* (system register remapping) to decide whether we're
|
||||
* effectively VHE-only or not.
|
||||
*/
|
||||
msr_hcr_el2 x0 // Setup HCR_EL2 as nVHE
|
||||
isb
|
||||
mov x1, #1 // Write something to FAR_EL1
|
||||
msr far_el1, x1
|
||||
isb
|
||||
mov x1, #2 // Try to overwrite it via FAR_EL2
|
||||
msr far_el2, x1
|
||||
isb
|
||||
mrs x1, far_el1 // If we see the latest write in FAR_EL1,
|
||||
cmp x1, #2 // we can safely assume we are VHE only.
|
||||
b.ne .LnVHE_\@ // Otherwise, we know that nVHE works.
|
||||
|
||||
.LnE2H0_\@:
|
||||
orr x0, x0, #HCR_E2H
|
||||
.LnVHE_\@:
|
||||
msr_hcr_el2 x0
|
||||
isb
|
||||
.LnVHE_\@:
|
||||
.endm
|
||||
|
||||
.macro __init_el2_sctlr
|
||||
|
||||
@@ -816,6 +816,11 @@ struct kvm_vcpu_arch {
|
||||
u64 hcrx_el2;
|
||||
u64 mdcr_el2;
|
||||
|
||||
struct {
|
||||
u64 r;
|
||||
u64 w;
|
||||
} fgt[__NR_FGT_GROUP_IDS__];
|
||||
|
||||
/* Exception Information */
|
||||
struct kvm_vcpu_fault_info fault;
|
||||
|
||||
@@ -1600,6 +1605,51 @@ static inline bool kvm_arch_has_irq_bypass(void)
|
||||
void compute_fgu(struct kvm *kvm, enum fgt_group_id fgt);
|
||||
void get_reg_fixed_bits(struct kvm *kvm, enum vcpu_sysreg reg, u64 *res0, u64 *res1);
|
||||
void check_feature_map(void);
|
||||
void kvm_vcpu_load_fgt(struct kvm_vcpu *vcpu);
|
||||
|
||||
static __always_inline enum fgt_group_id __fgt_reg_to_group_id(enum vcpu_sysreg reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case HFGRTR_EL2:
|
||||
case HFGWTR_EL2:
|
||||
return HFGRTR_GROUP;
|
||||
case HFGITR_EL2:
|
||||
return HFGITR_GROUP;
|
||||
case HDFGRTR_EL2:
|
||||
case HDFGWTR_EL2:
|
||||
return HDFGRTR_GROUP;
|
||||
case HAFGRTR_EL2:
|
||||
return HAFGRTR_GROUP;
|
||||
case HFGRTR2_EL2:
|
||||
case HFGWTR2_EL2:
|
||||
return HFGRTR2_GROUP;
|
||||
case HFGITR2_EL2:
|
||||
return HFGITR2_GROUP;
|
||||
case HDFGRTR2_EL2:
|
||||
case HDFGWTR2_EL2:
|
||||
return HDFGRTR2_GROUP;
|
||||
default:
|
||||
BUILD_BUG_ON(1);
|
||||
}
|
||||
}
|
||||
|
||||
#define vcpu_fgt(vcpu, reg) \
|
||||
({ \
|
||||
enum fgt_group_id id = __fgt_reg_to_group_id(reg); \
|
||||
u64 *p; \
|
||||
switch (reg) { \
|
||||
case HFGWTR_EL2: \
|
||||
case HDFGWTR_EL2: \
|
||||
case HFGWTR2_EL2: \
|
||||
case HDFGWTR2_EL2: \
|
||||
p = &(vcpu)->arch.fgt[id].w; \
|
||||
break; \
|
||||
default: \
|
||||
p = &(vcpu)->arch.fgt[id].r; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
p; \
|
||||
})
|
||||
|
||||
#endif /* __ARM64_KVM_HOST_H__ */
|
||||
|
||||
@@ -293,7 +293,8 @@ static inline pmd_t set_pmd_bit(pmd_t pmd, pgprot_t prot)
|
||||
static inline pte_t pte_mkwrite_novma(pte_t pte)
|
||||
{
|
||||
pte = set_pte_bit(pte, __pgprot(PTE_WRITE));
|
||||
pte = clear_pte_bit(pte, __pgprot(PTE_RDONLY));
|
||||
if (pte_sw_dirty(pte))
|
||||
pte = clear_pte_bit(pte, __pgprot(PTE_RDONLY));
|
||||
return pte;
|
||||
}
|
||||
|
||||
|
||||
@@ -1220,10 +1220,19 @@
|
||||
__val; \
|
||||
})
|
||||
|
||||
/*
|
||||
* The "Z" constraint combined with the "%x0" template should be enough
|
||||
* to force XZR generation if (v) is a constant 0 value but LLVM does not
|
||||
* yet understand that modifier/constraint combo so a conditional is required
|
||||
* to nudge the compiler into using XZR as a source for a 0 constant value.
|
||||
*/
|
||||
#define write_sysreg_s(v, r) do { \
|
||||
u64 __val = (u64)(v); \
|
||||
u32 __maybe_unused __check_r = (u32)(r); \
|
||||
asm volatile(__msr_s(r, "%x0") : : "rZ" (__val)); \
|
||||
if (__builtin_constant_p(__val) && __val == 0) \
|
||||
asm volatile(__msr_s(r, "xzr")); \
|
||||
else \
|
||||
asm volatile(__msr_s(r, "%x0") : : "r" (__val)); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
|
||||
@@ -697,6 +697,8 @@ static void noinstr el0_breakpt(struct pt_regs *regs, unsigned long esr)
|
||||
|
||||
static void noinstr el0_softstp(struct pt_regs *regs, unsigned long esr)
|
||||
{
|
||||
bool step_done;
|
||||
|
||||
if (!is_ttbr0_addr(regs->pc))
|
||||
arm64_apply_bp_hardening();
|
||||
|
||||
@@ -707,10 +709,10 @@ static void noinstr el0_softstp(struct pt_regs *regs, unsigned long esr)
|
||||
* If we are stepping a suspended breakpoint there's nothing more to do:
|
||||
* the single-step is complete.
|
||||
*/
|
||||
if (!try_step_suspended_breakpoints(regs)) {
|
||||
local_daif_restore(DAIF_PROCCTX);
|
||||
step_done = try_step_suspended_breakpoints(regs);
|
||||
local_daif_restore(DAIF_PROCCTX);
|
||||
if (!step_done)
|
||||
do_el0_softstep(esr, regs);
|
||||
}
|
||||
arm64_exit_to_user_mode(regs);
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ static int nr_timers(struct kvm_vcpu *vcpu)
|
||||
|
||||
u32 timer_get_ctl(struct arch_timer_context *ctxt)
|
||||
{
|
||||
struct kvm_vcpu *vcpu = ctxt->vcpu;
|
||||
struct kvm_vcpu *vcpu = timer_context_to_vcpu(ctxt);
|
||||
|
||||
switch(arch_timer_ctx_index(ctxt)) {
|
||||
case TIMER_VTIMER:
|
||||
@@ -85,7 +85,7 @@ u32 timer_get_ctl(struct arch_timer_context *ctxt)
|
||||
|
||||
u64 timer_get_cval(struct arch_timer_context *ctxt)
|
||||
{
|
||||
struct kvm_vcpu *vcpu = ctxt->vcpu;
|
||||
struct kvm_vcpu *vcpu = timer_context_to_vcpu(ctxt);
|
||||
|
||||
switch(arch_timer_ctx_index(ctxt)) {
|
||||
case TIMER_VTIMER:
|
||||
@@ -104,7 +104,7 @@ u64 timer_get_cval(struct arch_timer_context *ctxt)
|
||||
|
||||
static void timer_set_ctl(struct arch_timer_context *ctxt, u32 ctl)
|
||||
{
|
||||
struct kvm_vcpu *vcpu = ctxt->vcpu;
|
||||
struct kvm_vcpu *vcpu = timer_context_to_vcpu(ctxt);
|
||||
|
||||
switch(arch_timer_ctx_index(ctxt)) {
|
||||
case TIMER_VTIMER:
|
||||
@@ -126,7 +126,7 @@ static void timer_set_ctl(struct arch_timer_context *ctxt, u32 ctl)
|
||||
|
||||
static void timer_set_cval(struct arch_timer_context *ctxt, u64 cval)
|
||||
{
|
||||
struct kvm_vcpu *vcpu = ctxt->vcpu;
|
||||
struct kvm_vcpu *vcpu = timer_context_to_vcpu(ctxt);
|
||||
|
||||
switch(arch_timer_ctx_index(ctxt)) {
|
||||
case TIMER_VTIMER:
|
||||
@@ -146,16 +146,6 @@ static void timer_set_cval(struct arch_timer_context *ctxt, u64 cval)
|
||||
}
|
||||
}
|
||||
|
||||
static void timer_set_offset(struct arch_timer_context *ctxt, u64 offset)
|
||||
{
|
||||
if (!ctxt->offset.vm_offset) {
|
||||
WARN(offset, "timer %ld\n", arch_timer_ctx_index(ctxt));
|
||||
return;
|
||||
}
|
||||
|
||||
WRITE_ONCE(*ctxt->offset.vm_offset, offset);
|
||||
}
|
||||
|
||||
u64 kvm_phys_timer_read(void)
|
||||
{
|
||||
return timecounter->cc->read(timecounter->cc);
|
||||
@@ -343,7 +333,7 @@ static enum hrtimer_restart kvm_hrtimer_expire(struct hrtimer *hrt)
|
||||
u64 ns;
|
||||
|
||||
ctx = container_of(hrt, struct arch_timer_context, hrtimer);
|
||||
vcpu = ctx->vcpu;
|
||||
vcpu = timer_context_to_vcpu(ctx);
|
||||
|
||||
trace_kvm_timer_hrtimer_expire(ctx);
|
||||
|
||||
@@ -436,8 +426,9 @@ static void kvm_timer_update_status(struct arch_timer_context *ctx, bool level)
|
||||
*
|
||||
* But hey, it's fast, right?
|
||||
*/
|
||||
if (is_hyp_ctxt(ctx->vcpu) &&
|
||||
(ctx == vcpu_vtimer(ctx->vcpu) || ctx == vcpu_ptimer(ctx->vcpu))) {
|
||||
struct kvm_vcpu *vcpu = timer_context_to_vcpu(ctx);
|
||||
if (is_hyp_ctxt(vcpu) &&
|
||||
(ctx == vcpu_vtimer(vcpu) || ctx == vcpu_ptimer(vcpu))) {
|
||||
unsigned long val = timer_get_ctl(ctx);
|
||||
__assign_bit(__ffs(ARCH_TIMER_CTRL_IT_STAT), &val, level);
|
||||
timer_set_ctl(ctx, val);
|
||||
@@ -470,7 +461,7 @@ static void timer_emulate(struct arch_timer_context *ctx)
|
||||
trace_kvm_timer_emulate(ctx, should_fire);
|
||||
|
||||
if (should_fire != ctx->irq.level)
|
||||
kvm_timer_update_irq(ctx->vcpu, should_fire, ctx);
|
||||
kvm_timer_update_irq(timer_context_to_vcpu(ctx), should_fire, ctx);
|
||||
|
||||
kvm_timer_update_status(ctx, should_fire);
|
||||
|
||||
@@ -498,7 +489,7 @@ static void set_cntpoff(u64 cntpoff)
|
||||
|
||||
static void timer_save_state(struct arch_timer_context *ctx)
|
||||
{
|
||||
struct arch_timer_cpu *timer = vcpu_timer(ctx->vcpu);
|
||||
struct arch_timer_cpu *timer = vcpu_timer(timer_context_to_vcpu(ctx));
|
||||
enum kvm_arch_timers index = arch_timer_ctx_index(ctx);
|
||||
unsigned long flags;
|
||||
|
||||
@@ -609,7 +600,7 @@ static void kvm_timer_unblocking(struct kvm_vcpu *vcpu)
|
||||
|
||||
static void timer_restore_state(struct arch_timer_context *ctx)
|
||||
{
|
||||
struct arch_timer_cpu *timer = vcpu_timer(ctx->vcpu);
|
||||
struct arch_timer_cpu *timer = vcpu_timer(timer_context_to_vcpu(ctx));
|
||||
enum kvm_arch_timers index = arch_timer_ctx_index(ctx);
|
||||
unsigned long flags;
|
||||
|
||||
@@ -668,7 +659,7 @@ static inline void set_timer_irq_phys_active(struct arch_timer_context *ctx, boo
|
||||
|
||||
static void kvm_timer_vcpu_load_gic(struct arch_timer_context *ctx)
|
||||
{
|
||||
struct kvm_vcpu *vcpu = ctx->vcpu;
|
||||
struct kvm_vcpu *vcpu = timer_context_to_vcpu(ctx);
|
||||
bool phys_active = false;
|
||||
|
||||
/*
|
||||
@@ -677,7 +668,7 @@ static void kvm_timer_vcpu_load_gic(struct arch_timer_context *ctx)
|
||||
* this point and the register restoration, we'll take the
|
||||
* interrupt anyway.
|
||||
*/
|
||||
kvm_timer_update_irq(ctx->vcpu, kvm_timer_should_fire(ctx), ctx);
|
||||
kvm_timer_update_irq(vcpu, kvm_timer_should_fire(ctx), ctx);
|
||||
|
||||
if (irqchip_in_kernel(vcpu->kvm))
|
||||
phys_active = kvm_vgic_map_is_active(vcpu, timer_irq(ctx));
|
||||
@@ -1063,7 +1054,7 @@ static void timer_context_init(struct kvm_vcpu *vcpu, int timerid)
|
||||
struct arch_timer_context *ctxt = vcpu_get_timer(vcpu, timerid);
|
||||
struct kvm *kvm = vcpu->kvm;
|
||||
|
||||
ctxt->vcpu = vcpu;
|
||||
ctxt->timer_id = timerid;
|
||||
|
||||
if (timerid == TIMER_VTIMER)
|
||||
ctxt->offset.vm_offset = &kvm->arch.timer_data.voffset;
|
||||
@@ -1121,49 +1112,6 @@ void kvm_timer_cpu_down(void)
|
||||
disable_percpu_irq(host_ptimer_irq);
|
||||
}
|
||||
|
||||
int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value)
|
||||
{
|
||||
struct arch_timer_context *timer;
|
||||
|
||||
switch (regid) {
|
||||
case KVM_REG_ARM_TIMER_CTL:
|
||||
timer = vcpu_vtimer(vcpu);
|
||||
kvm_arm_timer_write(vcpu, timer, TIMER_REG_CTL, value);
|
||||
break;
|
||||
case KVM_REG_ARM_TIMER_CNT:
|
||||
if (!test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET,
|
||||
&vcpu->kvm->arch.flags)) {
|
||||
timer = vcpu_vtimer(vcpu);
|
||||
timer_set_offset(timer, kvm_phys_timer_read() - value);
|
||||
}
|
||||
break;
|
||||
case KVM_REG_ARM_TIMER_CVAL:
|
||||
timer = vcpu_vtimer(vcpu);
|
||||
kvm_arm_timer_write(vcpu, timer, TIMER_REG_CVAL, value);
|
||||
break;
|
||||
case KVM_REG_ARM_PTIMER_CTL:
|
||||
timer = vcpu_ptimer(vcpu);
|
||||
kvm_arm_timer_write(vcpu, timer, TIMER_REG_CTL, value);
|
||||
break;
|
||||
case KVM_REG_ARM_PTIMER_CNT:
|
||||
if (!test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET,
|
||||
&vcpu->kvm->arch.flags)) {
|
||||
timer = vcpu_ptimer(vcpu);
|
||||
timer_set_offset(timer, kvm_phys_timer_read() - value);
|
||||
}
|
||||
break;
|
||||
case KVM_REG_ARM_PTIMER_CVAL:
|
||||
timer = vcpu_ptimer(vcpu);
|
||||
kvm_arm_timer_write(vcpu, timer, TIMER_REG_CVAL, value);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u64 read_timer_ctl(struct arch_timer_context *timer)
|
||||
{
|
||||
/*
|
||||
@@ -1180,31 +1128,6 @@ static u64 read_timer_ctl(struct arch_timer_context *timer)
|
||||
return ctl;
|
||||
}
|
||||
|
||||
u64 kvm_arm_timer_get_reg(struct kvm_vcpu *vcpu, u64 regid)
|
||||
{
|
||||
switch (regid) {
|
||||
case KVM_REG_ARM_TIMER_CTL:
|
||||
return kvm_arm_timer_read(vcpu,
|
||||
vcpu_vtimer(vcpu), TIMER_REG_CTL);
|
||||
case KVM_REG_ARM_TIMER_CNT:
|
||||
return kvm_arm_timer_read(vcpu,
|
||||
vcpu_vtimer(vcpu), TIMER_REG_CNT);
|
||||
case KVM_REG_ARM_TIMER_CVAL:
|
||||
return kvm_arm_timer_read(vcpu,
|
||||
vcpu_vtimer(vcpu), TIMER_REG_CVAL);
|
||||
case KVM_REG_ARM_PTIMER_CTL:
|
||||
return kvm_arm_timer_read(vcpu,
|
||||
vcpu_ptimer(vcpu), TIMER_REG_CTL);
|
||||
case KVM_REG_ARM_PTIMER_CNT:
|
||||
return kvm_arm_timer_read(vcpu,
|
||||
vcpu_ptimer(vcpu), TIMER_REG_CNT);
|
||||
case KVM_REG_ARM_PTIMER_CVAL:
|
||||
return kvm_arm_timer_read(vcpu,
|
||||
vcpu_ptimer(vcpu), TIMER_REG_CVAL);
|
||||
}
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu,
|
||||
struct arch_timer_context *timer,
|
||||
enum kvm_arch_timer_regs treg)
|
||||
|
||||
@@ -642,6 +642,7 @@ nommu:
|
||||
vcpu->arch.hcr_el2 |= HCR_TWI;
|
||||
|
||||
vcpu_set_pauth_traps(vcpu);
|
||||
kvm_vcpu_load_fgt(vcpu);
|
||||
|
||||
if (is_protected_kvm_enabled()) {
|
||||
kvm_call_hyp_nvhe(__pkvm_vcpu_load,
|
||||
@@ -1794,6 +1795,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
|
||||
case KVM_GET_VCPU_EVENTS: {
|
||||
struct kvm_vcpu_events events;
|
||||
|
||||
if (!kvm_vcpu_initialized(vcpu))
|
||||
return -ENOEXEC;
|
||||
|
||||
if (kvm_arm_vcpu_get_events(vcpu, &events))
|
||||
return -EINVAL;
|
||||
|
||||
@@ -1805,6 +1809,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
|
||||
case KVM_SET_VCPU_EVENTS: {
|
||||
struct kvm_vcpu_events events;
|
||||
|
||||
if (!kvm_vcpu_initialized(vcpu))
|
||||
return -ENOEXEC;
|
||||
|
||||
if (copy_from_user(&events, argp, sizeof(events)))
|
||||
return -EFAULT;
|
||||
|
||||
|
||||
@@ -91,7 +91,6 @@ static enum trans_regime compute_translation_regime(struct kvm_vcpu *vcpu, u32 o
|
||||
case OP_AT_S1E2W:
|
||||
case OP_AT_S1E2A:
|
||||
return vcpu_el2_e2h_is_set(vcpu) ? TR_EL20 : TR_EL2;
|
||||
break;
|
||||
default:
|
||||
return (vcpu_el2_e2h_is_set(vcpu) &&
|
||||
vcpu_el2_tge_is_set(vcpu)) ? TR_EL20 : TR_EL10;
|
||||
@@ -1602,13 +1601,17 @@ int __kvm_find_s1_desc_level(struct kvm_vcpu *vcpu, u64 va, u64 ipa, int *level)
|
||||
.fn = match_s1_desc,
|
||||
.priv = &dm,
|
||||
},
|
||||
.regime = TR_EL10,
|
||||
.as_el0 = false,
|
||||
.pan = false,
|
||||
};
|
||||
struct s1_walk_result wr = {};
|
||||
int ret;
|
||||
|
||||
if (is_hyp_ctxt(vcpu))
|
||||
wi.regime = vcpu_el2_e2h_is_set(vcpu) ? TR_EL20 : TR_EL2;
|
||||
else
|
||||
wi.regime = TR_EL10;
|
||||
|
||||
ret = setup_s1_walk(vcpu, &wi, &wr, va);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
*/
|
||||
|
||||
#include <linux/kvm_host.h>
|
||||
#include <asm/kvm_emulate.h>
|
||||
#include <asm/kvm_nested.h>
|
||||
#include <asm/sysreg.h>
|
||||
|
||||
/*
|
||||
@@ -1428,3 +1430,91 @@ void get_reg_fixed_bits(struct kvm *kvm, enum vcpu_sysreg reg, u64 *res0, u64 *r
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static __always_inline struct fgt_masks *__fgt_reg_to_masks(enum vcpu_sysreg reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case HFGRTR_EL2:
|
||||
return &hfgrtr_masks;
|
||||
case HFGWTR_EL2:
|
||||
return &hfgwtr_masks;
|
||||
case HFGITR_EL2:
|
||||
return &hfgitr_masks;
|
||||
case HDFGRTR_EL2:
|
||||
return &hdfgrtr_masks;
|
||||
case HDFGWTR_EL2:
|
||||
return &hdfgwtr_masks;
|
||||
case HAFGRTR_EL2:
|
||||
return &hafgrtr_masks;
|
||||
case HFGRTR2_EL2:
|
||||
return &hfgrtr2_masks;
|
||||
case HFGWTR2_EL2:
|
||||
return &hfgwtr2_masks;
|
||||
case HFGITR2_EL2:
|
||||
return &hfgitr2_masks;
|
||||
case HDFGRTR2_EL2:
|
||||
return &hdfgrtr2_masks;
|
||||
case HDFGWTR2_EL2:
|
||||
return &hdfgwtr2_masks;
|
||||
default:
|
||||
BUILD_BUG_ON(1);
|
||||
}
|
||||
}
|
||||
|
||||
static __always_inline void __compute_fgt(struct kvm_vcpu *vcpu, enum vcpu_sysreg reg)
|
||||
{
|
||||
u64 fgu = vcpu->kvm->arch.fgu[__fgt_reg_to_group_id(reg)];
|
||||
struct fgt_masks *m = __fgt_reg_to_masks(reg);
|
||||
u64 clear = 0, set = 0, val = m->nmask;
|
||||
|
||||
set |= fgu & m->mask;
|
||||
clear |= fgu & m->nmask;
|
||||
|
||||
if (is_nested_ctxt(vcpu)) {
|
||||
u64 nested = __vcpu_sys_reg(vcpu, reg);
|
||||
set |= nested & m->mask;
|
||||
clear |= ~nested & m->nmask;
|
||||
}
|
||||
|
||||
val |= set;
|
||||
val &= ~clear;
|
||||
*vcpu_fgt(vcpu, reg) = val;
|
||||
}
|
||||
|
||||
static void __compute_hfgwtr(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
__compute_fgt(vcpu, HFGWTR_EL2);
|
||||
|
||||
if (cpus_have_final_cap(ARM64_WORKAROUND_AMPERE_AC03_CPU_38))
|
||||
*vcpu_fgt(vcpu, HFGWTR_EL2) |= HFGWTR_EL2_TCR_EL1;
|
||||
}
|
||||
|
||||
static void __compute_hdfgwtr(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
__compute_fgt(vcpu, HDFGWTR_EL2);
|
||||
|
||||
if (is_hyp_ctxt(vcpu))
|
||||
*vcpu_fgt(vcpu, HDFGWTR_EL2) |= HDFGWTR_EL2_MDSCR_EL1;
|
||||
}
|
||||
|
||||
void kvm_vcpu_load_fgt(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (!cpus_have_final_cap(ARM64_HAS_FGT))
|
||||
return;
|
||||
|
||||
__compute_fgt(vcpu, HFGRTR_EL2);
|
||||
__compute_hfgwtr(vcpu);
|
||||
__compute_fgt(vcpu, HFGITR_EL2);
|
||||
__compute_fgt(vcpu, HDFGRTR_EL2);
|
||||
__compute_hdfgwtr(vcpu);
|
||||
__compute_fgt(vcpu, HAFGRTR_EL2);
|
||||
|
||||
if (!cpus_have_final_cap(ARM64_HAS_FGT2))
|
||||
return;
|
||||
|
||||
__compute_fgt(vcpu, HFGRTR2_EL2);
|
||||
__compute_fgt(vcpu, HFGWTR2_EL2);
|
||||
__compute_fgt(vcpu, HFGITR2_EL2);
|
||||
__compute_fgt(vcpu, HDFGRTR2_EL2);
|
||||
__compute_fgt(vcpu, HDFGWTR2_EL2);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,12 @@
|
||||
#include <asm/kvm_arm.h>
|
||||
#include <asm/kvm_emulate.h>
|
||||
|
||||
static int cpu_has_spe(u64 dfr0)
|
||||
{
|
||||
return cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_PMSVer_SHIFT) &&
|
||||
!(read_sysreg_s(SYS_PMBIDR_EL1) & PMBIDR_EL1_P);
|
||||
}
|
||||
|
||||
/**
|
||||
* kvm_arm_setup_mdcr_el2 - configure vcpu mdcr_el2 value
|
||||
*
|
||||
@@ -77,13 +83,12 @@ void kvm_init_host_debug_data(void)
|
||||
*host_data_ptr(debug_brps) = SYS_FIELD_GET(ID_AA64DFR0_EL1, BRPs, dfr0);
|
||||
*host_data_ptr(debug_wrps) = SYS_FIELD_GET(ID_AA64DFR0_EL1, WRPs, dfr0);
|
||||
|
||||
if (cpu_has_spe(dfr0))
|
||||
host_data_set_flag(HAS_SPE);
|
||||
|
||||
if (has_vhe())
|
||||
return;
|
||||
|
||||
if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_PMSVer_SHIFT) &&
|
||||
!(read_sysreg_s(SYS_PMBIDR_EL1) & PMBIDR_EL1_P))
|
||||
host_data_set_flag(HAS_SPE);
|
||||
|
||||
/* Check if we have BRBE implemented and available at the host */
|
||||
if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_BRBE_SHIFT))
|
||||
host_data_set_flag(HAS_BRBE);
|
||||
@@ -102,7 +107,7 @@ void kvm_init_host_debug_data(void)
|
||||
void kvm_debug_init_vhe(void)
|
||||
{
|
||||
/* Clear PMSCR_EL1.E{0,1}SPE which reset to UNKNOWN values. */
|
||||
if (SYS_FIELD_GET(ID_AA64DFR0_EL1, PMSVer, read_sysreg(id_aa64dfr0_el1)))
|
||||
if (host_data_test_flag(HAS_SPE))
|
||||
write_sysreg_el1(0, SYS_PMSCR);
|
||||
}
|
||||
|
||||
|
||||
@@ -591,64 +591,6 @@ static unsigned long num_core_regs(const struct kvm_vcpu *vcpu)
|
||||
return copy_core_reg_indices(vcpu, NULL);
|
||||
}
|
||||
|
||||
static const u64 timer_reg_list[] = {
|
||||
KVM_REG_ARM_TIMER_CTL,
|
||||
KVM_REG_ARM_TIMER_CNT,
|
||||
KVM_REG_ARM_TIMER_CVAL,
|
||||
KVM_REG_ARM_PTIMER_CTL,
|
||||
KVM_REG_ARM_PTIMER_CNT,
|
||||
KVM_REG_ARM_PTIMER_CVAL,
|
||||
};
|
||||
|
||||
#define NUM_TIMER_REGS ARRAY_SIZE(timer_reg_list)
|
||||
|
||||
static bool is_timer_reg(u64 index)
|
||||
{
|
||||
switch (index) {
|
||||
case KVM_REG_ARM_TIMER_CTL:
|
||||
case KVM_REG_ARM_TIMER_CNT:
|
||||
case KVM_REG_ARM_TIMER_CVAL:
|
||||
case KVM_REG_ARM_PTIMER_CTL:
|
||||
case KVM_REG_ARM_PTIMER_CNT:
|
||||
case KVM_REG_ARM_PTIMER_CVAL:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int copy_timer_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
|
||||
{
|
||||
for (int i = 0; i < NUM_TIMER_REGS; i++) {
|
||||
if (put_user(timer_reg_list[i], uindices))
|
||||
return -EFAULT;
|
||||
uindices++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
|
||||
{
|
||||
void __user *uaddr = (void __user *)(long)reg->addr;
|
||||
u64 val;
|
||||
int ret;
|
||||
|
||||
ret = copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id));
|
||||
if (ret != 0)
|
||||
return -EFAULT;
|
||||
|
||||
return kvm_arm_timer_set_reg(vcpu, reg->id, val);
|
||||
}
|
||||
|
||||
static int get_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
|
||||
{
|
||||
void __user *uaddr = (void __user *)(long)reg->addr;
|
||||
u64 val;
|
||||
|
||||
val = kvm_arm_timer_get_reg(vcpu, reg->id);
|
||||
return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)) ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
static unsigned long num_sve_regs(const struct kvm_vcpu *vcpu)
|
||||
{
|
||||
const unsigned int slices = vcpu_sve_slices(vcpu);
|
||||
@@ -724,7 +666,6 @@ unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu)
|
||||
res += num_sve_regs(vcpu);
|
||||
res += kvm_arm_num_sys_reg_descs(vcpu);
|
||||
res += kvm_arm_get_fw_num_regs(vcpu);
|
||||
res += NUM_TIMER_REGS;
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -755,11 +696,6 @@ int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
|
||||
return ret;
|
||||
uindices += kvm_arm_get_fw_num_regs(vcpu);
|
||||
|
||||
ret = copy_timer_indices(vcpu, uindices);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
uindices += NUM_TIMER_REGS;
|
||||
|
||||
return kvm_arm_copy_sys_reg_indices(vcpu, uindices);
|
||||
}
|
||||
|
||||
@@ -777,9 +713,6 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
|
||||
case KVM_REG_ARM64_SVE: return get_sve_reg(vcpu, reg);
|
||||
}
|
||||
|
||||
if (is_timer_reg(reg->id))
|
||||
return get_timer_reg(vcpu, reg);
|
||||
|
||||
return kvm_arm_sys_reg_get_reg(vcpu, reg);
|
||||
}
|
||||
|
||||
@@ -797,9 +730,6 @@ int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
|
||||
case KVM_REG_ARM64_SVE: return set_sve_reg(vcpu, reg);
|
||||
}
|
||||
|
||||
if (is_timer_reg(reg->id))
|
||||
return set_timer_reg(vcpu, reg);
|
||||
|
||||
return kvm_arm_sys_reg_set_reg(vcpu, reg);
|
||||
}
|
||||
|
||||
|
||||
@@ -147,7 +147,12 @@ static int kvm_handle_wfx(struct kvm_vcpu *vcpu)
|
||||
if (esr & ESR_ELx_WFx_ISS_RV) {
|
||||
u64 val, now;
|
||||
|
||||
now = kvm_arm_timer_get_reg(vcpu, KVM_REG_ARM_TIMER_CNT);
|
||||
now = kvm_phys_timer_read();
|
||||
if (is_hyp_ctxt(vcpu) && vcpu_el2_e2h_is_set(vcpu))
|
||||
now -= timer_get_offset(vcpu_hvtimer(vcpu));
|
||||
else
|
||||
now -= timer_get_offset(vcpu_vtimer(vcpu));
|
||||
|
||||
val = vcpu_get_reg(vcpu, kvm_vcpu_sys_get_rt(vcpu));
|
||||
|
||||
if (now >= val)
|
||||
|
||||
@@ -195,123 +195,6 @@ static inline void __deactivate_cptr_traps(struct kvm_vcpu *vcpu)
|
||||
__deactivate_cptr_traps_nvhe(vcpu);
|
||||
}
|
||||
|
||||
#define reg_to_fgt_masks(reg) \
|
||||
({ \
|
||||
struct fgt_masks *m; \
|
||||
switch(reg) { \
|
||||
case HFGRTR_EL2: \
|
||||
m = &hfgrtr_masks; \
|
||||
break; \
|
||||
case HFGWTR_EL2: \
|
||||
m = &hfgwtr_masks; \
|
||||
break; \
|
||||
case HFGITR_EL2: \
|
||||
m = &hfgitr_masks; \
|
||||
break; \
|
||||
case HDFGRTR_EL2: \
|
||||
m = &hdfgrtr_masks; \
|
||||
break; \
|
||||
case HDFGWTR_EL2: \
|
||||
m = &hdfgwtr_masks; \
|
||||
break; \
|
||||
case HAFGRTR_EL2: \
|
||||
m = &hafgrtr_masks; \
|
||||
break; \
|
||||
case HFGRTR2_EL2: \
|
||||
m = &hfgrtr2_masks; \
|
||||
break; \
|
||||
case HFGWTR2_EL2: \
|
||||
m = &hfgwtr2_masks; \
|
||||
break; \
|
||||
case HFGITR2_EL2: \
|
||||
m = &hfgitr2_masks; \
|
||||
break; \
|
||||
case HDFGRTR2_EL2: \
|
||||
m = &hdfgrtr2_masks; \
|
||||
break; \
|
||||
case HDFGWTR2_EL2: \
|
||||
m = &hdfgwtr2_masks; \
|
||||
break; \
|
||||
default: \
|
||||
BUILD_BUG_ON(1); \
|
||||
} \
|
||||
\
|
||||
m; \
|
||||
})
|
||||
|
||||
#define compute_clr_set(vcpu, reg, clr, set) \
|
||||
do { \
|
||||
u64 hfg = __vcpu_sys_reg(vcpu, reg); \
|
||||
struct fgt_masks *m = reg_to_fgt_masks(reg); \
|
||||
set |= hfg & m->mask; \
|
||||
clr |= ~hfg & m->nmask; \
|
||||
} while(0)
|
||||
|
||||
#define reg_to_fgt_group_id(reg) \
|
||||
({ \
|
||||
enum fgt_group_id id; \
|
||||
switch(reg) { \
|
||||
case HFGRTR_EL2: \
|
||||
case HFGWTR_EL2: \
|
||||
id = HFGRTR_GROUP; \
|
||||
break; \
|
||||
case HFGITR_EL2: \
|
||||
id = HFGITR_GROUP; \
|
||||
break; \
|
||||
case HDFGRTR_EL2: \
|
||||
case HDFGWTR_EL2: \
|
||||
id = HDFGRTR_GROUP; \
|
||||
break; \
|
||||
case HAFGRTR_EL2: \
|
||||
id = HAFGRTR_GROUP; \
|
||||
break; \
|
||||
case HFGRTR2_EL2: \
|
||||
case HFGWTR2_EL2: \
|
||||
id = HFGRTR2_GROUP; \
|
||||
break; \
|
||||
case HFGITR2_EL2: \
|
||||
id = HFGITR2_GROUP; \
|
||||
break; \
|
||||
case HDFGRTR2_EL2: \
|
||||
case HDFGWTR2_EL2: \
|
||||
id = HDFGRTR2_GROUP; \
|
||||
break; \
|
||||
default: \
|
||||
BUILD_BUG_ON(1); \
|
||||
} \
|
||||
\
|
||||
id; \
|
||||
})
|
||||
|
||||
#define compute_undef_clr_set(vcpu, kvm, reg, clr, set) \
|
||||
do { \
|
||||
u64 hfg = kvm->arch.fgu[reg_to_fgt_group_id(reg)]; \
|
||||
struct fgt_masks *m = reg_to_fgt_masks(reg); \
|
||||
set |= hfg & m->mask; \
|
||||
clr |= hfg & m->nmask; \
|
||||
} while(0)
|
||||
|
||||
#define update_fgt_traps_cs(hctxt, vcpu, kvm, reg, clr, set) \
|
||||
do { \
|
||||
struct fgt_masks *m = reg_to_fgt_masks(reg); \
|
||||
u64 c = clr, s = set; \
|
||||
u64 val; \
|
||||
\
|
||||
ctxt_sys_reg(hctxt, reg) = read_sysreg_s(SYS_ ## reg); \
|
||||
if (is_nested_ctxt(vcpu)) \
|
||||
compute_clr_set(vcpu, reg, c, s); \
|
||||
\
|
||||
compute_undef_clr_set(vcpu, kvm, reg, c, s); \
|
||||
\
|
||||
val = m->nmask; \
|
||||
val |= s; \
|
||||
val &= ~c; \
|
||||
write_sysreg_s(val, SYS_ ## reg); \
|
||||
} while(0)
|
||||
|
||||
#define update_fgt_traps(hctxt, vcpu, kvm, reg) \
|
||||
update_fgt_traps_cs(hctxt, vcpu, kvm, reg, 0, 0)
|
||||
|
||||
static inline bool cpu_has_amu(void)
|
||||
{
|
||||
u64 pfr0 = read_sysreg_s(SYS_ID_AA64PFR0_EL1);
|
||||
@@ -320,33 +203,36 @@ static inline bool cpu_has_amu(void)
|
||||
ID_AA64PFR0_EL1_AMU_SHIFT);
|
||||
}
|
||||
|
||||
#define __activate_fgt(hctxt, vcpu, reg) \
|
||||
do { \
|
||||
ctxt_sys_reg(hctxt, reg) = read_sysreg_s(SYS_ ## reg); \
|
||||
write_sysreg_s(*vcpu_fgt(vcpu, reg), SYS_ ## reg); \
|
||||
} while (0)
|
||||
|
||||
static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm_cpu_context *hctxt = host_data_ptr(host_ctxt);
|
||||
struct kvm *kvm = kern_hyp_va(vcpu->kvm);
|
||||
|
||||
if (!cpus_have_final_cap(ARM64_HAS_FGT))
|
||||
return;
|
||||
|
||||
update_fgt_traps(hctxt, vcpu, kvm, HFGRTR_EL2);
|
||||
update_fgt_traps_cs(hctxt, vcpu, kvm, HFGWTR_EL2, 0,
|
||||
cpus_have_final_cap(ARM64_WORKAROUND_AMPERE_AC03_CPU_38) ?
|
||||
HFGWTR_EL2_TCR_EL1_MASK : 0);
|
||||
update_fgt_traps(hctxt, vcpu, kvm, HFGITR_EL2);
|
||||
update_fgt_traps(hctxt, vcpu, kvm, HDFGRTR_EL2);
|
||||
update_fgt_traps(hctxt, vcpu, kvm, HDFGWTR_EL2);
|
||||
__activate_fgt(hctxt, vcpu, HFGRTR_EL2);
|
||||
__activate_fgt(hctxt, vcpu, HFGWTR_EL2);
|
||||
__activate_fgt(hctxt, vcpu, HFGITR_EL2);
|
||||
__activate_fgt(hctxt, vcpu, HDFGRTR_EL2);
|
||||
__activate_fgt(hctxt, vcpu, HDFGWTR_EL2);
|
||||
|
||||
if (cpu_has_amu())
|
||||
update_fgt_traps(hctxt, vcpu, kvm, HAFGRTR_EL2);
|
||||
__activate_fgt(hctxt, vcpu, HAFGRTR_EL2);
|
||||
|
||||
if (!cpus_have_final_cap(ARM64_HAS_FGT2))
|
||||
return;
|
||||
|
||||
update_fgt_traps(hctxt, vcpu, kvm, HFGRTR2_EL2);
|
||||
update_fgt_traps(hctxt, vcpu, kvm, HFGWTR2_EL2);
|
||||
update_fgt_traps(hctxt, vcpu, kvm, HFGITR2_EL2);
|
||||
update_fgt_traps(hctxt, vcpu, kvm, HDFGRTR2_EL2);
|
||||
update_fgt_traps(hctxt, vcpu, kvm, HDFGWTR2_EL2);
|
||||
__activate_fgt(hctxt, vcpu, HFGRTR2_EL2);
|
||||
__activate_fgt(hctxt, vcpu, HFGWTR2_EL2);
|
||||
__activate_fgt(hctxt, vcpu, HFGITR2_EL2);
|
||||
__activate_fgt(hctxt, vcpu, HDFGRTR2_EL2);
|
||||
__activate_fgt(hctxt, vcpu, HDFGWTR2_EL2);
|
||||
}
|
||||
|
||||
#define __deactivate_fgt(htcxt, vcpu, reg) \
|
||||
|
||||
@@ -172,6 +172,7 @@ static int pkvm_vcpu_init_traps(struct pkvm_hyp_vcpu *hyp_vcpu)
|
||||
|
||||
/* Trust the host for non-protected vcpu features. */
|
||||
vcpu->arch.hcrx_el2 = host_vcpu->arch.hcrx_el2;
|
||||
memcpy(vcpu->arch.fgt, host_vcpu->arch.fgt, sizeof(vcpu->arch.fgt));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1859,13 +1859,16 @@ void kvm_nested_setup_mdcr_el2(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
u64 guest_mdcr = __vcpu_sys_reg(vcpu, MDCR_EL2);
|
||||
|
||||
if (is_nested_ctxt(vcpu))
|
||||
vcpu->arch.mdcr_el2 |= (guest_mdcr & NV_MDCR_GUEST_INCLUDE);
|
||||
/*
|
||||
* In yet another example where FEAT_NV2 is fscking broken, accesses
|
||||
* to MDSCR_EL1 are redirected to the VNCR despite having an effect
|
||||
* at EL2. Use a big hammer to apply sanity.
|
||||
*
|
||||
* Unless of course we have FEAT_FGT, in which case we can precisely
|
||||
* trap MDSCR_EL1.
|
||||
*/
|
||||
if (is_hyp_ctxt(vcpu))
|
||||
else if (!cpus_have_final_cap(ARM64_HAS_FGT))
|
||||
vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
|
||||
else
|
||||
vcpu->arch.mdcr_el2 |= (guest_mdcr & NV_MDCR_GUEST_INCLUDE);
|
||||
}
|
||||
|
||||
@@ -203,7 +203,6 @@ static void locate_register(const struct kvm_vcpu *vcpu, enum vcpu_sysreg reg,
|
||||
MAPPED_EL2_SYSREG(AMAIR_EL2, AMAIR_EL1, NULL );
|
||||
MAPPED_EL2_SYSREG(ELR_EL2, ELR_EL1, NULL );
|
||||
MAPPED_EL2_SYSREG(SPSR_EL2, SPSR_EL1, NULL );
|
||||
MAPPED_EL2_SYSREG(ZCR_EL2, ZCR_EL1, NULL );
|
||||
MAPPED_EL2_SYSREG(CONTEXTIDR_EL2, CONTEXTIDR_EL1, NULL );
|
||||
MAPPED_EL2_SYSREG(SCTLR2_EL2, SCTLR2_EL1, NULL );
|
||||
case CNTHCTL_EL2:
|
||||
@@ -1595,14 +1594,47 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool access_hv_timer(struct kvm_vcpu *vcpu,
|
||||
struct sys_reg_params *p,
|
||||
const struct sys_reg_desc *r)
|
||||
static int arch_timer_set_user(struct kvm_vcpu *vcpu,
|
||||
const struct sys_reg_desc *rd,
|
||||
u64 val)
|
||||
{
|
||||
if (!vcpu_el2_e2h_is_set(vcpu))
|
||||
return undef_access(vcpu, p, r);
|
||||
switch (reg_to_encoding(rd)) {
|
||||
case SYS_CNTV_CTL_EL0:
|
||||
case SYS_CNTP_CTL_EL0:
|
||||
case SYS_CNTHV_CTL_EL2:
|
||||
case SYS_CNTHP_CTL_EL2:
|
||||
val &= ~ARCH_TIMER_CTRL_IT_STAT;
|
||||
break;
|
||||
case SYS_CNTVCT_EL0:
|
||||
if (!test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET, &vcpu->kvm->arch.flags))
|
||||
timer_set_offset(vcpu_vtimer(vcpu), kvm_phys_timer_read() - val);
|
||||
return 0;
|
||||
case SYS_CNTPCT_EL0:
|
||||
if (!test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET, &vcpu->kvm->arch.flags))
|
||||
timer_set_offset(vcpu_ptimer(vcpu), kvm_phys_timer_read() - val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return access_arch_timer(vcpu, p, r);
|
||||
__vcpu_assign_sys_reg(vcpu, rd->reg, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arch_timer_get_user(struct kvm_vcpu *vcpu,
|
||||
const struct sys_reg_desc *rd,
|
||||
u64 *val)
|
||||
{
|
||||
switch (reg_to_encoding(rd)) {
|
||||
case SYS_CNTVCT_EL0:
|
||||
*val = kvm_phys_timer_read() - timer_get_offset(vcpu_vtimer(vcpu));
|
||||
break;
|
||||
case SYS_CNTPCT_EL0:
|
||||
*val = kvm_phys_timer_read() - timer_get_offset(vcpu_ptimer(vcpu));
|
||||
break;
|
||||
default:
|
||||
*val = __vcpu_sys_reg(vcpu, rd->reg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static s64 kvm_arm64_ftr_safe_value(u32 id, const struct arm64_ftr_bits *ftrp,
|
||||
@@ -2507,15 +2539,20 @@ static bool bad_redir_trap(struct kvm_vcpu *vcpu,
|
||||
"trap of EL2 register redirected to EL1");
|
||||
}
|
||||
|
||||
#define EL2_REG_FILTERED(name, acc, rst, v, filter) { \
|
||||
#define SYS_REG_USER_FILTER(name, acc, rst, v, gu, su, filter) { \
|
||||
SYS_DESC(SYS_##name), \
|
||||
.access = acc, \
|
||||
.reset = rst, \
|
||||
.reg = name, \
|
||||
.get_user = gu, \
|
||||
.set_user = su, \
|
||||
.visibility = filter, \
|
||||
.val = v, \
|
||||
}
|
||||
|
||||
#define EL2_REG_FILTERED(name, acc, rst, v, filter) \
|
||||
SYS_REG_USER_FILTER(name, acc, rst, v, NULL, NULL, filter)
|
||||
|
||||
#define EL2_REG(name, acc, rst, v) \
|
||||
EL2_REG_FILTERED(name, acc, rst, v, el2_visibility)
|
||||
|
||||
@@ -2526,6 +2563,10 @@ static bool bad_redir_trap(struct kvm_vcpu *vcpu,
|
||||
EL2_REG_VNCR_FILT(name, hidden_visibility)
|
||||
#define EL2_REG_REDIR(name, rst, v) EL2_REG(name, bad_redir_trap, rst, v)
|
||||
|
||||
#define TIMER_REG(name, vis) \
|
||||
SYS_REG_USER_FILTER(name, access_arch_timer, reset_val, 0, \
|
||||
arch_timer_get_user, arch_timer_set_user, vis)
|
||||
|
||||
/*
|
||||
* Since reset() callback and field val are not used for idregs, they will be
|
||||
* used for specific purposes for idregs.
|
||||
@@ -2705,18 +2746,17 @@ static bool access_zcr_el2(struct kvm_vcpu *vcpu,
|
||||
|
||||
if (guest_hyp_sve_traps_enabled(vcpu)) {
|
||||
kvm_inject_nested_sve_trap(vcpu);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!p->is_write) {
|
||||
p->regval = vcpu_read_sys_reg(vcpu, ZCR_EL2);
|
||||
p->regval = __vcpu_sys_reg(vcpu, ZCR_EL2);
|
||||
return true;
|
||||
}
|
||||
|
||||
vq = SYS_FIELD_GET(ZCR_ELx, LEN, p->regval) + 1;
|
||||
vq = min(vq, vcpu_sve_max_vq(vcpu));
|
||||
vcpu_write_sys_reg(vcpu, vq - 1, ZCR_EL2);
|
||||
|
||||
__vcpu_assign_sys_reg(vcpu, ZCR_EL2, vq - 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2833,6 +2873,16 @@ static unsigned int s1pie_el2_visibility(const struct kvm_vcpu *vcpu,
|
||||
return __el2_visibility(vcpu, rd, s1pie_visibility);
|
||||
}
|
||||
|
||||
static unsigned int cnthv_visibility(const struct kvm_vcpu *vcpu,
|
||||
const struct sys_reg_desc *rd)
|
||||
{
|
||||
if (vcpu_has_nv(vcpu) &&
|
||||
!vcpu_has_feature(vcpu, KVM_ARM_VCPU_HAS_EL2_E2H0))
|
||||
return 0;
|
||||
|
||||
return REG_HIDDEN;
|
||||
}
|
||||
|
||||
static bool access_mdcr(struct kvm_vcpu *vcpu,
|
||||
struct sys_reg_params *p,
|
||||
const struct sys_reg_desc *r)
|
||||
@@ -3482,17 +3532,19 @@ static const struct sys_reg_desc sys_reg_descs[] = {
|
||||
AMU_AMEVTYPER1_EL0(14),
|
||||
AMU_AMEVTYPER1_EL0(15),
|
||||
|
||||
{ SYS_DESC(SYS_CNTPCT_EL0), access_arch_timer },
|
||||
{ SYS_DESC(SYS_CNTVCT_EL0), access_arch_timer },
|
||||
{ SYS_DESC(SYS_CNTPCT_EL0), .access = access_arch_timer,
|
||||
.get_user = arch_timer_get_user, .set_user = arch_timer_set_user },
|
||||
{ SYS_DESC(SYS_CNTVCT_EL0), .access = access_arch_timer,
|
||||
.get_user = arch_timer_get_user, .set_user = arch_timer_set_user },
|
||||
{ SYS_DESC(SYS_CNTPCTSS_EL0), access_arch_timer },
|
||||
{ SYS_DESC(SYS_CNTVCTSS_EL0), access_arch_timer },
|
||||
{ SYS_DESC(SYS_CNTP_TVAL_EL0), access_arch_timer },
|
||||
{ SYS_DESC(SYS_CNTP_CTL_EL0), access_arch_timer },
|
||||
{ SYS_DESC(SYS_CNTP_CVAL_EL0), access_arch_timer },
|
||||
TIMER_REG(CNTP_CTL_EL0, NULL),
|
||||
TIMER_REG(CNTP_CVAL_EL0, NULL),
|
||||
|
||||
{ SYS_DESC(SYS_CNTV_TVAL_EL0), access_arch_timer },
|
||||
{ SYS_DESC(SYS_CNTV_CTL_EL0), access_arch_timer },
|
||||
{ SYS_DESC(SYS_CNTV_CVAL_EL0), access_arch_timer },
|
||||
TIMER_REG(CNTV_CTL_EL0, NULL),
|
||||
TIMER_REG(CNTV_CVAL_EL0, NULL),
|
||||
|
||||
/* PMEVCNTRn_EL0 */
|
||||
PMU_PMEVCNTR_EL0(0),
|
||||
@@ -3690,12 +3742,12 @@ static const struct sys_reg_desc sys_reg_descs[] = {
|
||||
EL2_REG_VNCR(CNTVOFF_EL2, reset_val, 0),
|
||||
EL2_REG(CNTHCTL_EL2, access_rw, reset_val, 0),
|
||||
{ SYS_DESC(SYS_CNTHP_TVAL_EL2), access_arch_timer },
|
||||
EL2_REG(CNTHP_CTL_EL2, access_arch_timer, reset_val, 0),
|
||||
EL2_REG(CNTHP_CVAL_EL2, access_arch_timer, reset_val, 0),
|
||||
TIMER_REG(CNTHP_CTL_EL2, el2_visibility),
|
||||
TIMER_REG(CNTHP_CVAL_EL2, el2_visibility),
|
||||
|
||||
{ SYS_DESC(SYS_CNTHV_TVAL_EL2), access_hv_timer },
|
||||
EL2_REG(CNTHV_CTL_EL2, access_hv_timer, reset_val, 0),
|
||||
EL2_REG(CNTHV_CVAL_EL2, access_hv_timer, reset_val, 0),
|
||||
{ SYS_DESC(SYS_CNTHV_TVAL_EL2), access_arch_timer, .visibility = cnthv_visibility },
|
||||
TIMER_REG(CNTHV_CTL_EL2, cnthv_visibility),
|
||||
TIMER_REG(CNTHV_CVAL_EL2, cnthv_visibility),
|
||||
|
||||
{ SYS_DESC(SYS_CNTKCTL_EL12), access_cntkctl_el12 },
|
||||
|
||||
@@ -5233,15 +5285,28 @@ static int demux_c15_set(struct kvm_vcpu *vcpu, u64 id, void __user *uaddr)
|
||||
}
|
||||
}
|
||||
|
||||
static u64 kvm_one_reg_to_id(const struct kvm_one_reg *reg)
|
||||
{
|
||||
switch(reg->id) {
|
||||
case KVM_REG_ARM_TIMER_CVAL:
|
||||
return TO_ARM64_SYS_REG(CNTV_CVAL_EL0);
|
||||
case KVM_REG_ARM_TIMER_CNT:
|
||||
return TO_ARM64_SYS_REG(CNTVCT_EL0);
|
||||
default:
|
||||
return reg->id;
|
||||
}
|
||||
}
|
||||
|
||||
int kvm_sys_reg_get_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg,
|
||||
const struct sys_reg_desc table[], unsigned int num)
|
||||
{
|
||||
u64 __user *uaddr = (u64 __user *)(unsigned long)reg->addr;
|
||||
const struct sys_reg_desc *r;
|
||||
u64 id = kvm_one_reg_to_id(reg);
|
||||
u64 val;
|
||||
int ret;
|
||||
|
||||
r = id_to_sys_reg_desc(vcpu, reg->id, table, num);
|
||||
r = id_to_sys_reg_desc(vcpu, id, table, num);
|
||||
if (!r || sysreg_hidden(vcpu, r))
|
||||
return -ENOENT;
|
||||
|
||||
@@ -5274,13 +5339,14 @@ int kvm_sys_reg_set_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg,
|
||||
{
|
||||
u64 __user *uaddr = (u64 __user *)(unsigned long)reg->addr;
|
||||
const struct sys_reg_desc *r;
|
||||
u64 id = kvm_one_reg_to_id(reg);
|
||||
u64 val;
|
||||
int ret;
|
||||
|
||||
if (get_user(val, uaddr))
|
||||
return -EFAULT;
|
||||
|
||||
r = id_to_sys_reg_desc(vcpu, reg->id, table, num);
|
||||
r = id_to_sys_reg_desc(vcpu, id, table, num);
|
||||
if (!r || sysreg_hidden(vcpu, r))
|
||||
return -ENOENT;
|
||||
|
||||
@@ -5340,10 +5406,23 @@ static u64 sys_reg_to_index(const struct sys_reg_desc *reg)
|
||||
|
||||
static bool copy_reg_to_user(const struct sys_reg_desc *reg, u64 __user **uind)
|
||||
{
|
||||
u64 idx;
|
||||
|
||||
if (!*uind)
|
||||
return true;
|
||||
|
||||
if (put_user(sys_reg_to_index(reg), *uind))
|
||||
switch (reg_to_encoding(reg)) {
|
||||
case SYS_CNTV_CVAL_EL0:
|
||||
idx = KVM_REG_ARM_TIMER_CVAL;
|
||||
break;
|
||||
case SYS_CNTVCT_EL0:
|
||||
idx = KVM_REG_ARM_TIMER_CNT;
|
||||
break;
|
||||
default:
|
||||
idx = sys_reg_to_index(reg);
|
||||
}
|
||||
|
||||
if (put_user(idx, *uind))
|
||||
return false;
|
||||
|
||||
(*uind)++;
|
||||
|
||||
@@ -257,4 +257,10 @@ int kvm_finalize_sys_regs(struct kvm_vcpu *vcpu);
|
||||
(val); \
|
||||
})
|
||||
|
||||
#define TO_ARM64_SYS_REG(r) ARM64_SYS_REG(sys_reg_Op0(SYS_ ## r), \
|
||||
sys_reg_Op1(SYS_ ## r), \
|
||||
sys_reg_CRn(SYS_ ## r), \
|
||||
sys_reg_CRm(SYS_ ## r), \
|
||||
sys_reg_Op2(SYS_ ## r))
|
||||
|
||||
#endif /* __ARM64_KVM_SYS_REGS_LOCAL_H__ */
|
||||
|
||||
@@ -297,8 +297,11 @@ void vcpu_set_ich_hcr(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct vgic_v3_cpu_if *vgic_v3 = &vcpu->arch.vgic_cpu.vgic_v3;
|
||||
|
||||
if (!vgic_is_v3(vcpu->kvm))
|
||||
return;
|
||||
|
||||
/* Hide GICv3 sysreg if necessary */
|
||||
if (!kvm_has_gicv3(vcpu->kvm)) {
|
||||
if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V2) {
|
||||
vgic_v3->vgic_hcr |= (ICH_HCR_EL2_TALL0 | ICH_HCR_EL2_TALL1 |
|
||||
ICH_HCR_EL2_TC);
|
||||
return;
|
||||
|
||||
@@ -35,7 +35,7 @@ void copy_highpage(struct page *to, struct page *from)
|
||||
from != folio_page(src, 0))
|
||||
return;
|
||||
|
||||
WARN_ON_ONCE(!folio_try_hugetlb_mte_tagging(dst));
|
||||
folio_try_hugetlb_mte_tagging(dst);
|
||||
|
||||
/*
|
||||
* Populate tags for all subpages.
|
||||
@@ -51,8 +51,13 @@ void copy_highpage(struct page *to, struct page *from)
|
||||
}
|
||||
folio_set_hugetlb_mte_tagged(dst);
|
||||
} else if (page_mte_tagged(from)) {
|
||||
/* It's a new page, shouldn't have been tagged yet */
|
||||
WARN_ON_ONCE(!try_page_mte_tagging(to));
|
||||
/*
|
||||
* Most of the time it's a new page that shouldn't have been
|
||||
* tagged yet. However, folio migration can end up reusing the
|
||||
* same page without untagging it. Ignore the warning if the
|
||||
* page is already tagged.
|
||||
*/
|
||||
try_page_mte_tagging(to);
|
||||
|
||||
mte_copy_page_tags(kto, kfrom);
|
||||
set_page_mte_tagged(to);
|
||||
|
||||
@@ -21,7 +21,7 @@ void update_mmu_cache_range(struct vm_fault *vmf, struct vm_area_struct *vma,
|
||||
|
||||
folio = page_folio(pfn_to_page(pfn));
|
||||
|
||||
if (test_and_set_bit(PG_dcache_clean, &folio->flags))
|
||||
if (test_and_set_bit(PG_dcache_clean, &folio->flags.f))
|
||||
return;
|
||||
|
||||
icache_inv_range(address, address + nr*PAGE_SIZE);
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
|
||||
static inline void flush_dcache_folio(struct folio *folio)
|
||||
{
|
||||
if (test_bit(PG_dcache_clean, &folio->flags))
|
||||
clear_bit(PG_dcache_clean, &folio->flags);
|
||||
if (test_bit(PG_dcache_clean, &folio->flags.f))
|
||||
clear_bit(PG_dcache_clean, &folio->flags.f);
|
||||
}
|
||||
#define flush_dcache_folio flush_dcache_folio
|
||||
|
||||
|
||||
@@ -46,10 +46,9 @@ CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT2_FS_XATTR=y
|
||||
CONFIG_EXT2_FS_POSIX_ACL=y
|
||||
CONFIG_EXT2_FS_SECURITY=y
|
||||
CONFIG_EXT3_FS=y
|
||||
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
|
||||
CONFIG_EXT3_FS_POSIX_ACL=y
|
||||
CONFIG_EXT3_FS_SECURITY=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_QUOTA=y
|
||||
CONFIG_PROC_KCORE=y
|
||||
CONFIG_TMPFS=y
|
||||
|
||||
@@ -72,9 +72,9 @@ CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT2_FS_XATTR=y
|
||||
CONFIG_EXT2_FS_POSIX_ACL=y
|
||||
CONFIG_EXT2_FS_SECURITY=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT3_FS_POSIX_ACL=y
|
||||
CONFIG_EXT3_FS_SECURITY=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
# CONFIG_FILE_LOCKING is not set
|
||||
# CONFIG_DNOTIFY is not set
|
||||
# CONFIG_INOTIFY_USER is not set
|
||||
|
||||
@@ -73,7 +73,7 @@ CONFIG_FB_XILINX=y
|
||||
CONFIG_UIO=y
|
||||
CONFIG_UIO_PDRV_GENIRQ=y
|
||||
CONFIG_UIO_DMEM_GENIRQ=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
# CONFIG_DNOTIFY is not set
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_CRAMFS=y
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user