Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
No conflicts. Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
4aea86b403
1
.gitignore
vendored
1
.gitignore
vendored
@ -39,6 +39,7 @@
|
||||
*.o.*
|
||||
*.patch
|
||||
*.rmeta
|
||||
*.rpm
|
||||
*.rsi
|
||||
*.s
|
||||
*.so
|
||||
|
@ -1,4 +1,4 @@
|
||||
What: /sys/kernel/oops_count
|
||||
What: /sys/kernel/warn_count
|
||||
Date: November 2022
|
||||
KernelVersion: 6.2.0
|
||||
Contact: Linux Kernel Hardening List <linux-hardening@vger.kernel.org>
|
||||
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: ROHM BD71828 Power Management Integrated Circuit LED driver
|
||||
|
||||
maintainers:
|
||||
- Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
|
||||
- Matti Vaittinen <mazziesaccount@gmail.com>
|
||||
|
||||
description: |
|
||||
This module is part of the ROHM BD71828 MFD device. For more details
|
||||
|
@ -21,6 +21,7 @@ properties:
|
||||
- mediatek,mt8173-gce
|
||||
- mediatek,mt8183-gce
|
||||
- mediatek,mt8186-gce
|
||||
- mediatek,mt8188-gce
|
||||
- mediatek,mt8192-gce
|
||||
- mediatek,mt8195-gce
|
||||
|
||||
|
@ -28,6 +28,7 @@ properties:
|
||||
- qcom,sc8180x-apss-shared
|
||||
- qcom,sdm660-apcs-hmss-global
|
||||
- qcom,sdm845-apss-shared
|
||||
- qcom,sm4250-apcs-hmss-global
|
||||
- qcom,sm6125-apcs-hmss-global
|
||||
- qcom,sm6115-apcs-hmss-global
|
||||
- qcom,sm8150-apss-shared
|
||||
|
@ -24,12 +24,14 @@ properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- qcom,sc7280-ipcc
|
||||
- qcom,sc8280xp-ipcc
|
||||
- qcom,sm6350-ipcc
|
||||
- qcom,sm6375-ipcc
|
||||
- qcom,sm8250-ipcc
|
||||
- qcom,sm8350-ipcc
|
||||
- qcom,sm8450-ipcc
|
||||
- qcom,sc7280-ipcc
|
||||
- qcom,sm8550-ipcc
|
||||
- const: qcom,ipcc
|
||||
|
||||
reg:
|
||||
|
42
Documentation/devicetree/bindings/mfd/ampere,smpro.yaml
Normal file
42
Documentation/devicetree/bindings/mfd/ampere,smpro.yaml
Normal file
@ -0,0 +1,42 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mfd/ampere,smpro.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Ampere Altra SMPro firmware driver
|
||||
|
||||
maintainers:
|
||||
- Quan Nguyen <quan@os.amperecomputing.com>
|
||||
|
||||
description: |
|
||||
Ampere Altra SMPro firmware may contain different blocks like hardware
|
||||
monitoring, error monitoring and other miscellaneous features.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- ampere,smpro
|
||||
|
||||
reg:
|
||||
description:
|
||||
I2C device address.
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
smpro@4f {
|
||||
compatible = "ampere,smpro";
|
||||
reg = <0x4f>;
|
||||
};
|
||||
};
|
@ -36,6 +36,9 @@ properties:
|
||||
const: 1
|
||||
|
||||
patternProperties:
|
||||
'^timer@[a-f0-9]+$':
|
||||
$ref: /schemas/timer/brcm,bcmbca-timer.yaml
|
||||
|
||||
'^watchdog@[a-f0-9]+$':
|
||||
$ref: /schemas/watchdog/brcm,bcm7038-wdt.yaml
|
||||
|
||||
@ -54,6 +57,11 @@ examples:
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
timer@0 {
|
||||
compatible = "brcm,bcm63138-timer";
|
||||
reg = <0x0 0x28>;
|
||||
};
|
||||
|
||||
watchdog@28 {
|
||||
compatible = "brcm,bcm7038-wdt";
|
||||
reg = <0x28 0x8>;
|
||||
|
@ -33,11 +33,6 @@ Required properties:
|
||||
"dlg,da9061" for DA9061
|
||||
- reg : Specifies the I2C slave address (this defaults to 0x58 but it can be
|
||||
modified to match the chip's OTP settings).
|
||||
- interrupts : IRQ line information.
|
||||
- interrupt-controller
|
||||
|
||||
See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt for
|
||||
further information on IRQ bindings.
|
||||
|
||||
Optional properties:
|
||||
|
||||
@ -48,6 +43,12 @@ Optional properties:
|
||||
See Documentation/devicetree/bindings/gpio/gpio.txt for further information on
|
||||
GPIO bindings.
|
||||
|
||||
- interrupts : IRQ line information.
|
||||
- interrupt-controller
|
||||
|
||||
See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt for
|
||||
further information on IRQ bindings.
|
||||
|
||||
Sub-nodes:
|
||||
|
||||
- regulators : This node defines the settings for the LDOs and BUCKs.
|
||||
@ -85,7 +86,7 @@ Sub-nodes:
|
||||
|
||||
- onkey : See ../input/da9062-onkey.txt
|
||||
|
||||
- watchdog: See ../watchdog/da9062-watchdog.txt
|
||||
- watchdog: See ../watchdog/da9062-wdt.txt
|
||||
|
||||
- thermal : See ../thermal/da9062-thermal.txt
|
||||
|
||||
|
@ -12,7 +12,8 @@ maintainers:
|
||||
description: |
|
||||
The Ocelot ethernet switch family contains chips that have an internal CPU
|
||||
(VSC7513, VSC7514) and chips that don't (VSC7511, VSC7512). All switches have
|
||||
the option to be controlled externally, which is the purpose of this driver.
|
||||
the option to be controlled externally via external interfaces like SPI or
|
||||
PCIe.
|
||||
|
||||
The switch family is a multi-port networking switch that supports many
|
||||
interfaces. Additionally, the device can perform pin control, MDIO buses, and
|
||||
@ -61,7 +62,6 @@ required:
|
||||
- reg
|
||||
- '#address-cells'
|
||||
- '#size-cells'
|
||||
- spi-max-frequency
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
|
@ -21,6 +21,7 @@ Required properties:
|
||||
compatible:
|
||||
"mediatek,mt6323" for PMIC MT6323
|
||||
"mediatek,mt6331" for PMIC MT6331 and MT6332
|
||||
"mediatek,mt6357" for PMIC MT6357
|
||||
"mediatek,mt6358" for PMIC MT6358 and MT6366
|
||||
"mediatek,mt6359" for PMIC MT6359
|
||||
"mediatek,mt6397" for PMIC MT6397
|
||||
|
@ -99,10 +99,16 @@ properties:
|
||||
type: object
|
||||
$ref: /schemas/regulator/qcom,spmi-regulator.yaml#
|
||||
|
||||
pwm:
|
||||
type: object
|
||||
$ref: /schemas/leds/leds-qcom-lpg.yaml#
|
||||
|
||||
patternProperties:
|
||||
"^adc@[0-9a-f]+$":
|
||||
type: object
|
||||
$ref: /schemas/iio/adc/qcom,spmi-vadc.yaml#
|
||||
oneOf:
|
||||
- $ref: /schemas/iio/adc/qcom,spmi-iadc.yaml#
|
||||
- $ref: /schemas/iio/adc/qcom,spmi-vadc.yaml#
|
||||
|
||||
"^adc-tm@[0-9a-f]+$":
|
||||
type: object
|
||||
@ -112,11 +118,13 @@ patternProperties:
|
||||
type: object
|
||||
additionalProperties: true # FIXME qcom,pm8916-wcd-analog-codec binding not converted yet
|
||||
|
||||
"extcon@[0-9a-f]+$":
|
||||
"^charger@[0-9a-f]+$":
|
||||
type: object
|
||||
$ref: /schemas/extcon/qcom,pm8941-misc.yaml#
|
||||
oneOf:
|
||||
- $ref: /schemas/power/supply/qcom,pm8941-charger.yaml#
|
||||
- $ref: /schemas/power/supply/qcom,pm8941-coincell.yaml#
|
||||
|
||||
"gpio(s)?@[0-9a-f]+$":
|
||||
"gpio@[0-9a-f]+$":
|
||||
type: object
|
||||
$ref: /schemas/pinctrl/qcom,pmic-gpio.yaml#
|
||||
|
||||
@ -124,10 +132,6 @@ patternProperties:
|
||||
type: object
|
||||
$ref: /schemas/power/reset/qcom,pon.yaml#
|
||||
|
||||
"pwm@[0-9a-f]+$":
|
||||
type: object
|
||||
$ref: /schemas/leds/leds-qcom-lpg.yaml#
|
||||
|
||||
"^rtc@[0-9a-f]+$":
|
||||
type: object
|
||||
$ref: /schemas/rtc/qcom-pm8xxx-rtc.yaml#
|
||||
@ -136,9 +140,17 @@ patternProperties:
|
||||
type: object
|
||||
$ref: /schemas/thermal/qcom,spmi-temp-alarm.yaml#
|
||||
|
||||
"^usb-detect@[0-9a-f]+$":
|
||||
type: object
|
||||
$ref: /schemas/extcon/qcom,pm8941-misc.yaml#
|
||||
|
||||
"^usb-vbus-regulator@[0-9a-f]+$":
|
||||
type: object
|
||||
$ref: /schemas/regulator/qcom,usb-vbus-regulator.yaml#
|
||||
|
||||
"^vibrator@[0-9a-f]+$":
|
||||
type: object
|
||||
additionalProperties: true # FIXME qcom,pm8916-vib binding not converted yet
|
||||
$ref: /schemas/input/qcom,pm8xxx-vib.yaml#
|
||||
|
||||
"^mpps@[0-9a-f]+$":
|
||||
type: object
|
||||
@ -200,7 +212,7 @@ examples:
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pmi8998_gpio: gpios@c000 {
|
||||
pmi8998_gpio: gpio@c000 {
|
||||
compatible = "qcom,pmi8998-gpio", "qcom,spmi-gpio";
|
||||
reg = <0xc000>;
|
||||
gpio-controller;
|
||||
@ -285,7 +297,7 @@ examples:
|
||||
};
|
||||
};
|
||||
|
||||
pm6150_gpio: gpios@c000 {
|
||||
pm6150_gpio: gpio@c000 {
|
||||
compatible = "qcom,pm6150-gpio", "qcom,spmi-gpio";
|
||||
reg = <0xc000>;
|
||||
gpio-controller;
|
||||
|
@ -17,10 +17,12 @@ properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- qcom,msm8976-tcsr
|
||||
- qcom,msm8998-tcsr
|
||||
- qcom,qcs404-tcsr
|
||||
- qcom,sc7180-tcsr
|
||||
- qcom,sc7280-tcsr
|
||||
- qcom,sc8280xp-tcsr
|
||||
- qcom,sdm630-tcsr
|
||||
- qcom,sdm845-tcsr
|
||||
- qcom,sm8150-tcsr
|
||||
|
@ -15,11 +15,15 @@ description: |
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,pm8018
|
||||
- qcom,pm8058
|
||||
- qcom,pm8821
|
||||
- qcom,pm8921
|
||||
oneOf:
|
||||
- enum:
|
||||
- qcom,pm8058
|
||||
- qcom,pm8821
|
||||
- qcom,pm8921
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,pm8018
|
||||
- const: qcom,pm8921
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@ -56,4 +60,23 @@ required:
|
||||
- interrupt-controller
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
ssbi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
pmic@0 {
|
||||
compatible = "qcom,pm8921";
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
|
||||
interrupt-parent = <&tlmm>;
|
||||
interrupts = <32 IRQ_TYPE_EDGE_RISING>;
|
||||
};
|
||||
};
|
||||
...
|
||||
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: ROHM BD71815 Power Management Integrated Circuit
|
||||
|
||||
maintainers:
|
||||
- Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
|
||||
- Matti Vaittinen <mazziesaccount@gmail.com>
|
||||
|
||||
description: |
|
||||
BD71815AGW is a single-chip power management ICs for battery-powered
|
||||
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: ROHM BD71828 Power Management Integrated Circuit
|
||||
|
||||
maintainers:
|
||||
- Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
|
||||
- Matti Vaittinen <mazziesaccount@gmail.com>
|
||||
|
||||
description: |
|
||||
BD71828GW is a single-chip power management IC for battery-powered portable
|
||||
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: ROHM BD71837 Power Management Integrated Circuit
|
||||
|
||||
maintainers:
|
||||
- Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
|
||||
- Matti Vaittinen <mazziesaccount@gmail.com>
|
||||
|
||||
description: |
|
||||
BD71837MWV is programmable Power Management ICs for powering single-core,
|
||||
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: ROHM BD71847 and BD71850 Power Management Integrated Circuit
|
||||
|
||||
maintainers:
|
||||
- Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
|
||||
- Matti Vaittinen <mazziesaccount@gmail.com>
|
||||
|
||||
description: |
|
||||
BD71847AMWV and BD71850MWV are programmable Power Management ICs for powering
|
||||
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: ROHM BD9576MUF and BD9573MUF Power Management Integrated Circuit
|
||||
|
||||
maintainers:
|
||||
- Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
|
||||
- Matti Vaittinen <mazziesaccount@gmail.com>
|
||||
|
||||
description: |
|
||||
BD9576MUF and BD9573MUF are power management ICs primarily intended for
|
||||
|
@ -53,6 +53,7 @@ properties:
|
||||
- microchip,lan966x-cpu-syscon
|
||||
- microchip,sparx5-cpu-syscon
|
||||
- mstar,msc313-pmsleep
|
||||
- nuvoton,wpcm450-shm
|
||||
- rockchip,px30-qos
|
||||
- rockchip,rk3036-qos
|
||||
- rockchip,rk3066-qos
|
||||
|
@ -52,6 +52,9 @@ properties:
|
||||
type: object
|
||||
description: Magnetic reader
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
@ -26,7 +26,9 @@ properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- ti,j7200-system-controller
|
||||
- ti,j721e-system-controller
|
||||
- ti,j721s2-system-controller
|
||||
- const: syscon
|
||||
- const: simple-mfd
|
||||
|
||||
|
@ -40,6 +40,9 @@ properties:
|
||||
clock-names:
|
||||
const: stmmaceth
|
||||
|
||||
phy-supply:
|
||||
description: PHY regulator
|
||||
|
||||
syscon:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
|
@ -16,9 +16,6 @@ description: |
|
||||
8k has a second unit which provides an interface with the xMDIO bus. This
|
||||
driver handles these interfaces.
|
||||
|
||||
allOf:
|
||||
- $ref: "mdio.yaml#"
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
@ -39,13 +36,38 @@ required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
allOf:
|
||||
- $ref: mdio.yaml#
|
||||
|
||||
- if:
|
||||
required:
|
||||
- interrupts
|
||||
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
items:
|
||||
- items:
|
||||
- $ref: /schemas/types.yaml#/definitions/cell
|
||||
- const: 0x84
|
||||
|
||||
else:
|
||||
properties:
|
||||
reg:
|
||||
items:
|
||||
- items:
|
||||
- $ref: /schemas/types.yaml#/definitions/cell
|
||||
- enum:
|
||||
- 0x4
|
||||
- 0x10
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
mdio@d0072004 {
|
||||
compatible = "marvell,orion-mdio";
|
||||
reg = <0xd0072004 0x4>;
|
||||
reg = <0xd0072004 0x84>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
interrupts = <30>;
|
||||
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: ROHM BD99954 Battery charger
|
||||
|
||||
maintainers:
|
||||
- Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
|
||||
- Matti Vaittinen <mazziesaccount@gmail.com>
|
||||
- Markus Laine <markus.laine@fi.rohmeurope.com>
|
||||
- Mikko Mutanen <mikko.mutanen@fi.rohmeurope.com>
|
||||
|
||||
|
@ -35,6 +35,7 @@ properties:
|
||||
- renesas,pwm-r8a77980 # R-Car V3H
|
||||
- renesas,pwm-r8a77990 # R-Car E3
|
||||
- renesas,pwm-r8a77995 # R-Car D3
|
||||
- renesas,pwm-r8a779g0 # R-Car V4H
|
||||
- const: renesas,pwm-rcar
|
||||
|
||||
reg:
|
||||
|
@ -40,6 +40,7 @@ properties:
|
||||
- renesas,tpu-r8a77970 # R-Car V3M
|
||||
- renesas,tpu-r8a77980 # R-Car V3H
|
||||
- renesas,tpu-r8a779a0 # R-Car V3U
|
||||
- renesas,tpu-r8a779g0 # R-Car V4H
|
||||
- const: renesas,tpu
|
||||
|
||||
reg:
|
||||
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: ROHM BD71815 Power Management Integrated Circuit regulators
|
||||
|
||||
maintainers:
|
||||
- Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
|
||||
- Matti Vaittinen <mazziesaccount@gmail.com>
|
||||
|
||||
description: |
|
||||
This module is part of the ROHM BD718215 MFD device. For more details
|
||||
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: ROHM BD71828 Power Management Integrated Circuit regulators
|
||||
|
||||
maintainers:
|
||||
- Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
|
||||
- Matti Vaittinen <mazziesaccount@gmail.com>
|
||||
|
||||
description: |
|
||||
This module is part of the ROHM BD71828 MFD device. For more details
|
||||
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: ROHM BD71837 Power Management Integrated Circuit regulators
|
||||
|
||||
maintainers:
|
||||
- Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
|
||||
- Matti Vaittinen <mazziesaccount@gmail.com>
|
||||
|
||||
description: |
|
||||
List of regulators provided by this controller. BD71837 regulators node
|
||||
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: ROHM BD71847 and BD71850 Power Management Integrated Circuit regulators
|
||||
|
||||
maintainers:
|
||||
- Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
|
||||
- Matti Vaittinen <mazziesaccount@gmail.com>
|
||||
|
||||
description: |
|
||||
List of regulators provided by this controller. BD71847 regulators node
|
||||
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: ROHM BD9576 and BD9573 Power Management Integrated Circuit regulators
|
||||
|
||||
maintainers:
|
||||
- Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
|
||||
- Matti Vaittinen <mazziesaccount@gmail.com>
|
||||
|
||||
description: |
|
||||
This module is part of the ROHM BD9576 MFD device. For more details
|
||||
|
@ -22,6 +22,8 @@ properties:
|
||||
- fsl,imx8mn-cm7
|
||||
- fsl,imx8mp-cm7
|
||||
- fsl,imx8mq-cm4
|
||||
- fsl,imx8qm-cm4
|
||||
- fsl,imx8qxp-cm4
|
||||
- fsl,imx8ulp-cm33
|
||||
- fsl,imx93-cm33
|
||||
|
||||
@ -54,12 +56,26 @@ properties:
|
||||
minItems: 1
|
||||
maxItems: 32
|
||||
|
||||
power-domains:
|
||||
maxItems: 8
|
||||
|
||||
fsl,auto-boot:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description:
|
||||
Indicate whether need to load the default firmware and start the remote
|
||||
processor automatically.
|
||||
|
||||
fsl,entry-address:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
Specify CPU entry address for SCU enabled processor.
|
||||
|
||||
fsl,resource-id:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
This property is to specify the resource id of the remote processor in SoC
|
||||
which supports SCFW
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
|
@ -0,0 +1,135 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/remoteproc/xlnx,zynqmp-r5fss.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Xilinx R5F processor subsystem
|
||||
|
||||
maintainers:
|
||||
- Ben Levinsky <ben.levinsky@amd.com>
|
||||
- Tanmay Shah <tanmay.shah@amd.com>
|
||||
|
||||
description: |
|
||||
The Xilinx platforms include a pair of Cortex-R5F processors (RPU) for
|
||||
real-time processing based on the Cortex-R5F processor core from ARM.
|
||||
The Cortex-R5F processor implements the Arm v7-R architecture and includes a
|
||||
floating-point unit that implements the Arm VFPv3 instruction set.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: xlnx,zynqmp-r5fss
|
||||
|
||||
xlnx,cluster-mode:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1, 2]
|
||||
description: |
|
||||
The RPU MPCore can operate in split mode (Dual-processor performance), Safety
|
||||
lock-step mode(Both RPU cores execute the same code in lock-step,
|
||||
clock-for-clock) or Single CPU mode (RPU core 0 is held in reset while
|
||||
core 1 runs normally). The processor does not support dynamic configuration.
|
||||
Switching between modes is only permitted immediately after a processor reset.
|
||||
If set to 1 then lockstep mode and if 0 then split mode.
|
||||
If set to 2 then single CPU mode. When not defined, default will be lockstep mode.
|
||||
In summary,
|
||||
0: split mode
|
||||
1: lockstep mode (default)
|
||||
2: single cpu mode
|
||||
|
||||
patternProperties:
|
||||
"^r5f-[a-f0-9]+$":
|
||||
type: object
|
||||
description: |
|
||||
The RPU is located in the Low Power Domain of the Processor Subsystem.
|
||||
Each processor includes separate L1 instruction and data caches and
|
||||
tightly coupled memories (TCM). System memory is cacheable, but the TCM
|
||||
memory space is non-cacheable.
|
||||
|
||||
Each RPU contains one 64KB memory and two 32KB memories that
|
||||
are accessed via the TCM A and B port interfaces, for a total of 128KB
|
||||
per processor. In lock-step mode, the processor has access to 256KB of
|
||||
TCM memory.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: xlnx,zynqmp-r5f
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
mboxes:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: mailbox channel to send data to RPU
|
||||
- description: mailbox channel to receive data from RPU
|
||||
|
||||
mbox-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: tx
|
||||
- const: rx
|
||||
|
||||
sram:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
minItems: 1
|
||||
maxItems: 8
|
||||
items:
|
||||
maxItems: 1
|
||||
description: |
|
||||
phandles to one or more reserved on-chip SRAM regions. Other than TCM,
|
||||
the RPU can execute instructions and access data from the OCM memory,
|
||||
the main DDR memory, and other system memories.
|
||||
|
||||
The regions should be defined as child nodes of the respective SRAM
|
||||
node, and should be defined as per the generic bindings in
|
||||
Documentation/devicetree/bindings/sram/sram.yaml
|
||||
|
||||
memory-region:
|
||||
description: |
|
||||
List of phandles to the reserved memory regions associated with the
|
||||
remoteproc device. This is variable and describes the memories shared with
|
||||
the remote processor (e.g. remoteproc firmware and carveouts, rpmsg
|
||||
vrings, ...). This reserved memory region will be allocated in DDR memory.
|
||||
minItems: 1
|
||||
maxItems: 8
|
||||
items:
|
||||
- description: region used for RPU firmware image section
|
||||
- description: vdev buffer
|
||||
- description: vring0
|
||||
- description: vring1
|
||||
additionalItems: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- power-domains
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
remoteproc {
|
||||
compatible = "xlnx,zynqmp-r5fss";
|
||||
xlnx,cluster-mode = <1>;
|
||||
|
||||
r5f-0 {
|
||||
compatible = "xlnx,zynqmp-r5f";
|
||||
power-domains = <&zynqmp_firmware 0x7>;
|
||||
memory-region = <&rproc_0_fw_image>, <&rpu0vdev0buffer>, <&rpu0vdev0vring0>, <&rpu0vdev0vring1>;
|
||||
mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>;
|
||||
mbox-names = "tx", "rx";
|
||||
};
|
||||
|
||||
r5f-1 {
|
||||
compatible = "xlnx,zynqmp-r5f";
|
||||
power-domains = <&zynqmp_firmware 0x8>;
|
||||
memory-region = <&rproc_1_fw_image>, <&rpu1vdev0buffer>, <&rpu1vdev0vring0>, <&rpu1vdev0vring1>;
|
||||
mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>;
|
||||
mbox-names = "tx", "rx";
|
||||
};
|
||||
};
|
||||
...
|
@ -38,6 +38,7 @@ properties:
|
||||
- fsl,imx8mq-sai
|
||||
- fsl,imx8qm-sai
|
||||
- fsl,imx8ulp-sai
|
||||
- fsl,imx93-sai
|
||||
- fsl,vf610-sai
|
||||
|
||||
reg:
|
||||
|
@ -0,0 +1,40 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/timer/brcm,bcmbca-timer.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Broadcom Broadband SoC timer
|
||||
|
||||
maintainers:
|
||||
- Rafał Miłecki <rafal@milecki.pl>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: brcm,bcm6345-timer
|
||||
description: >
|
||||
An old block with 3 timers.
|
||||
|
||||
It can be found in BCM6345, BCM6838 and BCM63268.
|
||||
- const: brcm,bcm63138-timer
|
||||
description: >
|
||||
Updated block with 4 timers and control regs at the beginning.
|
||||
|
||||
It can be found in newer SoCs, e.g. BCM63138, BCM63148, BCM63381,
|
||||
BCM68360, BCM6848, BCM6858, BCM4908.
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
examples:
|
||||
- |
|
||||
timer@fffe0200 {
|
||||
compatible = "brcm,bcm6345-timer";
|
||||
reg = <0xfffe0200 0x1c>;
|
||||
};
|
@ -25,6 +25,11 @@ versions up to 3.1. File system type to use on mount is *ntfs3*.
|
||||
Note: Applied to empty files, this allows to switch type between
|
||||
sparse(0x200), compressed(0x800) and normal.
|
||||
|
||||
- *system.ntfs_attrib_be* gets/sets ntfs file/dir attributes.
|
||||
|
||||
Same value as system.ntfs_attrib but always represent as big-endian
|
||||
(endianness of system.ntfs_attrib is the same as of the CPU).
|
||||
|
||||
Mount Options
|
||||
=============
|
||||
|
||||
@ -75,6 +80,20 @@ this table marked with no it means default is without **no**.
|
||||
- Files with the Windows-specific SYSTEM (FILE_ATTRIBUTE_SYSTEM) attribute
|
||||
will be marked as system immutable files.
|
||||
|
||||
* - hide_dot_files
|
||||
- Updates the Windows-specific HIDDEN (FILE_ATTRIBUTE_HIDDEN) attribute
|
||||
when creating and moving or renaming files. Files whose names start
|
||||
with a dot will have the HIDDEN attribute set and files whose names
|
||||
do not start with a dot will have it unset.
|
||||
|
||||
* - windows_names
|
||||
- Prevents the creation of files and directories with a name not allowed
|
||||
by Windows, either because it contains some not allowed character (which
|
||||
are the characters " * / : < > ? \\ | and those whose code is less than
|
||||
0x20), because the name (with or without extension) is a reserved file
|
||||
name (CON, AUX, NUL, PRN, LPT1-9, COM1-9) or because the last character
|
||||
is a space or a dot. Existing such files can still be read and renamed.
|
||||
|
||||
* - discard
|
||||
- Enable support of the TRIM command for improved performance on delete
|
||||
operations, which is recommended for use with the solid-state drives
|
||||
|
@ -104,3 +104,4 @@ to do something different in the near future.
|
||||
../riscv/patch-acceptance
|
||||
../driver-api/media/maintainer-entry-profile
|
||||
../driver-api/vfio-pci-device-specific-driver-acceptance
|
||||
../nvme/feature-and-quirk-policy
|
||||
|
77
Documentation/nvme/feature-and-quirk-policy.rst
Normal file
77
Documentation/nvme/feature-and-quirk-policy.rst
Normal file
@ -0,0 +1,77 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
=======================================
|
||||
Linux NVMe feature and and quirk policy
|
||||
=======================================
|
||||
|
||||
This file explains the policy used to decide what is supported by the
|
||||
Linux NVMe driver and what is not.
|
||||
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
NVM Express is an open collection of standards and information.
|
||||
|
||||
The Linux NVMe host driver in drivers/nvme/host/ supports devices
|
||||
implementing the NVM Express (NVMe) family of specifications, which
|
||||
currently consists of a number of documents:
|
||||
|
||||
- the NVMe Base specification
|
||||
- various Command Set specifications (e.g. NVM Command Set)
|
||||
- various Transport specifications (e.g. PCIe, Fibre Channel, RDMA, TCP)
|
||||
- the NVMe Management Interface specification
|
||||
|
||||
See https://nvmexpress.org/developers/ for the NVMe specifications.
|
||||
|
||||
|
||||
Supported features
|
||||
==================
|
||||
|
||||
NVMe is a large suite of specifications, and contains features that are only
|
||||
useful or suitable for specific use-cases. It is important to note that Linux
|
||||
does not aim to implement every feature in the specification. Every additional
|
||||
feature implemented introduces more code, more maintenance and potentially more
|
||||
bugs. Hence there is an inherent tradeoff between functionality and
|
||||
maintainability of the NVMe host driver.
|
||||
|
||||
Any feature implemented in the Linux NVMe host driver must support the
|
||||
following requirements:
|
||||
|
||||
1. The feature is specified in a release version of an official NVMe
|
||||
specification, or in a ratified Technical Proposal (TP) that is
|
||||
available on NVMe website. Or if it is not directly related to the
|
||||
on-wire protocol, does not contradict any of the NVMe specifications.
|
||||
2. Does not conflict with the Linux architecture, nor the design of the
|
||||
NVMe host driver.
|
||||
3. Has a clear, indisputable value-proposition and a wide consensus across
|
||||
the community.
|
||||
|
||||
Vendor specific extensions are generally not supported in the NVMe host
|
||||
driver.
|
||||
|
||||
It is strongly recommended to work with the Linux NVMe and block layer
|
||||
maintainers and get feedback on specification changes that are intended
|
||||
to be used by the Linux NVMe host driver in order to avoid conflict at a
|
||||
later stage.
|
||||
|
||||
|
||||
Quirks
|
||||
======
|
||||
|
||||
Sometimes implementations of open standards fail to correctly implement parts
|
||||
of the standards. Linux uses identifier-based quirks to work around such
|
||||
implementation bugs. The intent of quirks is to deal with widely available
|
||||
hardware, usually consumer, which Linux users can't use without these quirks.
|
||||
Typically these implementations are not or only superficially tested with Linux
|
||||
by the hardware manufacturer.
|
||||
|
||||
The Linux NVMe maintainers decide ad hoc whether to quirk implementations
|
||||
based on the impact of the problem to Linux users and how it impacts
|
||||
maintainability of the driver. In general quirks are a last resort, if no
|
||||
firmware updates or other workarounds are available from the vendor.
|
||||
|
||||
Quirks will not be added to the Linux kernel for hardware that isn't available
|
||||
on the mass market. Hardware that fails qualification for enterprise Linux
|
||||
distributions, ChromeOS, Android or other consumers of the Linux kernel
|
||||
should be fixed before it is shipped instead of relying on Linux quirks.
|
@ -2,9 +2,9 @@
|
||||
|
||||
.. _netdev-FAQ:
|
||||
|
||||
==========
|
||||
netdev FAQ
|
||||
==========
|
||||
=============================
|
||||
Networking subsystem (netdev)
|
||||
=============================
|
||||
|
||||
tl;dr
|
||||
-----
|
||||
@ -15,14 +15,15 @@ tl;dr
|
||||
- don't repost your patches within one 24h period
|
||||
- reverse xmas tree
|
||||
|
||||
What is netdev?
|
||||
---------------
|
||||
It is a mailing list for all network-related Linux stuff. This
|
||||
netdev
|
||||
------
|
||||
|
||||
netdev is a mailing list for all network-related Linux stuff. This
|
||||
includes anything found under net/ (i.e. core code like IPv6) and
|
||||
drivers/net (i.e. hardware specific drivers) in the Linux source tree.
|
||||
|
||||
Note that some subsystems (e.g. wireless drivers) which have a high
|
||||
volume of traffic have their own specific mailing lists.
|
||||
volume of traffic have their own specific mailing lists and trees.
|
||||
|
||||
The netdev list is managed (like many other Linux mailing lists) through
|
||||
VGER (http://vger.kernel.org/) with archives available at
|
||||
@ -32,32 +33,10 @@ Aside from subsystems like those mentioned above, all network-related
|
||||
Linux development (i.e. RFC, review, comments, etc.) takes place on
|
||||
netdev.
|
||||
|
||||
How do the changes posted to netdev make their way into Linux?
|
||||
--------------------------------------------------------------
|
||||
There are always two trees (git repositories) in play. Both are
|
||||
driven by David Miller, the main network maintainer. There is the
|
||||
``net`` tree, and the ``net-next`` tree. As you can probably guess from
|
||||
the names, the ``net`` tree is for fixes to existing code already in the
|
||||
mainline tree from Linus, and ``net-next`` is where the new code goes
|
||||
for the future release. You can find the trees here:
|
||||
Development cycle
|
||||
-----------------
|
||||
|
||||
- https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git
|
||||
- https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git
|
||||
|
||||
How do I indicate which tree (net vs. net-next) my patch should be in?
|
||||
----------------------------------------------------------------------
|
||||
To help maintainers and CI bots you should explicitly mark which tree
|
||||
your patch is targeting. Assuming that you use git, use the prefix
|
||||
flag::
|
||||
|
||||
git format-patch --subject-prefix='PATCH net-next' start..finish
|
||||
|
||||
Use ``net`` instead of ``net-next`` (always lower case) in the above for
|
||||
bug-fix ``net`` content.
|
||||
|
||||
How often do changes from these trees make it to the mainline Linus tree?
|
||||
-------------------------------------------------------------------------
|
||||
To understand this, you need to know a bit of background information on
|
||||
Here is a bit of background information on
|
||||
the cadence of Linux development. Each new release starts off with a
|
||||
two week "merge window" where the main maintainers feed their new stuff
|
||||
to Linus for merging into the mainline tree. After the two weeks, the
|
||||
@ -69,9 +48,33 @@ rc2 is released. This repeats on a roughly weekly basis until rc7
|
||||
state of churn), and a week after the last vX.Y-rcN was done, the
|
||||
official vX.Y is released.
|
||||
|
||||
Relating that to netdev: At the beginning of the 2-week merge window,
|
||||
the ``net-next`` tree will be closed - no new changes/features. The
|
||||
accumulated new content of the past ~10 weeks will be passed onto
|
||||
To find out where we are now in the cycle - load the mainline (Linus)
|
||||
page here:
|
||||
|
||||
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
|
||||
|
||||
and note the top of the "tags" section. If it is rc1, it is early in
|
||||
the dev cycle. If it was tagged rc7 a week ago, then a release is
|
||||
probably imminent. If the most recent tag is a final release tag
|
||||
(without an ``-rcN`` suffix) - we are most likely in a merge window
|
||||
and ``net-next`` is closed.
|
||||
|
||||
git trees and patch flow
|
||||
------------------------
|
||||
|
||||
There are two networking trees (git repositories) in play. Both are
|
||||
driven by David Miller, the main network maintainer. There is the
|
||||
``net`` tree, and the ``net-next`` tree. As you can probably guess from
|
||||
the names, the ``net`` tree is for fixes to existing code already in the
|
||||
mainline tree from Linus, and ``net-next`` is where the new code goes
|
||||
for the future release. You can find the trees here:
|
||||
|
||||
- https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git
|
||||
- https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git
|
||||
|
||||
Relating that to kernel development: At the beginning of the 2-week
|
||||
merge window, the ``net-next`` tree will be closed - no new changes/features.
|
||||
The accumulated new content of the past ~10 weeks will be passed onto
|
||||
mainline/Linus via a pull request for vX.Y -- at the same time, the
|
||||
``net`` tree will start accumulating fixes for this pulled content
|
||||
relating to vX.Y
|
||||
@ -103,22 +106,14 @@ focus for ``net`` is on stabilization and bug fixes.
|
||||
|
||||
Finally, the vX.Y gets released, and the whole cycle starts over.
|
||||
|
||||
So where are we now in this cycle?
|
||||
----------------------------------
|
||||
netdev patch review
|
||||
-------------------
|
||||
|
||||
Load the mainline (Linus) page here:
|
||||
Patch status
|
||||
~~~~~~~~~~~~
|
||||
|
||||
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
|
||||
|
||||
and note the top of the "tags" section. If it is rc1, it is early in
|
||||
the dev cycle. If it was tagged rc7 a week ago, then a release is
|
||||
probably imminent. If the most recent tag is a final release tag
|
||||
(without an ``-rcN`` suffix) - we are most likely in a merge window
|
||||
and ``net-next`` is closed.
|
||||
|
||||
How can I tell the status of a patch I've sent?
|
||||
-----------------------------------------------
|
||||
Start by looking at the main patchworks queue for netdev:
|
||||
Status of a patch can be checked by looking at the main patchwork
|
||||
queue for netdev:
|
||||
|
||||
https://patchwork.kernel.org/project/netdevbpf/list/
|
||||
|
||||
@ -127,8 +122,20 @@ patch. Patches are indexed by the ``Message-ID`` header of the emails
|
||||
which carried them so if you have trouble finding your patch append
|
||||
the value of ``Message-ID`` to the URL above.
|
||||
|
||||
How long before my patch is accepted?
|
||||
-------------------------------------
|
||||
Updating patch status
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
It may be tempting to help the maintainers and update the state of your
|
||||
own patches when you post a new version or spot a bug. Please **do not**
|
||||
do that.
|
||||
Interfering with the patch status on patchwork will only cause confusion. Leave
|
||||
it to the maintainer to figure out what is the most recent and current
|
||||
version that should be applied. If there is any doubt, the maintainer
|
||||
will reply and ask what should be done.
|
||||
|
||||
Review timelines
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Generally speaking, the patches get triaged quickly (in less than
|
||||
48h). But be patient, if your patch is active in patchwork (i.e. it's
|
||||
listed on the project's patch list) the chances it was missed are close to zero.
|
||||
@ -136,116 +143,47 @@ Asking the maintainer for status updates on your
|
||||
patch is a good way to ensure your patch is ignored or pushed to the
|
||||
bottom of the priority list.
|
||||
|
||||
Should I directly update patchwork state of my own patches?
|
||||
-----------------------------------------------------------
|
||||
It may be tempting to help the maintainers and update the state of your
|
||||
own patches when you post a new version or spot a bug. Please do not do that.
|
||||
Interfering with the patch status on patchwork will only cause confusion. Leave
|
||||
it to the maintainer to figure out what is the most recent and current
|
||||
version that should be applied. If there is any doubt, the maintainer
|
||||
will reply and ask what should be done.
|
||||
Partial resends
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
How do I divide my work into patches?
|
||||
-------------------------------------
|
||||
|
||||
Put yourself in the shoes of the reviewer. Each patch is read separately
|
||||
and therefore should constitute a comprehensible step towards your stated
|
||||
goal.
|
||||
|
||||
Avoid sending series longer than 15 patches. Larger series takes longer
|
||||
to review as reviewers will defer looking at it until they find a large
|
||||
chunk of time. A small series can be reviewed in a short time, so Maintainers
|
||||
just do it. As a result, a sequence of smaller series gets merged quicker and
|
||||
with better review coverage. Re-posting large series also increases the mailing
|
||||
list traffic.
|
||||
|
||||
I made changes to only a few patches in a patch series should I resend only those changed?
|
||||
------------------------------------------------------------------------------------------
|
||||
No, please resend the entire patch series and make sure you do number your
|
||||
Please always resend the entire patch series and make sure you do number your
|
||||
patches such that it is clear this is the latest and greatest set of patches
|
||||
that can be applied.
|
||||
that can be applied. Do not try to resend just the patches which changed.
|
||||
|
||||
I have received review feedback, when should I post a revised version of the patches?
|
||||
-------------------------------------------------------------------------------------
|
||||
Allow at least 24 hours to pass between postings. This will ensure reviewers
|
||||
from all geographical locations have a chance to chime in. Do not wait
|
||||
too long (weeks) between postings either as it will make it harder for reviewers
|
||||
to recall all the context.
|
||||
Handling misapplied patches
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Make sure you address all the feedback in your new posting. Do not post a new
|
||||
version of the code if the discussion about the previous version is still
|
||||
ongoing, unless directly instructed by a reviewer.
|
||||
|
||||
I submitted multiple versions of a patch series and it looks like a version other than the last one has been accepted, what should I do?
|
||||
----------------------------------------------------------------------------------------------------------------------------------------
|
||||
Occasionally a patch series gets applied before receiving critical feedback,
|
||||
or the wrong version of a series gets applied.
|
||||
There is no revert possible, once it is pushed out, it stays like that.
|
||||
Please send incremental versions on top of what has been merged in order to fix
|
||||
the patches the way they would look like if your latest patch series was to be
|
||||
merged.
|
||||
|
||||
Are there special rules regarding stable submissions on netdev?
|
||||
---------------------------------------------------------------
|
||||
Stable tree
|
||||
~~~~~~~~~~~
|
||||
|
||||
While it used to be the case that netdev submissions were not supposed
|
||||
to carry explicit ``CC: stable@vger.kernel.org`` tags that is no longer
|
||||
the case today. Please follow the standard stable rules in
|
||||
:ref:`Documentation/process/stable-kernel-rules.rst <stable_kernel_rules>`,
|
||||
and make sure you include appropriate Fixes tags!
|
||||
|
||||
Is the comment style convention different for the networking content?
|
||||
---------------------------------------------------------------------
|
||||
Yes, in a largely trivial way. Instead of this::
|
||||
Security fixes
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
/*
|
||||
* foobar blah blah blah
|
||||
* another line of text
|
||||
*/
|
||||
|
||||
it is requested that you make it look like this::
|
||||
|
||||
/* foobar blah blah blah
|
||||
* another line of text
|
||||
*/
|
||||
|
||||
What is "reverse xmas tree"?
|
||||
----------------------------
|
||||
|
||||
Netdev has a convention for ordering local variables in functions.
|
||||
Order the variable declaration lines longest to shortest, e.g.::
|
||||
|
||||
struct scatterlist *sg;
|
||||
struct sk_buff *skb;
|
||||
int err, i;
|
||||
|
||||
If there are dependencies between the variables preventing the ordering
|
||||
move the initialization out of line.
|
||||
|
||||
I am working in existing code which uses non-standard formatting. Which formatting should I use?
|
||||
------------------------------------------------------------------------------------------------
|
||||
Make your code follow the most recent guidelines, so that eventually all code
|
||||
in the domain of netdev is in the preferred format.
|
||||
|
||||
I found a bug that might have possible security implications or similar. Should I mail the main netdev maintainer off-list?
|
||||
---------------------------------------------------------------------------------------------------------------------------
|
||||
No. The current netdev maintainer has consistently requested that
|
||||
Do not email netdev maintainers directly if you think you discovered
|
||||
a bug that might have possible security implications.
|
||||
The current netdev maintainer has consistently requested that
|
||||
people use the mailing lists and not reach out directly. If you aren't
|
||||
OK with that, then perhaps consider mailing security@kernel.org or
|
||||
reading about http://oss-security.openwall.org/wiki/mailing-lists/distros
|
||||
as possible alternative mechanisms.
|
||||
|
||||
What level of testing is expected before I submit my change?
|
||||
------------------------------------------------------------
|
||||
At the very minimum your changes must survive an ``allyesconfig`` and an
|
||||
``allmodconfig`` build with ``W=1`` set without new warnings or failures.
|
||||
|
||||
Ideally you will have done run-time testing specific to your change,
|
||||
and the patch series contains a set of kernel selftest for
|
||||
``tools/testing/selftests/net`` or using the KUnit framework.
|
||||
Co-posting changes to user space components
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You are expected to test your changes on top of the relevant networking
|
||||
tree (``net`` or ``net-next``) and not e.g. a stable tree or ``linux-next``.
|
||||
|
||||
How do I post corresponding changes to user space components?
|
||||
-------------------------------------------------------------
|
||||
User space code exercising kernel features should be posted
|
||||
alongside kernel patches. This gives reviewers a chance to see
|
||||
how any new interface is used and how well it works.
|
||||
@ -270,42 +208,10 @@ to the mailing list, e.g.::
|
||||
Posting as one thread is discouraged because it confuses patchwork
|
||||
(as of patchwork 2.2.2).
|
||||
|
||||
Can I reproduce the checks from patchwork on my local machine?
|
||||
--------------------------------------------------------------
|
||||
Preparing changes
|
||||
-----------------
|
||||
|
||||
Checks in patchwork are mostly simple wrappers around existing kernel
|
||||
scripts, the sources are available at:
|
||||
|
||||
https://github.com/kuba-moo/nipa/tree/master/tests
|
||||
|
||||
Running all the builds and checks locally is a pain, can I post my patches and have the patchwork bot validate them?
|
||||
--------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
No, you must ensure that your patches are ready by testing them locally
|
||||
before posting to the mailing list. The patchwork build bot instance
|
||||
gets overloaded very easily and netdev@vger really doesn't need more
|
||||
traffic if we can help it.
|
||||
|
||||
netdevsim is great, can I extend it for my out-of-tree tests?
|
||||
-------------------------------------------------------------
|
||||
|
||||
No, ``netdevsim`` is a test vehicle solely for upstream tests.
|
||||
(Please add your tests under ``tools/testing/selftests/``.)
|
||||
|
||||
We also give no guarantees that ``netdevsim`` won't change in the future
|
||||
in a way which would break what would normally be considered uAPI.
|
||||
|
||||
Is netdevsim considered a "user" of an API?
|
||||
-------------------------------------------
|
||||
|
||||
Linux kernel has a long standing rule that no API should be added unless
|
||||
it has a real, in-tree user. Mock-ups and tests based on ``netdevsim`` are
|
||||
strongly encouraged when adding new APIs, but ``netdevsim`` in itself
|
||||
is **not** considered a use case/user.
|
||||
|
||||
Any other tips to help ensure my net/net-next patch gets OK'd?
|
||||
--------------------------------------------------------------
|
||||
Attention to detail. Re-read your own work as if you were the
|
||||
Attention to detail is important. Re-read your own work as if you were the
|
||||
reviewer. You can start with using ``checkpatch.pl``, perhaps even with
|
||||
the ``--strict`` flag. But do not be mindlessly robotic in doing so.
|
||||
If your change is a bug fix, make sure your commit log indicates the
|
||||
@ -320,10 +226,133 @@ Finally, go back and read
|
||||
:ref:`Documentation/process/submitting-patches.rst <submittingpatches>`
|
||||
to be sure you are not repeating some common mistake documented there.
|
||||
|
||||
My company uses peer feedback in employee performance reviews. Can I ask netdev maintainers for feedback?
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
Indicating target tree
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Yes, especially if you spend significant amount of time reviewing code
|
||||
To help maintainers and CI bots you should explicitly mark which tree
|
||||
your patch is targeting. Assuming that you use git, use the prefix
|
||||
flag::
|
||||
|
||||
git format-patch --subject-prefix='PATCH net-next' start..finish
|
||||
|
||||
Use ``net`` instead of ``net-next`` (always lower case) in the above for
|
||||
bug-fix ``net`` content.
|
||||
|
||||
Dividing work into patches
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Put yourself in the shoes of the reviewer. Each patch is read separately
|
||||
and therefore should constitute a comprehensible step towards your stated
|
||||
goal.
|
||||
|
||||
Avoid sending series longer than 15 patches. Larger series takes longer
|
||||
to review as reviewers will defer looking at it until they find a large
|
||||
chunk of time. A small series can be reviewed in a short time, so Maintainers
|
||||
just do it. As a result, a sequence of smaller series gets merged quicker and
|
||||
with better review coverage. Re-posting large series also increases the mailing
|
||||
list traffic.
|
||||
|
||||
Multi-line comments
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Comment style convention is slightly different for networking and most of
|
||||
the tree. Instead of this::
|
||||
|
||||
/*
|
||||
* foobar blah blah blah
|
||||
* another line of text
|
||||
*/
|
||||
|
||||
it is requested that you make it look like this::
|
||||
|
||||
/* foobar blah blah blah
|
||||
* another line of text
|
||||
*/
|
||||
|
||||
Local variable ordering ("reverse xmas tree", "RCS")
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Netdev has a convention for ordering local variables in functions.
|
||||
Order the variable declaration lines longest to shortest, e.g.::
|
||||
|
||||
struct scatterlist *sg;
|
||||
struct sk_buff *skb;
|
||||
int err, i;
|
||||
|
||||
If there are dependencies between the variables preventing the ordering
|
||||
move the initialization out of line.
|
||||
|
||||
Format precedence
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
When working in existing code which uses nonstandard formatting make
|
||||
your code follow the most recent guidelines, so that eventually all code
|
||||
in the domain of netdev is in the preferred format.
|
||||
|
||||
Resending after review
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Allow at least 24 hours to pass between postings. This will ensure reviewers
|
||||
from all geographical locations have a chance to chime in. Do not wait
|
||||
too long (weeks) between postings either as it will make it harder for reviewers
|
||||
to recall all the context.
|
||||
|
||||
Make sure you address all the feedback in your new posting. Do not post a new
|
||||
version of the code if the discussion about the previous version is still
|
||||
ongoing, unless directly instructed by a reviewer.
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
Expected level of testing
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
At the very minimum your changes must survive an ``allyesconfig`` and an
|
||||
``allmodconfig`` build with ``W=1`` set without new warnings or failures.
|
||||
|
||||
Ideally you will have done run-time testing specific to your change,
|
||||
and the patch series contains a set of kernel selftest for
|
||||
``tools/testing/selftests/net`` or using the KUnit framework.
|
||||
|
||||
You are expected to test your changes on top of the relevant networking
|
||||
tree (``net`` or ``net-next``) and not e.g. a stable tree or ``linux-next``.
|
||||
|
||||
patchwork checks
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Checks in patchwork are mostly simple wrappers around existing kernel
|
||||
scripts, the sources are available at:
|
||||
|
||||
https://github.com/kuba-moo/nipa/tree/master/tests
|
||||
|
||||
**Do not** post your patches just to run them through the checks.
|
||||
You must ensure that your patches are ready by testing them locally
|
||||
before posting to the mailing list. The patchwork build bot instance
|
||||
gets overloaded very easily and netdev@vger really doesn't need more
|
||||
traffic if we can help it.
|
||||
|
||||
netdevsim
|
||||
~~~~~~~~~
|
||||
|
||||
``netdevsim`` is a test driver which can be used to exercise driver
|
||||
configuration APIs without requiring capable hardware.
|
||||
Mock-ups and tests based on ``netdevsim`` are strongly encouraged when
|
||||
adding new APIs, but ``netdevsim`` in itself is **not** considered
|
||||
a use case/user. You must also implement the new APIs in a real driver.
|
||||
|
||||
We give no guarantees that ``netdevsim`` won't change in the future
|
||||
in a way which would break what would normally be considered uAPI.
|
||||
|
||||
``netdevsim`` is reserved for use by upstream tests only, so any
|
||||
new ``netdevsim`` features must be accompanied by selftests under
|
||||
``tools/testing/selftests/``.
|
||||
|
||||
Testimonials / feedback
|
||||
-----------------------
|
||||
|
||||
Some companies use peer feedback in employee performance reviews.
|
||||
Please feel free to request feedback from netdev maintainers,
|
||||
especially if you spend significant amount of time reviewing code
|
||||
and go out of your way to improve shared infrastructure.
|
||||
|
||||
The feedback must be requested by you, the contributor, and will always
|
||||
|
@ -131,8 +131,7 @@ For example, if the function is non-recursive and is called with a
|
||||
spinlock held, maxactive = 1 should be enough. If the function is
|
||||
non-recursive and can never relinquish the CPU (e.g., via a semaphore
|
||||
or preemption), NR_CPUS should be enough. If maxactive <= 0, it is
|
||||
set to a default value. If CONFIG_PREEMPT is enabled, the default
|
||||
is max(10, 2*NR_CPUS). Otherwise, the default is NR_CPUS.
|
||||
set to a default value: max(10, 2*NR_CPUS).
|
||||
|
||||
It's not a disaster if you set maxactive too low; you'll just miss
|
||||
some probes. In the kretprobe struct, the nmissed field is set to
|
||||
|
@ -58,8 +58,8 @@ Synopsis of kprobe_events
|
||||
NAME=FETCHARG : Set NAME as the argument name of FETCHARG.
|
||||
FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types
|
||||
(u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types
|
||||
(x8/x16/x32/x64), "string", "ustring" and bitfield
|
||||
are supported.
|
||||
(x8/x16/x32/x64), "string", "ustring", "symbol", "symstr"
|
||||
and bitfield are supported.
|
||||
|
||||
(\*1) only for the probe on function entry (offs == 0).
|
||||
(\*2) only for return probe.
|
||||
@ -96,6 +96,10 @@ offset, and container-size (usually 32). The syntax is::
|
||||
|
||||
Symbol type('symbol') is an alias of u32 or u64 type (depends on BITS_PER_LONG)
|
||||
which shows given pointer in "symbol+offset" style.
|
||||
On the other hand, symbol-string type ('symstr') converts the given address to
|
||||
"symbol+offset/symbolsize" style and stores it as a null-terminated string.
|
||||
With 'symstr' type, you can filter the event with wildcard pattern of the
|
||||
symbols, and you don't need to solve symbol name by yourself.
|
||||
For $comm, the default type is "string"; any other type is invalid.
|
||||
|
||||
.. _user_mem_access:
|
||||
|
@ -5343,9 +5343,9 @@ KVM_XEN_ATTR_TYPE_SHARED_INFO
|
||||
32 vCPUs in the shared_info page, KVM does not automatically do so
|
||||
and instead requires that KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO be used
|
||||
explicitly even when the vcpu_info for a given vCPU resides at the
|
||||
"default" location in the shared_info page. This is because KVM is
|
||||
not aware of the Xen CPU id which is used as the index into the
|
||||
vcpu_info[] array, so cannot know the correct default location.
|
||||
"default" location in the shared_info page. This is because KVM may
|
||||
not be aware of the Xen CPU id which is used as the index into the
|
||||
vcpu_info[] array, so may know the correct default location.
|
||||
|
||||
Note that the shared info page may be constantly written to by KVM;
|
||||
it contains the event channel bitmap used to deliver interrupts to
|
||||
@ -5356,23 +5356,29 @@ KVM_XEN_ATTR_TYPE_SHARED_INFO
|
||||
any vCPU has been running or any event channel interrupts can be
|
||||
routed to the guest.
|
||||
|
||||
Setting the gfn to KVM_XEN_INVALID_GFN will disable the shared info
|
||||
page.
|
||||
|
||||
KVM_XEN_ATTR_TYPE_UPCALL_VECTOR
|
||||
Sets the exception vector used to deliver Xen event channel upcalls.
|
||||
This is the HVM-wide vector injected directly by the hypervisor
|
||||
(not through the local APIC), typically configured by a guest via
|
||||
HVM_PARAM_CALLBACK_IRQ.
|
||||
HVM_PARAM_CALLBACK_IRQ. This can be disabled again (e.g. for guest
|
||||
SHUTDOWN_soft_reset) by setting it to zero.
|
||||
|
||||
KVM_XEN_ATTR_TYPE_EVTCHN
|
||||
This attribute is available when the KVM_CAP_XEN_HVM ioctl indicates
|
||||
support for KVM_XEN_HVM_CONFIG_EVTCHN_SEND features. It configures
|
||||
an outbound port number for interception of EVTCHNOP_send requests
|
||||
from the guest. A given sending port number may be directed back
|
||||
to a specified vCPU (by APIC ID) / port / priority on the guest,
|
||||
or to trigger events on an eventfd. The vCPU and priority can be
|
||||
changed by setting KVM_XEN_EVTCHN_UPDATE in a subsequent call,
|
||||
but other fields cannot change for a given sending port. A port
|
||||
mapping is removed by using KVM_XEN_EVTCHN_DEASSIGN in the flags
|
||||
field.
|
||||
from the guest. A given sending port number may be directed back to
|
||||
a specified vCPU (by APIC ID) / port / priority on the guest, or to
|
||||
trigger events on an eventfd. The vCPU and priority can be changed
|
||||
by setting KVM_XEN_EVTCHN_UPDATE in a subsequent call, but but other
|
||||
fields cannot change for a given sending port. A port mapping is
|
||||
removed by using KVM_XEN_EVTCHN_DEASSIGN in the flags field. Passing
|
||||
KVM_XEN_EVTCHN_RESET in the flags field removes all interception of
|
||||
outbound event channels. The values of the flags field are mutually
|
||||
exclusive and cannot be combined as a bitmask.
|
||||
|
||||
KVM_XEN_ATTR_TYPE_XEN_VERSION
|
||||
This attribute is available when the KVM_CAP_XEN_HVM ioctl indicates
|
||||
@ -5388,7 +5394,7 @@ KVM_XEN_ATTR_TYPE_RUNSTATE_UPDATE_FLAG
|
||||
support for KVM_XEN_HVM_CONFIG_RUNSTATE_UPDATE_FLAG. It enables the
|
||||
XEN_RUNSTATE_UPDATE flag which allows guest vCPUs to safely read
|
||||
other vCPUs' vcpu_runstate_info. Xen guests enable this feature via
|
||||
the VM_ASST_TYPE_runstate_update_flag of the HYPERVISOR_vm_assist
|
||||
the VMASST_TYPE_runstate_update_flag of the HYPERVISOR_vm_assist
|
||||
hypercall.
|
||||
|
||||
4.127 KVM_XEN_HVM_GET_ATTR
|
||||
@ -5446,15 +5452,18 @@ KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO
|
||||
As with the shared_info page for the VM, the corresponding page may be
|
||||
dirtied at any time if event channel interrupt delivery is enabled, so
|
||||
userspace should always assume that the page is dirty without relying
|
||||
on dirty logging.
|
||||
on dirty logging. Setting the gpa to KVM_XEN_INVALID_GPA will disable
|
||||
the vcpu_info.
|
||||
|
||||
KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO
|
||||
Sets the guest physical address of an additional pvclock structure
|
||||
for a given vCPU. This is typically used for guest vsyscall support.
|
||||
Setting the gpa to KVM_XEN_INVALID_GPA will disable the structure.
|
||||
|
||||
KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR
|
||||
Sets the guest physical address of the vcpu_runstate_info for a given
|
||||
vCPU. This is how a Xen guest tracks CPU state such as steal time.
|
||||
Setting the gpa to KVM_XEN_INVALID_GPA will disable the runstate area.
|
||||
|
||||
KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT
|
||||
Sets the runstate (RUNSTATE_running/_runnable/_blocked/_offline) of
|
||||
@ -5487,7 +5496,8 @@ KVM_XEN_VCPU_ATTR_TYPE_TIMER
|
||||
This attribute is available when the KVM_CAP_XEN_HVM ioctl indicates
|
||||
support for KVM_XEN_HVM_CONFIG_EVTCHN_SEND features. It sets the
|
||||
event channel port/priority for the VIRQ_TIMER of the vCPU, as well
|
||||
as allowing a pending timer to be saved/restored.
|
||||
as allowing a pending timer to be saved/restored. Setting the timer
|
||||
port to zero disables kernel handling of the singleshot timer.
|
||||
|
||||
KVM_XEN_VCPU_ATTR_TYPE_UPCALL_VECTOR
|
||||
This attribute is available when the KVM_CAP_XEN_HVM ioctl indicates
|
||||
@ -5495,7 +5505,8 @@ KVM_XEN_VCPU_ATTR_TYPE_UPCALL_VECTOR
|
||||
per-vCPU local APIC upcall vector, configured by a Xen guest with
|
||||
the HVMOP_set_evtchn_upcall_vector hypercall. This is typically
|
||||
used by Windows guests, and is distinct from the HVM-wide upcall
|
||||
vector configured with HVM_PARAM_CALLBACK_IRQ.
|
||||
vector configured with HVM_PARAM_CALLBACK_IRQ. It is disabled by
|
||||
setting the vector to zero.
|
||||
|
||||
|
||||
4.129 KVM_XEN_VCPU_GET_ATTR
|
||||
@ -6577,11 +6588,6 @@ Please note that the kernel is allowed to use the kvm_run structure as the
|
||||
primary storage for certain register types. Therefore, the kernel may use the
|
||||
values in kvm_run even if the corresponding bit in kvm_dirty_regs is not set.
|
||||
|
||||
::
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
6. Capabilities that can be enabled on vCPUs
|
||||
============================================
|
||||
|
@ -16,17 +16,26 @@ The acquisition orders for mutexes are as follows:
|
||||
- kvm->slots_lock is taken outside kvm->irq_lock, though acquiring
|
||||
them together is quite rare.
|
||||
|
||||
- Unlike kvm->slots_lock, kvm->slots_arch_lock is released before
|
||||
synchronize_srcu(&kvm->srcu). Therefore kvm->slots_arch_lock
|
||||
can be taken inside a kvm->srcu read-side critical section,
|
||||
while kvm->slots_lock cannot.
|
||||
|
||||
- kvm->mn_active_invalidate_count ensures that pairs of
|
||||
invalidate_range_start() and invalidate_range_end() callbacks
|
||||
use the same memslots array. kvm->slots_lock and kvm->slots_arch_lock
|
||||
are taken on the waiting side in install_new_memslots, so MMU notifiers
|
||||
must not take either kvm->slots_lock or kvm->slots_arch_lock.
|
||||
|
||||
For SRCU:
|
||||
|
||||
- ``synchronize_srcu(&kvm->srcu)`` is called _inside_
|
||||
the kvm->slots_lock critical section, therefore kvm->slots_lock
|
||||
cannot be taken inside a kvm->srcu read-side critical section.
|
||||
Instead, kvm->slots_arch_lock is released before the call
|
||||
to ``synchronize_srcu()`` and _can_ be taken inside a
|
||||
kvm->srcu read-side critical section.
|
||||
|
||||
- kvm->lock is taken inside kvm->srcu, therefore
|
||||
``synchronize_srcu(&kvm->srcu)`` cannot be called inside
|
||||
a kvm->lock critical section. If you cannot delay the
|
||||
call until after kvm->lock is released, use ``call_srcu``.
|
||||
|
||||
On x86:
|
||||
|
||||
- vcpu->mutex is taken outside kvm->arch.hyperv.hv_lock
|
||||
|
@ -10878,6 +10878,7 @@ T: git git://git.kernel.dk/liburing
|
||||
F: io_uring/
|
||||
F: include/linux/io_uring.h
|
||||
F: include/linux/io_uring_types.h
|
||||
F: include/trace/events/io_uring.h
|
||||
F: include/uapi/linux/io_uring.h
|
||||
F: tools/io_uring/
|
||||
|
||||
@ -11467,7 +11468,7 @@ F: arch/x86/kvm/hyperv.*
|
||||
F: arch/x86/kvm/kvm_onhyperv.*
|
||||
F: arch/x86/kvm/svm/hyperv.*
|
||||
F: arch/x86/kvm/svm/svm_onhyperv.*
|
||||
F: arch/x86/kvm/vmx/evmcs.*
|
||||
F: arch/x86/kvm/vmx/hyperv.*
|
||||
|
||||
KVM X86 Xen (KVM/Xen)
|
||||
M: David Woodhouse <dwmw2@infradead.org>
|
||||
@ -14915,6 +14916,7 @@ L: linux-nvme@lists.infradead.org
|
||||
S: Supported
|
||||
W: http://git.infradead.org/nvme.git
|
||||
T: git://git.infradead.org/nvme.git
|
||||
F: Documentation/nvme/
|
||||
F: drivers/nvme/host/
|
||||
F: drivers/nvme/common/
|
||||
F: include/linux/nvme*
|
||||
@ -15336,6 +15338,7 @@ F: drivers/mfd/menelaus.c
|
||||
F: drivers/mfd/palmas.c
|
||||
F: drivers/mfd/tps65217.c
|
||||
F: drivers/mfd/tps65218.c
|
||||
F: drivers/mfd/tps65219.c
|
||||
F: drivers/mfd/tps65910.c
|
||||
F: drivers/mfd/twl-core.[ch]
|
||||
F: drivers/mfd/twl4030*.c
|
||||
@ -22243,7 +22246,9 @@ F: drivers/scsi/vmw_pvscsi.c
|
||||
F: drivers/scsi/vmw_pvscsi.h
|
||||
|
||||
VMWARE VIRTUAL PTP CLOCK DRIVER
|
||||
M: Vivek Thampi <vithampi@vmware.com>
|
||||
M: Srivatsa S. Bhat (VMware) <srivatsa@csail.mit.edu>
|
||||
M: Deep Shah <sdeep@vmware.com>
|
||||
R: Alexey Makhalov <amakhalov@vmware.com>
|
||||
R: VMware PV-Drivers Reviewers <pv-drivers@vmware.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
|
6
Makefile
6
Makefile
@ -1,8 +1,8 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 1
|
||||
PATCHLEVEL = 2
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION =
|
||||
EXTRAVERSION = -rc2
|
||||
NAME = Hurr durr I'ma ninja sloth
|
||||
|
||||
# *DOCUMENTATION*
|
||||
@ -297,7 +297,7 @@ no-compiler-targets := $(no-dot-config-targets) install dtbs_install \
|
||||
headers_install modules_install kernelrelease image_name
|
||||
no-sync-config-targets := $(no-dot-config-targets) %install kernelrelease \
|
||||
image_name
|
||||
single-targets := %.a %.i %.rsi %.ko %.lds %.ll %.lst %.mod %.o %.s %.symtypes %/
|
||||
single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.rsi %.s %.symtypes %/
|
||||
|
||||
config-build :=
|
||||
mixed-build :=
|
||||
|
@ -100,6 +100,22 @@
|
||||
};
|
||||
};
|
||||
|
||||
reserved-memory {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
|
||||
rproc_0_fw_image: memory@3ed00000 {
|
||||
no-map;
|
||||
reg = <0x0 0x3ed00000 0x0 0x40000>;
|
||||
};
|
||||
|
||||
rproc_1_fw_image: memory@3ef00000 {
|
||||
no-map;
|
||||
reg = <0x0 0x3ef00000 0x0 0x40000>;
|
||||
};
|
||||
};
|
||||
|
||||
zynqmp_ipi: zynqmp_ipi {
|
||||
compatible = "xlnx,zynqmp-ipi-mailbox";
|
||||
interrupt-parent = <&gic>;
|
||||
@ -203,6 +219,23 @@
|
||||
ranges;
|
||||
};
|
||||
|
||||
remoteproc {
|
||||
compatible = "xlnx,zynqmp-r5fss";
|
||||
xlnx,cluster-mode = <1>;
|
||||
|
||||
r5f-0 {
|
||||
compatible = "xlnx,zynqmp-r5f";
|
||||
power-domains = <&zynqmp_firmware PD_RPU_0>;
|
||||
memory-region = <&rproc_0_fw_image>;
|
||||
};
|
||||
|
||||
r5f-1 {
|
||||
compatible = "xlnx,zynqmp-r5f";
|
||||
power-domains = <&zynqmp_firmware PD_RPU_1>;
|
||||
memory-region = <&rproc_1_fw_image>;
|
||||
};
|
||||
};
|
||||
|
||||
amba: axi {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <2>;
|
||||
|
@ -38,26 +38,6 @@ static inline char *strncpy(char *dest, const char *src, size_t n)
|
||||
return xdest;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_COLDFIRE
|
||||
#define __HAVE_ARCH_STRCMP
|
||||
static inline int strcmp(const char *cs, const char *ct)
|
||||
{
|
||||
char res;
|
||||
|
||||
asm ("\n"
|
||||
"1: move.b (%0)+,%2\n" /* get *cs */
|
||||
" cmp.b (%1)+,%2\n" /* compare a byte */
|
||||
" jne 2f\n" /* not equal, break out */
|
||||
" tst.b %2\n" /* at end of cs? */
|
||||
" jne 1b\n" /* no, keep going */
|
||||
" jra 3f\n" /* strings are equal */
|
||||
"2: sub.b -(%1),%2\n" /* *cs - *ct */
|
||||
"3:"
|
||||
: "+a" (cs), "+a" (ct), "=d" (res));
|
||||
return res;
|
||||
}
|
||||
#endif /* CONFIG_COLDFIRE */
|
||||
|
||||
#define __HAVE_ARCH_MEMMOVE
|
||||
extern void *memmove(void *, const void *, __kernel_size_t);
|
||||
|
||||
|
@ -109,6 +109,8 @@
|
||||
compatible = "brcm,bcm7038-twd", "simple-mfd", "syscon";
|
||||
reg = <0x10000080 0x30>;
|
||||
ranges = <0x0 0x10000080 0x30>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
timer@0 {
|
||||
compatible = "brcm,bcm6345-timer";
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/mach-ralink/ralink_regs.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
@ -81,7 +82,8 @@ static int __init plat_of_setup(void)
|
||||
__dt_register_buses(soc_info.compatible, "palmbus");
|
||||
|
||||
/* make sure that the reset controller is setup early */
|
||||
ralink_rst_init();
|
||||
if (ralink_soc != MT762X_SOC_MT7621AT)
|
||||
ralink_rst_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -659,3 +659,19 @@
|
||||
interrupts = <16 2 1 9>;
|
||||
};
|
||||
};
|
||||
|
||||
&fman0_rx_0x08 {
|
||||
/delete-property/ fsl,fman-10g-port;
|
||||
};
|
||||
|
||||
&fman0_tx_0x28 {
|
||||
/delete-property/ fsl,fman-10g-port;
|
||||
};
|
||||
|
||||
&fman0_rx_0x09 {
|
||||
/delete-property/ fsl,fman-10g-port;
|
||||
};
|
||||
|
||||
&fman0_tx_0x29 {
|
||||
/delete-property/ fsl,fman-10g-port;
|
||||
};
|
||||
|
@ -13,10 +13,10 @@
|
||||
#include <linux/kvm.h>
|
||||
#include <linux/kvm_types.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <asm/csr.h>
|
||||
#include <asm/hwcap.h>
|
||||
#include <asm/kvm_vcpu_fp.h>
|
||||
#include <asm/kvm_vcpu_insn.h>
|
||||
#include <asm/kvm_vcpu_sbi.h>
|
||||
#include <asm/kvm_vcpu_timer.h>
|
||||
|
||||
#define KVM_MAX_VCPUS 1024
|
||||
@ -95,10 +95,6 @@ struct kvm_arch {
|
||||
struct kvm_guest_timer timer;
|
||||
};
|
||||
|
||||
struct kvm_sbi_context {
|
||||
int return_handled;
|
||||
};
|
||||
|
||||
struct kvm_cpu_trap {
|
||||
unsigned long sepc;
|
||||
unsigned long scause;
|
||||
@ -169,6 +165,11 @@ struct kvm_vcpu_arch {
|
||||
/* ISA feature bits (similar to MISA) */
|
||||
DECLARE_BITMAP(isa, RISCV_ISA_EXT_MAX);
|
||||
|
||||
/* Vendor, Arch, and Implementation details */
|
||||
unsigned long mvendorid;
|
||||
unsigned long marchid;
|
||||
unsigned long mimpid;
|
||||
|
||||
/* SSCRATCH, STVEC, and SCOUNTEREN of Host */
|
||||
unsigned long host_sscratch;
|
||||
unsigned long host_stvec;
|
||||
@ -217,7 +218,7 @@ struct kvm_vcpu_arch {
|
||||
struct kvm_csr_decode csr_decode;
|
||||
|
||||
/* SBI context */
|
||||
struct kvm_sbi_context sbi_context;
|
||||
struct kvm_vcpu_sbi_context sbi_context;
|
||||
|
||||
/* Cache pages needed to program page tables with spinlock held */
|
||||
struct kvm_mmu_memory_cache mmu_page_cache;
|
||||
@ -327,7 +328,4 @@ bool kvm_riscv_vcpu_has_interrupts(struct kvm_vcpu *vcpu, unsigned long mask);
|
||||
void kvm_riscv_vcpu_power_off(struct kvm_vcpu *vcpu);
|
||||
void kvm_riscv_vcpu_power_on(struct kvm_vcpu *vcpu);
|
||||
|
||||
int kvm_riscv_vcpu_sbi_return(struct kvm_vcpu *vcpu, struct kvm_run *run);
|
||||
int kvm_riscv_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, struct kvm_run *run);
|
||||
|
||||
#endif /* __RISCV_KVM_HOST_H__ */
|
||||
|
@ -14,6 +14,10 @@
|
||||
#define KVM_SBI_VERSION_MAJOR 1
|
||||
#define KVM_SBI_VERSION_MINOR 0
|
||||
|
||||
struct kvm_vcpu_sbi_context {
|
||||
int return_handled;
|
||||
};
|
||||
|
||||
struct kvm_vcpu_sbi_extension {
|
||||
unsigned long extid_start;
|
||||
unsigned long extid_end;
|
||||
@ -31,7 +35,9 @@ void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run);
|
||||
void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu,
|
||||
struct kvm_run *run,
|
||||
u32 type, u64 flags);
|
||||
int kvm_riscv_vcpu_sbi_return(struct kvm_vcpu *vcpu, struct kvm_run *run);
|
||||
const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext(unsigned long extid);
|
||||
int kvm_riscv_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, struct kvm_run *run);
|
||||
|
||||
#ifdef CONFIG_RISCV_SBI_V01
|
||||
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_v01;
|
||||
|
@ -49,6 +49,9 @@ struct kvm_sregs {
|
||||
struct kvm_riscv_config {
|
||||
unsigned long isa;
|
||||
unsigned long zicbom_block_size;
|
||||
unsigned long mvendorid;
|
||||
unsigned long marchid;
|
||||
unsigned long mimpid;
|
||||
};
|
||||
|
||||
/* CORE registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
|
||||
|
@ -627,16 +627,19 @@ long sbi_get_mvendorid(void)
|
||||
{
|
||||
return __sbi_base_ecall(SBI_EXT_BASE_GET_MVENDORID);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sbi_get_mvendorid);
|
||||
|
||||
long sbi_get_marchid(void)
|
||||
{
|
||||
return __sbi_base_ecall(SBI_EXT_BASE_GET_MARCHID);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sbi_get_marchid);
|
||||
|
||||
long sbi_get_mimpid(void)
|
||||
{
|
||||
return __sbi_base_ecall(SBI_EXT_BASE_GET_MIMPID);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sbi_get_mimpid);
|
||||
|
||||
static void sbi_send_cpumask_ipi(const struct cpumask *target)
|
||||
{
|
||||
|
@ -127,3 +127,9 @@ static int __init riscv_kvm_init(void)
|
||||
return kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
|
||||
}
|
||||
module_init(riscv_kvm_init);
|
||||
|
||||
static void __exit riscv_kvm_exit(void)
|
||||
{
|
||||
kvm_exit();
|
||||
}
|
||||
module_exit(riscv_kvm_exit);
|
||||
|
@ -537,10 +537,8 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
|
||||
if (change == KVM_MR_FLAGS_ONLY)
|
||||
goto out;
|
||||
|
||||
spin_lock(&kvm->mmu_lock);
|
||||
if (ret)
|
||||
gstage_unmap_range(kvm, base_gpa, size, false);
|
||||
spin_unlock(&kvm->mmu_lock);
|
||||
kvm_riscv_gstage_iounmap(kvm, base_gpa, size);
|
||||
|
||||
out:
|
||||
mmap_read_unlock(current->mm);
|
||||
@ -632,7 +630,7 @@ int kvm_riscv_gstage_map(struct kvm_vcpu *vcpu,
|
||||
|
||||
mmap_read_lock(current->mm);
|
||||
|
||||
vma = find_vma_intersection(current->mm, hva, hva + 1);
|
||||
vma = vma_lookup(current->mm, hva);
|
||||
if (unlikely(!vma)) {
|
||||
kvm_err("Failed to find VMA for hva 0x%lx\n", hva);
|
||||
mmap_read_unlock(current->mm);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <asm/csr.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/hwcap.h>
|
||||
#include <asm/sbi.h>
|
||||
|
||||
const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
|
||||
KVM_GENERIC_VCPU_STATS(),
|
||||
@ -171,6 +172,11 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
|
||||
set_bit(host_isa, vcpu->arch.isa);
|
||||
}
|
||||
|
||||
/* Setup vendor, arch, and implementation details */
|
||||
vcpu->arch.mvendorid = sbi_get_mvendorid();
|
||||
vcpu->arch.marchid = sbi_get_marchid();
|
||||
vcpu->arch.mimpid = sbi_get_mimpid();
|
||||
|
||||
/* Setup VCPU hfence queue */
|
||||
spin_lock_init(&vcpu->arch.hfence_lock);
|
||||
|
||||
@ -270,6 +276,15 @@ static int kvm_riscv_vcpu_get_reg_config(struct kvm_vcpu *vcpu,
|
||||
return -EINVAL;
|
||||
reg_val = riscv_cbom_block_size;
|
||||
break;
|
||||
case KVM_REG_RISCV_CONFIG_REG(mvendorid):
|
||||
reg_val = vcpu->arch.mvendorid;
|
||||
break;
|
||||
case KVM_REG_RISCV_CONFIG_REG(marchid):
|
||||
reg_val = vcpu->arch.marchid;
|
||||
break;
|
||||
case KVM_REG_RISCV_CONFIG_REG(mimpid):
|
||||
reg_val = vcpu->arch.mimpid;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -296,12 +311,15 @@ static int kvm_riscv_vcpu_set_reg_config(struct kvm_vcpu *vcpu,
|
||||
if (copy_from_user(®_val, uaddr, KVM_REG_SIZE(reg->id)))
|
||||
return -EFAULT;
|
||||
|
||||
/* This ONE REG interface is only defined for single letter extensions */
|
||||
if (fls(reg_val) >= RISCV_ISA_EXT_BASE)
|
||||
return -EINVAL;
|
||||
|
||||
switch (reg_num) {
|
||||
case KVM_REG_RISCV_CONFIG_REG(isa):
|
||||
/*
|
||||
* This ONE REG interface is only defined for
|
||||
* single letter extensions.
|
||||
*/
|
||||
if (fls(reg_val) >= RISCV_ISA_EXT_BASE)
|
||||
return -EINVAL;
|
||||
|
||||
if (!vcpu->arch.ran_atleast_once) {
|
||||
/* Ignore the enable/disable request for certain extensions */
|
||||
for (i = 0; i < RISCV_ISA_EXT_BASE; i++) {
|
||||
@ -329,6 +347,24 @@ static int kvm_riscv_vcpu_set_reg_config(struct kvm_vcpu *vcpu,
|
||||
break;
|
||||
case KVM_REG_RISCV_CONFIG_REG(zicbom_block_size):
|
||||
return -EOPNOTSUPP;
|
||||
case KVM_REG_RISCV_CONFIG_REG(mvendorid):
|
||||
if (!vcpu->arch.ran_atleast_once)
|
||||
vcpu->arch.mvendorid = reg_val;
|
||||
else
|
||||
return -EBUSY;
|
||||
break;
|
||||
case KVM_REG_RISCV_CONFIG_REG(marchid):
|
||||
if (!vcpu->arch.ran_atleast_once)
|
||||
vcpu->arch.marchid = reg_val;
|
||||
else
|
||||
return -EBUSY;
|
||||
break;
|
||||
case KVM_REG_RISCV_CONFIG_REG(mimpid):
|
||||
if (!vcpu->arch.ran_atleast_once)
|
||||
vcpu->arch.mimpid = reg_val;
|
||||
else
|
||||
return -EBUSY;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -541,22 +577,26 @@ static int kvm_riscv_vcpu_set_reg_isa_ext(struct kvm_vcpu *vcpu,
|
||||
static int kvm_riscv_vcpu_set_reg(struct kvm_vcpu *vcpu,
|
||||
const struct kvm_one_reg *reg)
|
||||
{
|
||||
if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_CONFIG)
|
||||
switch (reg->id & KVM_REG_RISCV_TYPE_MASK) {
|
||||
case KVM_REG_RISCV_CONFIG:
|
||||
return kvm_riscv_vcpu_set_reg_config(vcpu, reg);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_CORE)
|
||||
case KVM_REG_RISCV_CORE:
|
||||
return kvm_riscv_vcpu_set_reg_core(vcpu, reg);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_CSR)
|
||||
case KVM_REG_RISCV_CSR:
|
||||
return kvm_riscv_vcpu_set_reg_csr(vcpu, reg);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_TIMER)
|
||||
case KVM_REG_RISCV_TIMER:
|
||||
return kvm_riscv_vcpu_set_reg_timer(vcpu, reg);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_FP_F)
|
||||
case KVM_REG_RISCV_FP_F:
|
||||
return kvm_riscv_vcpu_set_reg_fp(vcpu, reg,
|
||||
KVM_REG_RISCV_FP_F);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_FP_D)
|
||||
case KVM_REG_RISCV_FP_D:
|
||||
return kvm_riscv_vcpu_set_reg_fp(vcpu, reg,
|
||||
KVM_REG_RISCV_FP_D);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_ISA_EXT)
|
||||
case KVM_REG_RISCV_ISA_EXT:
|
||||
return kvm_riscv_vcpu_set_reg_isa_ext(vcpu, reg);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -564,22 +604,26 @@ static int kvm_riscv_vcpu_set_reg(struct kvm_vcpu *vcpu,
|
||||
static int kvm_riscv_vcpu_get_reg(struct kvm_vcpu *vcpu,
|
||||
const struct kvm_one_reg *reg)
|
||||
{
|
||||
if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_CONFIG)
|
||||
switch (reg->id & KVM_REG_RISCV_TYPE_MASK) {
|
||||
case KVM_REG_RISCV_CONFIG:
|
||||
return kvm_riscv_vcpu_get_reg_config(vcpu, reg);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_CORE)
|
||||
case KVM_REG_RISCV_CORE:
|
||||
return kvm_riscv_vcpu_get_reg_core(vcpu, reg);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_CSR)
|
||||
case KVM_REG_RISCV_CSR:
|
||||
return kvm_riscv_vcpu_get_reg_csr(vcpu, reg);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_TIMER)
|
||||
case KVM_REG_RISCV_TIMER:
|
||||
return kvm_riscv_vcpu_get_reg_timer(vcpu, reg);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_FP_F)
|
||||
case KVM_REG_RISCV_FP_F:
|
||||
return kvm_riscv_vcpu_get_reg_fp(vcpu, reg,
|
||||
KVM_REG_RISCV_FP_F);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_FP_D)
|
||||
case KVM_REG_RISCV_FP_D:
|
||||
return kvm_riscv_vcpu_get_reg_fp(vcpu, reg,
|
||||
KVM_REG_RISCV_FP_D);
|
||||
else if ((reg->id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_ISA_EXT)
|
||||
case KVM_REG_RISCV_ISA_EXT:
|
||||
return kvm_riscv_vcpu_get_reg_isa_ext(vcpu, reg);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -984,8 +1028,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
|
||||
while (ret > 0) {
|
||||
/* Check conditions before entering the guest */
|
||||
ret = xfer_to_guest_mode_handle_work(vcpu);
|
||||
if (!ret)
|
||||
ret = 1;
|
||||
if (ret)
|
||||
continue;
|
||||
ret = 1;
|
||||
|
||||
kvm_riscv_gstage_vmid_update(vcpu);
|
||||
|
||||
|
@ -10,9 +10,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/kvm_host.h>
|
||||
#include <linux/version.h>
|
||||
#include <asm/csr.h>
|
||||
#include <asm/sbi.h>
|
||||
#include <asm/kvm_vcpu_timer.h>
|
||||
#include <asm/kvm_vcpu_sbi.h>
|
||||
|
||||
static int kvm_sbi_ext_base_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
|
||||
@ -21,7 +19,6 @@ static int kvm_sbi_ext_base_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
|
||||
{
|
||||
int ret = 0;
|
||||
struct kvm_cpu_context *cp = &vcpu->arch.guest_context;
|
||||
struct sbiret ecall_ret;
|
||||
|
||||
switch (cp->a6) {
|
||||
case SBI_EXT_BASE_GET_SPEC_VERSION:
|
||||
@ -50,13 +47,13 @@ static int kvm_sbi_ext_base_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
|
||||
*out_val = kvm_vcpu_sbi_find_ext(cp->a0) ? 1 : 0;
|
||||
break;
|
||||
case SBI_EXT_BASE_GET_MVENDORID:
|
||||
*out_val = vcpu->arch.mvendorid;
|
||||
break;
|
||||
case SBI_EXT_BASE_GET_MARCHID:
|
||||
*out_val = vcpu->arch.marchid;
|
||||
break;
|
||||
case SBI_EXT_BASE_GET_MIMPID:
|
||||
ecall_ret = sbi_ecall(SBI_EXT_BASE, cp->a6, 0, 0, 0, 0, 0, 0);
|
||||
if (!ecall_ret.error)
|
||||
*out_val = ecall_ret.value;
|
||||
/*TODO: We are unnecessarily converting the error twice */
|
||||
ret = sbi_err_map_linux_errno(ecall_ret.error);
|
||||
*out_val = vcpu->arch.mimpid;
|
||||
break;
|
||||
default:
|
||||
ret = -EOPNOTSUPP;
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/kvm_host.h>
|
||||
#include <asm/csr.h>
|
||||
#include <asm/sbi.h>
|
||||
#include <asm/kvm_vcpu_sbi.h>
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/kvm_host.h>
|
||||
#include <asm/csr.h>
|
||||
#include <asm/sbi.h>
|
||||
#include <asm/kvm_vcpu_timer.h>
|
||||
#include <asm/kvm_vcpu_sbi.h>
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/kvm_host.h>
|
||||
#include <asm/csr.h>
|
||||
#include <asm/sbi.h>
|
||||
#include <asm/kvm_vcpu_timer.h>
|
||||
#include <asm/kvm_vcpu_sbi.h>
|
||||
|
@ -102,7 +102,7 @@ static int switch_drv_remove(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
flush_work(&psw->work);
|
||||
del_timer_sync(&psw->debounce);
|
||||
timer_shutdown_sync(&psw->debounce);
|
||||
free_irq(irq, pdev);
|
||||
|
||||
kfree(psw);
|
||||
|
@ -386,8 +386,8 @@ static int handle_mmio(struct pt_regs *regs, struct ve_info *ve)
|
||||
{
|
||||
unsigned long *reg, val, vaddr;
|
||||
char buffer[MAX_INSN_SIZE];
|
||||
enum insn_mmio_type mmio;
|
||||
struct insn insn = {};
|
||||
enum mmio_type mmio;
|
||||
int size, extend_size;
|
||||
u8 extend_val = 0;
|
||||
|
||||
@ -402,10 +402,10 @@ static int handle_mmio(struct pt_regs *regs, struct ve_info *ve)
|
||||
return -EINVAL;
|
||||
|
||||
mmio = insn_decode_mmio(&insn, &size);
|
||||
if (WARN_ON_ONCE(mmio == MMIO_DECODE_FAILED))
|
||||
if (WARN_ON_ONCE(mmio == INSN_MMIO_DECODE_FAILED))
|
||||
return -EINVAL;
|
||||
|
||||
if (mmio != MMIO_WRITE_IMM && mmio != MMIO_MOVS) {
|
||||
if (mmio != INSN_MMIO_WRITE_IMM && mmio != INSN_MMIO_MOVS) {
|
||||
reg = insn_get_modrm_reg_ptr(&insn, regs);
|
||||
if (!reg)
|
||||
return -EINVAL;
|
||||
@ -426,23 +426,23 @@ static int handle_mmio(struct pt_regs *regs, struct ve_info *ve)
|
||||
|
||||
/* Handle writes first */
|
||||
switch (mmio) {
|
||||
case MMIO_WRITE:
|
||||
case INSN_MMIO_WRITE:
|
||||
memcpy(&val, reg, size);
|
||||
if (!mmio_write(size, ve->gpa, val))
|
||||
return -EIO;
|
||||
return insn.length;
|
||||
case MMIO_WRITE_IMM:
|
||||
case INSN_MMIO_WRITE_IMM:
|
||||
val = insn.immediate.value;
|
||||
if (!mmio_write(size, ve->gpa, val))
|
||||
return -EIO;
|
||||
return insn.length;
|
||||
case MMIO_READ:
|
||||
case MMIO_READ_ZERO_EXTEND:
|
||||
case MMIO_READ_SIGN_EXTEND:
|
||||
case INSN_MMIO_READ:
|
||||
case INSN_MMIO_READ_ZERO_EXTEND:
|
||||
case INSN_MMIO_READ_SIGN_EXTEND:
|
||||
/* Reads are handled below */
|
||||
break;
|
||||
case MMIO_MOVS:
|
||||
case MMIO_DECODE_FAILED:
|
||||
case INSN_MMIO_MOVS:
|
||||
case INSN_MMIO_DECODE_FAILED:
|
||||
/*
|
||||
* MMIO was accessed with an instruction that could not be
|
||||
* decoded or handled properly. It was likely not using io.h
|
||||
@ -459,15 +459,15 @@ static int handle_mmio(struct pt_regs *regs, struct ve_info *ve)
|
||||
return -EIO;
|
||||
|
||||
switch (mmio) {
|
||||
case MMIO_READ:
|
||||
case INSN_MMIO_READ:
|
||||
/* Zero-extend for 32-bit operation */
|
||||
extend_size = size == 4 ? sizeof(*reg) : 0;
|
||||
break;
|
||||
case MMIO_READ_ZERO_EXTEND:
|
||||
case INSN_MMIO_READ_ZERO_EXTEND:
|
||||
/* Zero extend based on operand size */
|
||||
extend_size = insn.opnd_bytes;
|
||||
break;
|
||||
case MMIO_READ_SIGN_EXTEND:
|
||||
case INSN_MMIO_READ_SIGN_EXTEND:
|
||||
/* Sign extend based on operand size */
|
||||
extend_size = insn.opnd_bytes;
|
||||
if (size == 1 && val & BIT(7))
|
||||
|
@ -1387,7 +1387,7 @@ static int __init amd_core_pmu_init(void)
|
||||
* numbered counter following it.
|
||||
*/
|
||||
for (i = 0; i < x86_pmu.num_counters - 1; i += 2)
|
||||
even_ctr_mask |= 1 << i;
|
||||
even_ctr_mask |= BIT_ULL(i);
|
||||
|
||||
pair_constraint = (struct event_constraint)
|
||||
__EVENT_CONSTRAINT(0, even_ctr_mask, 0,
|
||||
|
@ -32,16 +32,16 @@ int insn_fetch_from_user_inatomic(struct pt_regs *regs,
|
||||
bool insn_decode_from_regs(struct insn *insn, struct pt_regs *regs,
|
||||
unsigned char buf[MAX_INSN_SIZE], int buf_size);
|
||||
|
||||
enum mmio_type {
|
||||
MMIO_DECODE_FAILED,
|
||||
MMIO_WRITE,
|
||||
MMIO_WRITE_IMM,
|
||||
MMIO_READ,
|
||||
MMIO_READ_ZERO_EXTEND,
|
||||
MMIO_READ_SIGN_EXTEND,
|
||||
MMIO_MOVS,
|
||||
enum insn_mmio_type {
|
||||
INSN_MMIO_DECODE_FAILED,
|
||||
INSN_MMIO_WRITE,
|
||||
INSN_MMIO_WRITE_IMM,
|
||||
INSN_MMIO_READ,
|
||||
INSN_MMIO_READ_ZERO_EXTEND,
|
||||
INSN_MMIO_READ_SIGN_EXTEND,
|
||||
INSN_MMIO_MOVS,
|
||||
};
|
||||
|
||||
enum mmio_type insn_decode_mmio(struct insn *insn, int *bytes);
|
||||
enum insn_mmio_type insn_decode_mmio(struct insn *insn, int *bytes);
|
||||
|
||||
#endif /* _ASM_X86_INSN_EVAL_H */
|
||||
|
@ -119,7 +119,7 @@ static bool is_coretext(const struct core_text *ct, void *addr)
|
||||
return within_module_coretext(addr);
|
||||
}
|
||||
|
||||
static __init_or_module bool skip_addr(void *dest)
|
||||
static bool skip_addr(void *dest)
|
||||
{
|
||||
if (dest == error_entry)
|
||||
return true;
|
||||
@ -181,7 +181,7 @@ static const u8 nops[] = {
|
||||
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
|
||||
};
|
||||
|
||||
static __init_or_module void *patch_dest(void *dest, bool direct)
|
||||
static void *patch_dest(void *dest, bool direct)
|
||||
{
|
||||
unsigned int tsize = SKL_TMPL_SIZE;
|
||||
u8 *pad = dest - tsize;
|
||||
|
@ -1981,6 +1981,8 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl)
|
||||
if (ctrl == PR_SPEC_FORCE_DISABLE)
|
||||
task_set_spec_ib_force_disable(task);
|
||||
task_update_spec_tif(task);
|
||||
if (task == current)
|
||||
indirect_branch_prediction_barrier();
|
||||
break;
|
||||
default:
|
||||
return -ERANGE;
|
||||
|
@ -401,10 +401,8 @@ int crash_load_segments(struct kimage *image)
|
||||
kbuf.buf_align = ELF_CORE_HEADER_ALIGN;
|
||||
kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
|
||||
ret = kexec_add_buffer(&kbuf);
|
||||
if (ret) {
|
||||
vfree((void *)image->elf_headers);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
image->elf_load_addr = kbuf.mem;
|
||||
pr_debug("Loaded ELF headers at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
|
||||
image->elf_load_addr, kbuf.bufsz, kbuf.memsz);
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <linux/extable.h>
|
||||
#include <linux/kdebug.h>
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/kgdb.h>
|
||||
#include <linux/ftrace.h>
|
||||
#include <linux/kasan.h>
|
||||
#include <linux/moduleloader.h>
|
||||
@ -281,12 +282,15 @@ static int can_probe(unsigned long paddr)
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_KGDB
|
||||
/*
|
||||
* Another debugging subsystem might insert this breakpoint.
|
||||
* In that case, we can't recover it.
|
||||
* If there is a dynamically installed kgdb sw breakpoint,
|
||||
* this function should not be probed.
|
||||
*/
|
||||
if (insn.opcode.bytes[0] == INT3_INSN_OPCODE)
|
||||
if (insn.opcode.bytes[0] == INT3_INSN_OPCODE &&
|
||||
kgdb_has_hit_break(addr))
|
||||
return 0;
|
||||
#endif
|
||||
addr += insn.length;
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <linux/extable.h>
|
||||
#include <linux/kdebug.h>
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/kgdb.h>
|
||||
#include <linux/ftrace.h>
|
||||
#include <linux/objtool.h>
|
||||
#include <linux/pgtable.h>
|
||||
@ -279,19 +280,6 @@ static int insn_is_indirect_jump(struct insn *insn)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool is_padding_int3(unsigned long addr, unsigned long eaddr)
|
||||
{
|
||||
unsigned char ops;
|
||||
|
||||
for (; addr < eaddr; addr++) {
|
||||
if (get_kernel_nofault(ops, (void *)addr) < 0 ||
|
||||
ops != INT3_INSN_OPCODE)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Decode whole function to ensure any instructions don't jump into target */
|
||||
static int can_optimize(unsigned long paddr)
|
||||
{
|
||||
@ -334,15 +322,15 @@ static int can_optimize(unsigned long paddr)
|
||||
ret = insn_decode_kernel(&insn, (void *)recovered_insn);
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_KGDB
|
||||
/*
|
||||
* In the case of detecting unknown breakpoint, this could be
|
||||
* a padding INT3 between functions. Let's check that all the
|
||||
* rest of the bytes are also INT3.
|
||||
* If there is a dynamically installed kgdb sw breakpoint,
|
||||
* this function should not be probed.
|
||||
*/
|
||||
if (insn.opcode.bytes[0] == INT3_INSN_OPCODE)
|
||||
return is_padding_int3(addr, paddr - offset + size) ? 1 : 0;
|
||||
|
||||
if (insn.opcode.bytes[0] == INT3_INSN_OPCODE &&
|
||||
kgdb_has_hit_break(addr))
|
||||
return 0;
|
||||
#endif
|
||||
/* Recover address */
|
||||
insn.kaddr = (void *)addr;
|
||||
insn.next_byte = (void *)(addr + insn.length);
|
||||
|
@ -1536,32 +1536,32 @@ static enum es_result vc_handle_mmio_movs(struct es_em_ctxt *ctxt,
|
||||
static enum es_result vc_handle_mmio(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
|
||||
{
|
||||
struct insn *insn = &ctxt->insn;
|
||||
enum insn_mmio_type mmio;
|
||||
unsigned int bytes = 0;
|
||||
enum mmio_type mmio;
|
||||
enum es_result ret;
|
||||
u8 sign_byte;
|
||||
long *reg_data;
|
||||
|
||||
mmio = insn_decode_mmio(insn, &bytes);
|
||||
if (mmio == MMIO_DECODE_FAILED)
|
||||
if (mmio == INSN_MMIO_DECODE_FAILED)
|
||||
return ES_DECODE_FAILED;
|
||||
|
||||
if (mmio != MMIO_WRITE_IMM && mmio != MMIO_MOVS) {
|
||||
if (mmio != INSN_MMIO_WRITE_IMM && mmio != INSN_MMIO_MOVS) {
|
||||
reg_data = insn_get_modrm_reg_ptr(insn, ctxt->regs);
|
||||
if (!reg_data)
|
||||
return ES_DECODE_FAILED;
|
||||
}
|
||||
|
||||
switch (mmio) {
|
||||
case MMIO_WRITE:
|
||||
case INSN_MMIO_WRITE:
|
||||
memcpy(ghcb->shared_buffer, reg_data, bytes);
|
||||
ret = vc_do_mmio(ghcb, ctxt, bytes, false);
|
||||
break;
|
||||
case MMIO_WRITE_IMM:
|
||||
case INSN_MMIO_WRITE_IMM:
|
||||
memcpy(ghcb->shared_buffer, insn->immediate1.bytes, bytes);
|
||||
ret = vc_do_mmio(ghcb, ctxt, bytes, false);
|
||||
break;
|
||||
case MMIO_READ:
|
||||
case INSN_MMIO_READ:
|
||||
ret = vc_do_mmio(ghcb, ctxt, bytes, true);
|
||||
if (ret)
|
||||
break;
|
||||
@ -1572,7 +1572,7 @@ static enum es_result vc_handle_mmio(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
|
||||
|
||||
memcpy(reg_data, ghcb->shared_buffer, bytes);
|
||||
break;
|
||||
case MMIO_READ_ZERO_EXTEND:
|
||||
case INSN_MMIO_READ_ZERO_EXTEND:
|
||||
ret = vc_do_mmio(ghcb, ctxt, bytes, true);
|
||||
if (ret)
|
||||
break;
|
||||
@ -1581,7 +1581,7 @@ static enum es_result vc_handle_mmio(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
|
||||
memset(reg_data, 0, insn->opnd_bytes);
|
||||
memcpy(reg_data, ghcb->shared_buffer, bytes);
|
||||
break;
|
||||
case MMIO_READ_SIGN_EXTEND:
|
||||
case INSN_MMIO_READ_SIGN_EXTEND:
|
||||
ret = vc_do_mmio(ghcb, ctxt, bytes, true);
|
||||
if (ret)
|
||||
break;
|
||||
@ -1600,7 +1600,7 @@ static enum es_result vc_handle_mmio(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
|
||||
memset(reg_data, sign_byte, insn->opnd_bytes);
|
||||
memcpy(reg_data, ghcb->shared_buffer, bytes);
|
||||
break;
|
||||
case MMIO_MOVS:
|
||||
case INSN_MMIO_MOVS:
|
||||
ret = vc_handle_mmio_movs(ctxt, bytes);
|
||||
break;
|
||||
default:
|
||||
|
@ -1769,6 +1769,7 @@ static bool hv_is_vp_in_sparse_set(u32 vp_id, u64 valid_bank_mask, u64 sparse_ba
|
||||
}
|
||||
|
||||
struct kvm_hv_hcall {
|
||||
/* Hypercall input data */
|
||||
u64 param;
|
||||
u64 ingpa;
|
||||
u64 outgpa;
|
||||
@ -1779,12 +1780,21 @@ struct kvm_hv_hcall {
|
||||
bool fast;
|
||||
bool rep;
|
||||
sse128_t xmm[HV_HYPERCALL_MAX_XMM_REGISTERS];
|
||||
|
||||
/*
|
||||
* Current read offset when KVM reads hypercall input data gradually,
|
||||
* either offset in bytes from 'ingpa' for regular hypercalls or the
|
||||
* number of already consumed 'XMM halves' for 'fast' hypercalls.
|
||||
*/
|
||||
union {
|
||||
gpa_t data_offset;
|
||||
int consumed_xmm_halves;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
static int kvm_hv_get_hc_data(struct kvm *kvm, struct kvm_hv_hcall *hc,
|
||||
u16 orig_cnt, u16 cnt_cap, u64 *data,
|
||||
int consumed_xmm_halves, gpa_t offset)
|
||||
u16 orig_cnt, u16 cnt_cap, u64 *data)
|
||||
{
|
||||
/*
|
||||
* Preserve the original count when ignoring entries via a "cap", KVM
|
||||
@ -1799,11 +1809,11 @@ static int kvm_hv_get_hc_data(struct kvm *kvm, struct kvm_hv_hcall *hc,
|
||||
* Each XMM holds two sparse banks, but do not count halves that
|
||||
* have already been consumed for hypercall parameters.
|
||||
*/
|
||||
if (orig_cnt > 2 * HV_HYPERCALL_MAX_XMM_REGISTERS - consumed_xmm_halves)
|
||||
if (orig_cnt > 2 * HV_HYPERCALL_MAX_XMM_REGISTERS - hc->consumed_xmm_halves)
|
||||
return HV_STATUS_INVALID_HYPERCALL_INPUT;
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
j = i + consumed_xmm_halves;
|
||||
j = i + hc->consumed_xmm_halves;
|
||||
if (j % 2)
|
||||
data[i] = sse128_hi(hc->xmm[j / 2]);
|
||||
else
|
||||
@ -1812,27 +1822,24 @@ static int kvm_hv_get_hc_data(struct kvm *kvm, struct kvm_hv_hcall *hc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
return kvm_read_guest(kvm, hc->ingpa + offset, data,
|
||||
return kvm_read_guest(kvm, hc->ingpa + hc->data_offset, data,
|
||||
cnt * sizeof(*data));
|
||||
}
|
||||
|
||||
static u64 kvm_get_sparse_vp_set(struct kvm *kvm, struct kvm_hv_hcall *hc,
|
||||
u64 *sparse_banks, int consumed_xmm_halves,
|
||||
gpa_t offset)
|
||||
u64 *sparse_banks)
|
||||
{
|
||||
if (hc->var_cnt > HV_MAX_SPARSE_VCPU_BANKS)
|
||||
return -EINVAL;
|
||||
|
||||
/* Cap var_cnt to ignore banks that cannot contain a legal VP index. */
|
||||
return kvm_hv_get_hc_data(kvm, hc, hc->var_cnt, KVM_HV_MAX_SPARSE_VCPU_SET_BITS,
|
||||
sparse_banks, consumed_xmm_halves, offset);
|
||||
sparse_banks);
|
||||
}
|
||||
|
||||
static int kvm_hv_get_tlb_flush_entries(struct kvm *kvm, struct kvm_hv_hcall *hc, u64 entries[],
|
||||
int consumed_xmm_halves, gpa_t offset)
|
||||
static int kvm_hv_get_tlb_flush_entries(struct kvm *kvm, struct kvm_hv_hcall *hc, u64 entries[])
|
||||
{
|
||||
return kvm_hv_get_hc_data(kvm, hc, hc->rep_cnt, hc->rep_cnt,
|
||||
entries, consumed_xmm_halves, offset);
|
||||
return kvm_hv_get_hc_data(kvm, hc, hc->rep_cnt, hc->rep_cnt, entries);
|
||||
}
|
||||
|
||||
static void hv_tlb_flush_enqueue(struct kvm_vcpu *vcpu,
|
||||
@ -1926,8 +1933,6 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc)
|
||||
struct kvm_vcpu *v;
|
||||
unsigned long i;
|
||||
bool all_cpus;
|
||||
int consumed_xmm_halves = 0;
|
||||
gpa_t data_offset;
|
||||
|
||||
/*
|
||||
* The Hyper-V TLFS doesn't allow more than HV_MAX_SPARSE_VCPU_BANKS
|
||||
@ -1955,12 +1960,12 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc)
|
||||
flush.address_space = hc->ingpa;
|
||||
flush.flags = hc->outgpa;
|
||||
flush.processor_mask = sse128_lo(hc->xmm[0]);
|
||||
consumed_xmm_halves = 1;
|
||||
hc->consumed_xmm_halves = 1;
|
||||
} else {
|
||||
if (unlikely(kvm_read_guest(kvm, hc->ingpa,
|
||||
&flush, sizeof(flush))))
|
||||
return HV_STATUS_INVALID_HYPERCALL_INPUT;
|
||||
data_offset = sizeof(flush);
|
||||
hc->data_offset = sizeof(flush);
|
||||
}
|
||||
|
||||
trace_kvm_hv_flush_tlb(flush.processor_mask,
|
||||
@ -1985,12 +1990,12 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc)
|
||||
flush_ex.flags = hc->outgpa;
|
||||
memcpy(&flush_ex.hv_vp_set,
|
||||
&hc->xmm[0], sizeof(hc->xmm[0]));
|
||||
consumed_xmm_halves = 2;
|
||||
hc->consumed_xmm_halves = 2;
|
||||
} else {
|
||||
if (unlikely(kvm_read_guest(kvm, hc->ingpa, &flush_ex,
|
||||
sizeof(flush_ex))))
|
||||
return HV_STATUS_INVALID_HYPERCALL_INPUT;
|
||||
data_offset = sizeof(flush_ex);
|
||||
hc->data_offset = sizeof(flush_ex);
|
||||
}
|
||||
|
||||
trace_kvm_hv_flush_tlb_ex(flush_ex.hv_vp_set.valid_bank_mask,
|
||||
@ -2009,8 +2014,7 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc)
|
||||
if (!hc->var_cnt)
|
||||
goto ret_success;
|
||||
|
||||
if (kvm_get_sparse_vp_set(kvm, hc, sparse_banks,
|
||||
consumed_xmm_halves, data_offset))
|
||||
if (kvm_get_sparse_vp_set(kvm, hc, sparse_banks))
|
||||
return HV_STATUS_INVALID_HYPERCALL_INPUT;
|
||||
}
|
||||
|
||||
@ -2021,8 +2025,10 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc)
|
||||
* consumed_xmm_halves to make sure TLB flush entries are read
|
||||
* from the correct offset.
|
||||
*/
|
||||
data_offset += hc->var_cnt * sizeof(sparse_banks[0]);
|
||||
consumed_xmm_halves += hc->var_cnt;
|
||||
if (hc->fast)
|
||||
hc->consumed_xmm_halves += hc->var_cnt;
|
||||
else
|
||||
hc->data_offset += hc->var_cnt * sizeof(sparse_banks[0]);
|
||||
}
|
||||
|
||||
if (hc->code == HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE ||
|
||||
@ -2030,8 +2036,7 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc)
|
||||
hc->rep_cnt > ARRAY_SIZE(__tlb_flush_entries)) {
|
||||
tlb_flush_entries = NULL;
|
||||
} else {
|
||||
if (kvm_hv_get_tlb_flush_entries(kvm, hc, __tlb_flush_entries,
|
||||
consumed_xmm_halves, data_offset))
|
||||
if (kvm_hv_get_tlb_flush_entries(kvm, hc, __tlb_flush_entries))
|
||||
return HV_STATUS_INVALID_HYPERCALL_INPUT;
|
||||
tlb_flush_entries = __tlb_flush_entries;
|
||||
}
|
||||
@ -2180,9 +2185,13 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc)
|
||||
if (!hc->var_cnt)
|
||||
goto ret_success;
|
||||
|
||||
if (kvm_get_sparse_vp_set(kvm, hc, sparse_banks, 1,
|
||||
offsetof(struct hv_send_ipi_ex,
|
||||
vp_set.bank_contents)))
|
||||
if (!hc->fast)
|
||||
hc->data_offset = offsetof(struct hv_send_ipi_ex,
|
||||
vp_set.bank_contents);
|
||||
else
|
||||
hc->consumed_xmm_halves = 1;
|
||||
|
||||
if (kvm_get_sparse_vp_set(kvm, hc, sparse_banks))
|
||||
return HV_STATUS_INVALID_HYPERCALL_INPUT;
|
||||
}
|
||||
|
||||
|
@ -426,8 +426,9 @@ void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu,
|
||||
kvm_set_msi_irq(vcpu->kvm, entry, &irq);
|
||||
|
||||
if (irq.trig_mode &&
|
||||
kvm_apic_match_dest(vcpu, NULL, APIC_DEST_NOSHORT,
|
||||
irq.dest_id, irq.dest_mode))
|
||||
(kvm_apic_match_dest(vcpu, NULL, APIC_DEST_NOSHORT,
|
||||
irq.dest_id, irq.dest_mode) ||
|
||||
kvm_apic_pending_eoi(vcpu, irq.vector)))
|
||||
__set_bit(irq.vector, ioapic_handled_vectors);
|
||||
}
|
||||
}
|
||||
|
@ -188,11 +188,11 @@ static inline bool lapic_in_kernel(struct kvm_vcpu *vcpu)
|
||||
|
||||
extern struct static_key_false_deferred apic_hw_disabled;
|
||||
|
||||
static inline int kvm_apic_hw_enabled(struct kvm_lapic *apic)
|
||||
static inline bool kvm_apic_hw_enabled(struct kvm_lapic *apic)
|
||||
{
|
||||
if (static_branch_unlikely(&apic_hw_disabled.key))
|
||||
return apic->vcpu->arch.apic_base & MSR_IA32_APICBASE_ENABLE;
|
||||
return MSR_IA32_APICBASE_ENABLE;
|
||||
return true;
|
||||
}
|
||||
|
||||
extern struct static_key_false_deferred apic_sw_disabled;
|
||||
|
@ -363,7 +363,7 @@ static __always_inline bool is_rsvd_spte(struct rsvd_bits_validate *rsvd_check,
|
||||
* A shadow-present leaf SPTE may be non-writable for 4 possible reasons:
|
||||
*
|
||||
* 1. To intercept writes for dirty logging. KVM write-protects huge pages
|
||||
* so that they can be split be split down into the dirty logging
|
||||
* so that they can be split down into the dirty logging
|
||||
* granularity (4KiB) whenever the guest writes to them. KVM also
|
||||
* write-protects 4KiB pages so that writes can be recorded in the dirty log
|
||||
* (e.g. if not using PML). SPTEs are write-protected for dirty logging
|
||||
|
@ -1074,7 +1074,9 @@ static int tdp_mmu_map_handle_target_level(struct kvm_vcpu *vcpu,
|
||||
int ret = RET_PF_FIXED;
|
||||
bool wrprot = false;
|
||||
|
||||
WARN_ON(sp->role.level != fault->goal_level);
|
||||
if (WARN_ON_ONCE(sp->role.level != fault->goal_level))
|
||||
return RET_PF_RETRY;
|
||||
|
||||
if (unlikely(!fault->slot))
|
||||
new_spte = make_mmio_spte(vcpu, iter->gfn, ACC_ALL);
|
||||
else
|
||||
@ -1173,9 +1175,6 @@ int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
|
||||
if (fault->nx_huge_page_workaround_enabled)
|
||||
disallowed_hugepage_adjust(fault, iter.old_spte, iter.level);
|
||||
|
||||
if (iter.level == fault->goal_level)
|
||||
break;
|
||||
|
||||
/*
|
||||
* If SPTE has been frozen by another thread, just give up and
|
||||
* retry, avoiding unnecessary page table allocation and free.
|
||||
@ -1183,6 +1182,9 @@ int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
|
||||
if (is_removed_spte(iter.old_spte))
|
||||
goto retry;
|
||||
|
||||
if (iter.level == fault->goal_level)
|
||||
goto map_target_level;
|
||||
|
||||
/* Step down into the lower level page table if it exists. */
|
||||
if (is_shadow_present_pte(iter.old_spte) &&
|
||||
!is_large_pte(iter.old_spte))
|
||||
@ -1203,8 +1205,8 @@ int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
|
||||
r = tdp_mmu_link_sp(kvm, &iter, sp, true);
|
||||
|
||||
/*
|
||||
* Also force the guest to retry the access if the upper level SPTEs
|
||||
* aren't in place.
|
||||
* Force the guest to retry if installing an upper level SPTE
|
||||
* failed, e.g. because a different task modified the SPTE.
|
||||
*/
|
||||
if (r) {
|
||||
tdp_mmu_free_sp(sp);
|
||||
@ -1214,11 +1216,20 @@ int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
|
||||
if (fault->huge_page_disallowed &&
|
||||
fault->req_level >= iter.level) {
|
||||
spin_lock(&kvm->arch.tdp_mmu_pages_lock);
|
||||
track_possible_nx_huge_page(kvm, sp);
|
||||
if (sp->nx_huge_page_disallowed)
|
||||
track_possible_nx_huge_page(kvm, sp);
|
||||
spin_unlock(&kvm->arch.tdp_mmu_pages_lock);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The walk aborted before reaching the target level, e.g. because the
|
||||
* iterator detected an upper level SPTE was frozen during traversal.
|
||||
*/
|
||||
WARN_ON_ONCE(iter.level == fault->goal_level);
|
||||
goto retry;
|
||||
|
||||
map_target_level:
|
||||
ret = tdp_mmu_map_handle_target_level(vcpu, fault, &iter);
|
||||
|
||||
retry:
|
||||
|
@ -238,7 +238,8 @@ static bool pmc_resume_counter(struct kvm_pmc *pmc)
|
||||
return false;
|
||||
|
||||
/* recalibrate sample period and check if it's accepted by perf core */
|
||||
if (perf_event_period(pmc->perf_event,
|
||||
if (is_sampling_event(pmc->perf_event) &&
|
||||
perf_event_period(pmc->perf_event,
|
||||
get_sample_period(pmc, pmc->counter)))
|
||||
return false;
|
||||
|
||||
|
@ -140,7 +140,8 @@ static inline u64 get_sample_period(struct kvm_pmc *pmc, u64 counter_value)
|
||||
|
||||
static inline void pmc_update_sample_period(struct kvm_pmc *pmc)
|
||||
{
|
||||
if (!pmc->perf_event || pmc->is_paused)
|
||||
if (!pmc->perf_event || pmc->is_paused ||
|
||||
!is_sampling_event(pmc->perf_event))
|
||||
return;
|
||||
|
||||
perf_event_period(pmc->perf_event,
|
||||
|
@ -5296,10 +5296,19 @@ static int handle_vmclear(struct kvm_vcpu *vcpu)
|
||||
if (vmptr == vmx->nested.current_vmptr)
|
||||
nested_release_vmcs12(vcpu);
|
||||
|
||||
kvm_vcpu_write_guest(vcpu,
|
||||
vmptr + offsetof(struct vmcs12,
|
||||
launch_state),
|
||||
&zero, sizeof(zero));
|
||||
/*
|
||||
* Silently ignore memory errors on VMCLEAR, Intel's pseudocode
|
||||
* for VMCLEAR includes a "ensure that data for VMCS referenced
|
||||
* by the operand is in memory" clause that guards writes to
|
||||
* memory, i.e. doing nothing for I/O is architecturally valid.
|
||||
*
|
||||
* FIXME: Suppress failures if and only if no memslot is found,
|
||||
* i.e. exit to userspace if __copy_to_user() fails.
|
||||
*/
|
||||
(void)kvm_vcpu_write_guest(vcpu,
|
||||
vmptr + offsetof(struct vmcs12,
|
||||
launch_state),
|
||||
&zero, sizeof(zero));
|
||||
} else if (vmx->nested.hv_evmcs && vmptr == vmx->nested.hv_evmcs_vmptr) {
|
||||
nested_release_evmcs(vcpu);
|
||||
}
|
||||
@ -6873,7 +6882,8 @@ void nested_vmx_setup_ctls_msrs(struct vmcs_config *vmcs_conf, u32 ept_caps)
|
||||
SECONDARY_EXEC_ENABLE_INVPCID |
|
||||
SECONDARY_EXEC_RDSEED_EXITING |
|
||||
SECONDARY_EXEC_XSAVES |
|
||||
SECONDARY_EXEC_TSC_SCALING;
|
||||
SECONDARY_EXEC_TSC_SCALING |
|
||||
SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE;
|
||||
|
||||
/*
|
||||
* We can emulate "VMCS shadowing," even if the hardware
|
||||
|
@ -4459,6 +4459,13 @@ vmx_adjust_secondary_exec_control(struct vcpu_vmx *vmx, u32 *exec_control,
|
||||
* controls for features that are/aren't exposed to the guest.
|
||||
*/
|
||||
if (nested) {
|
||||
/*
|
||||
* All features that can be added or removed to VMX MSRs must
|
||||
* be supported in the first place for nested virtualization.
|
||||
*/
|
||||
if (WARN_ON_ONCE(!(vmcs_config.nested.secondary_ctls_high & control)))
|
||||
enabled = false;
|
||||
|
||||
if (enabled)
|
||||
vmx->nested.msrs.secondary_ctls_high |= control;
|
||||
else
|
||||
|
@ -13132,6 +13132,9 @@ int kvm_handle_memory_failure(struct kvm_vcpu *vcpu, int r,
|
||||
struct x86_exception *e)
|
||||
{
|
||||
if (r == X86EMUL_PROPAGATE_FAULT) {
|
||||
if (KVM_BUG_ON(!e, vcpu->kvm))
|
||||
return -EIO;
|
||||
|
||||
kvm_inject_emulated_page_fault(vcpu, e);
|
||||
return 1;
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ static int kvm_xen_shared_info_init(struct kvm *kvm, gfn_t gfn)
|
||||
int ret = 0;
|
||||
int idx = srcu_read_lock(&kvm->srcu);
|
||||
|
||||
if (gfn == GPA_INVALID) {
|
||||
if (gfn == KVM_XEN_INVALID_GFN) {
|
||||
kvm_gpc_deactivate(gpc);
|
||||
goto out;
|
||||
}
|
||||
@ -659,7 +659,7 @@ int kvm_xen_hvm_get_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data)
|
||||
if (kvm->arch.xen.shinfo_cache.active)
|
||||
data->u.shared_info.gfn = gpa_to_gfn(kvm->arch.xen.shinfo_cache.gpa);
|
||||
else
|
||||
data->u.shared_info.gfn = GPA_INVALID;
|
||||
data->u.shared_info.gfn = KVM_XEN_INVALID_GFN;
|
||||
r = 0;
|
||||
break;
|
||||
|
||||
@ -705,7 +705,7 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data)
|
||||
BUILD_BUG_ON(offsetof(struct vcpu_info, time) !=
|
||||
offsetof(struct compat_vcpu_info, time));
|
||||
|
||||
if (data->u.gpa == GPA_INVALID) {
|
||||
if (data->u.gpa == KVM_XEN_INVALID_GPA) {
|
||||
kvm_gpc_deactivate(&vcpu->arch.xen.vcpu_info_cache);
|
||||
r = 0;
|
||||
break;
|
||||
@ -719,7 +719,7 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data)
|
||||
break;
|
||||
|
||||
case KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO:
|
||||
if (data->u.gpa == GPA_INVALID) {
|
||||
if (data->u.gpa == KVM_XEN_INVALID_GPA) {
|
||||
kvm_gpc_deactivate(&vcpu->arch.xen.vcpu_time_info_cache);
|
||||
r = 0;
|
||||
break;
|
||||
@ -739,7 +739,7 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data)
|
||||
r = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
if (data->u.gpa == GPA_INVALID) {
|
||||
if (data->u.gpa == KVM_XEN_INVALID_GPA) {
|
||||
r = 0;
|
||||
deactivate_out:
|
||||
kvm_gpc_deactivate(&vcpu->arch.xen.runstate_cache);
|
||||
@ -937,7 +937,7 @@ int kvm_xen_vcpu_get_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data)
|
||||
if (vcpu->arch.xen.vcpu_info_cache.active)
|
||||
data->u.gpa = vcpu->arch.xen.vcpu_info_cache.gpa;
|
||||
else
|
||||
data->u.gpa = GPA_INVALID;
|
||||
data->u.gpa = KVM_XEN_INVALID_GPA;
|
||||
r = 0;
|
||||
break;
|
||||
|
||||
@ -945,7 +945,7 @@ int kvm_xen_vcpu_get_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data)
|
||||
if (vcpu->arch.xen.vcpu_time_info_cache.active)
|
||||
data->u.gpa = vcpu->arch.xen.vcpu_time_info_cache.gpa;
|
||||
else
|
||||
data->u.gpa = GPA_INVALID;
|
||||
data->u.gpa = KVM_XEN_INVALID_GPA;
|
||||
r = 0;
|
||||
break;
|
||||
|
||||
@ -1069,6 +1069,7 @@ int kvm_xen_write_hypercall_page(struct kvm_vcpu *vcpu, u64 data)
|
||||
u8 blob_size = lm ? kvm->arch.xen_hvm_config.blob_size_64
|
||||
: kvm->arch.xen_hvm_config.blob_size_32;
|
||||
u8 *page;
|
||||
int ret;
|
||||
|
||||
if (page_num >= blob_size)
|
||||
return 1;
|
||||
@ -1079,10 +1080,10 @@ int kvm_xen_write_hypercall_page(struct kvm_vcpu *vcpu, u64 data)
|
||||
if (IS_ERR(page))
|
||||
return PTR_ERR(page);
|
||||
|
||||
if (kvm_vcpu_write_guest(vcpu, page_addr, page, PAGE_SIZE)) {
|
||||
kfree(page);
|
||||
ret = kvm_vcpu_write_guest(vcpu, page_addr, page, PAGE_SIZE);
|
||||
kfree(page);
|
||||
if (ret)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1183,30 +1184,22 @@ static bool wait_pending_event(struct kvm_vcpu *vcpu, int nr_ports,
|
||||
static bool kvm_xen_schedop_poll(struct kvm_vcpu *vcpu, bool longmode,
|
||||
u64 param, u64 *r)
|
||||
{
|
||||
int idx, i;
|
||||
struct sched_poll sched_poll;
|
||||
evtchn_port_t port, *ports;
|
||||
gpa_t gpa;
|
||||
struct x86_exception e;
|
||||
int i;
|
||||
|
||||
if (!lapic_in_kernel(vcpu) ||
|
||||
!(vcpu->kvm->arch.xen_hvm_config.flags & KVM_XEN_HVM_CONFIG_EVTCHN_SEND))
|
||||
return false;
|
||||
|
||||
idx = srcu_read_lock(&vcpu->kvm->srcu);
|
||||
gpa = kvm_mmu_gva_to_gpa_system(vcpu, param, NULL);
|
||||
srcu_read_unlock(&vcpu->kvm->srcu, idx);
|
||||
if (!gpa) {
|
||||
*r = -EFAULT;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_64BIT) && !longmode) {
|
||||
struct compat_sched_poll sp32;
|
||||
|
||||
/* Sanity check that the compat struct definition is correct */
|
||||
BUILD_BUG_ON(sizeof(sp32) != 16);
|
||||
|
||||
if (kvm_vcpu_read_guest(vcpu, gpa, &sp32, sizeof(sp32))) {
|
||||
if (kvm_read_guest_virt(vcpu, param, &sp32, sizeof(sp32), &e)) {
|
||||
*r = -EFAULT;
|
||||
return true;
|
||||
}
|
||||
@ -1220,8 +1213,8 @@ static bool kvm_xen_schedop_poll(struct kvm_vcpu *vcpu, bool longmode,
|
||||
sched_poll.nr_ports = sp32.nr_ports;
|
||||
sched_poll.timeout = sp32.timeout;
|
||||
} else {
|
||||
if (kvm_vcpu_read_guest(vcpu, gpa, &sched_poll,
|
||||
sizeof(sched_poll))) {
|
||||
if (kvm_read_guest_virt(vcpu, param, &sched_poll,
|
||||
sizeof(sched_poll), &e)) {
|
||||
*r = -EFAULT;
|
||||
return true;
|
||||
}
|
||||
@ -1243,18 +1236,13 @@ static bool kvm_xen_schedop_poll(struct kvm_vcpu *vcpu, bool longmode,
|
||||
} else
|
||||
ports = &port;
|
||||
|
||||
for (i = 0; i < sched_poll.nr_ports; i++) {
|
||||
idx = srcu_read_lock(&vcpu->kvm->srcu);
|
||||
gpa = kvm_mmu_gva_to_gpa_system(vcpu,
|
||||
(gva_t)(sched_poll.ports + i),
|
||||
NULL);
|
||||
srcu_read_unlock(&vcpu->kvm->srcu, idx);
|
||||
if (kvm_read_guest_virt(vcpu, (gva_t)sched_poll.ports, ports,
|
||||
sched_poll.nr_ports * sizeof(*ports), &e)) {
|
||||
*r = -EFAULT;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!gpa || kvm_vcpu_read_guest(vcpu, gpa,
|
||||
&ports[i], sizeof(port))) {
|
||||
*r = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
for (i = 0; i < sched_poll.nr_ports; i++) {
|
||||
if (ports[i] >= max_evtchn_port(vcpu->kvm)) {
|
||||
*r = -EINVAL;
|
||||
goto out;
|
||||
@ -1330,9 +1318,8 @@ static bool kvm_xen_hcall_vcpu_op(struct kvm_vcpu *vcpu, bool longmode, int cmd,
|
||||
int vcpu_id, u64 param, u64 *r)
|
||||
{
|
||||
struct vcpu_set_singleshot_timer oneshot;
|
||||
struct x86_exception e;
|
||||
s64 delta;
|
||||
gpa_t gpa;
|
||||
int idx;
|
||||
|
||||
if (!kvm_xen_timer_enabled(vcpu))
|
||||
return false;
|
||||
@ -1343,9 +1330,6 @@ static bool kvm_xen_hcall_vcpu_op(struct kvm_vcpu *vcpu, bool longmode, int cmd,
|
||||
*r = -EINVAL;
|
||||
return true;
|
||||
}
|
||||
idx = srcu_read_lock(&vcpu->kvm->srcu);
|
||||
gpa = kvm_mmu_gva_to_gpa_system(vcpu, param, NULL);
|
||||
srcu_read_unlock(&vcpu->kvm->srcu, idx);
|
||||
|
||||
/*
|
||||
* The only difference for 32-bit compat is the 4 bytes of
|
||||
@ -1363,9 +1347,8 @@ static bool kvm_xen_hcall_vcpu_op(struct kvm_vcpu *vcpu, bool longmode, int cmd,
|
||||
BUILD_BUG_ON(sizeof_field(struct compat_vcpu_set_singleshot_timer, flags) !=
|
||||
sizeof_field(struct vcpu_set_singleshot_timer, flags));
|
||||
|
||||
if (!gpa ||
|
||||
kvm_vcpu_read_guest(vcpu, gpa, &oneshot, longmode ? sizeof(oneshot) :
|
||||
sizeof(struct compat_vcpu_set_singleshot_timer))) {
|
||||
if (kvm_read_guest_virt(vcpu, param, &oneshot, longmode ? sizeof(oneshot) :
|
||||
sizeof(struct compat_vcpu_set_singleshot_timer), &e)) {
|
||||
*r = -EFAULT;
|
||||
return true;
|
||||
}
|
||||
@ -1825,20 +1808,20 @@ static int kvm_xen_eventfd_update(struct kvm *kvm,
|
||||
{
|
||||
u32 port = data->u.evtchn.send_port;
|
||||
struct evtchnfd *evtchnfd;
|
||||
int ret;
|
||||
|
||||
if (!port || port >= max_evtchn_port(kvm))
|
||||
return -EINVAL;
|
||||
|
||||
/* Protect writes to evtchnfd as well as the idr lookup. */
|
||||
mutex_lock(&kvm->lock);
|
||||
evtchnfd = idr_find(&kvm->arch.xen.evtchn_ports, port);
|
||||
mutex_unlock(&kvm->lock);
|
||||
|
||||
ret = -ENOENT;
|
||||
if (!evtchnfd)
|
||||
return -ENOENT;
|
||||
goto out_unlock;
|
||||
|
||||
/* For an UPDATE, nothing may change except the priority/vcpu */
|
||||
ret = -EINVAL;
|
||||
if (evtchnfd->type != data->u.evtchn.type)
|
||||
return -EINVAL;
|
||||
goto out_unlock;
|
||||
|
||||
/*
|
||||
* Port cannot change, and if it's zero that was an eventfd
|
||||
@ -1846,20 +1829,21 @@ static int kvm_xen_eventfd_update(struct kvm *kvm,
|
||||
*/
|
||||
if (!evtchnfd->deliver.port.port ||
|
||||
evtchnfd->deliver.port.port != data->u.evtchn.deliver.port.port)
|
||||
return -EINVAL;
|
||||
goto out_unlock;
|
||||
|
||||
/* We only support 2 level event channels for now */
|
||||
if (data->u.evtchn.deliver.port.priority != KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL)
|
||||
return -EINVAL;
|
||||
goto out_unlock;
|
||||
|
||||
mutex_lock(&kvm->lock);
|
||||
evtchnfd->deliver.port.priority = data->u.evtchn.deliver.port.priority;
|
||||
if (evtchnfd->deliver.port.vcpu_id != data->u.evtchn.deliver.port.vcpu) {
|
||||
evtchnfd->deliver.port.vcpu_id = data->u.evtchn.deliver.port.vcpu;
|
||||
evtchnfd->deliver.port.vcpu_idx = -1;
|
||||
}
|
||||
ret = 0;
|
||||
out_unlock:
|
||||
mutex_unlock(&kvm->lock);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1871,12 +1855,9 @@ static int kvm_xen_eventfd_assign(struct kvm *kvm,
|
||||
{
|
||||
u32 port = data->u.evtchn.send_port;
|
||||
struct eventfd_ctx *eventfd = NULL;
|
||||
struct evtchnfd *evtchnfd = NULL;
|
||||
struct evtchnfd *evtchnfd;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (!port || port >= max_evtchn_port(kvm))
|
||||
return -EINVAL;
|
||||
|
||||
evtchnfd = kzalloc(sizeof(struct evtchnfd), GFP_KERNEL);
|
||||
if (!evtchnfd)
|
||||
return -ENOMEM;
|
||||
@ -1952,8 +1933,7 @@ static int kvm_xen_eventfd_deassign(struct kvm *kvm, u32 port)
|
||||
if (!evtchnfd)
|
||||
return -ENOENT;
|
||||
|
||||
if (kvm)
|
||||
synchronize_srcu(&kvm->srcu);
|
||||
synchronize_srcu(&kvm->srcu);
|
||||
if (!evtchnfd->deliver.port.port)
|
||||
eventfd_ctx_put(evtchnfd->deliver.eventfd.ctx);
|
||||
kfree(evtchnfd);
|
||||
@ -1962,18 +1942,42 @@ static int kvm_xen_eventfd_deassign(struct kvm *kvm, u32 port)
|
||||
|
||||
static int kvm_xen_eventfd_reset(struct kvm *kvm)
|
||||
{
|
||||
struct evtchnfd *evtchnfd;
|
||||
struct evtchnfd *evtchnfd, **all_evtchnfds;
|
||||
int i;
|
||||
int n = 0;
|
||||
|
||||
mutex_lock(&kvm->lock);
|
||||
|
||||
/*
|
||||
* Because synchronize_srcu() cannot be called inside the
|
||||
* critical section, first collect all the evtchnfd objects
|
||||
* in an array as they are removed from evtchn_ports.
|
||||
*/
|
||||
idr_for_each_entry(&kvm->arch.xen.evtchn_ports, evtchnfd, i)
|
||||
n++;
|
||||
|
||||
all_evtchnfds = kmalloc_array(n, sizeof(struct evtchnfd *), GFP_KERNEL);
|
||||
if (!all_evtchnfds) {
|
||||
mutex_unlock(&kvm->lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
n = 0;
|
||||
idr_for_each_entry(&kvm->arch.xen.evtchn_ports, evtchnfd, i) {
|
||||
all_evtchnfds[n++] = evtchnfd;
|
||||
idr_remove(&kvm->arch.xen.evtchn_ports, evtchnfd->send_port);
|
||||
synchronize_srcu(&kvm->srcu);
|
||||
}
|
||||
mutex_unlock(&kvm->lock);
|
||||
|
||||
synchronize_srcu(&kvm->srcu);
|
||||
|
||||
while (n--) {
|
||||
evtchnfd = all_evtchnfds[n];
|
||||
if (!evtchnfd->deliver.port.port)
|
||||
eventfd_ctx_put(evtchnfd->deliver.eventfd.ctx);
|
||||
kfree(evtchnfd);
|
||||
}
|
||||
mutex_unlock(&kvm->lock);
|
||||
kfree(all_evtchnfds);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2002,20 +2006,22 @@ static bool kvm_xen_hcall_evtchn_send(struct kvm_vcpu *vcpu, u64 param, u64 *r)
|
||||
{
|
||||
struct evtchnfd *evtchnfd;
|
||||
struct evtchn_send send;
|
||||
gpa_t gpa;
|
||||
int idx;
|
||||
struct x86_exception e;
|
||||
|
||||
idx = srcu_read_lock(&vcpu->kvm->srcu);
|
||||
gpa = kvm_mmu_gva_to_gpa_system(vcpu, param, NULL);
|
||||
srcu_read_unlock(&vcpu->kvm->srcu, idx);
|
||||
|
||||
if (!gpa || kvm_vcpu_read_guest(vcpu, gpa, &send, sizeof(send))) {
|
||||
/* Sanity check: this structure is the same for 32-bit and 64-bit */
|
||||
BUILD_BUG_ON(sizeof(send) != 4);
|
||||
if (kvm_read_guest_virt(vcpu, param, &send, sizeof(send), &e)) {
|
||||
*r = -EFAULT;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* The evtchn_ports idr is protected by vcpu->kvm->srcu */
|
||||
/*
|
||||
* evtchnfd is protected by kvm->srcu; the idr lookup instead
|
||||
* is protected by RCU.
|
||||
*/
|
||||
rcu_read_lock();
|
||||
evtchnfd = idr_find(&vcpu->kvm->arch.xen.evtchn_ports, send.port);
|
||||
rcu_read_unlock();
|
||||
if (!evtchnfd)
|
||||
return false;
|
||||
|
||||
|
@ -1595,16 +1595,16 @@ bool insn_decode_from_regs(struct insn *insn, struct pt_regs *regs,
|
||||
* Returns:
|
||||
*
|
||||
* Type of the instruction. Size of the memory operand is stored in
|
||||
* @bytes. If decode failed, MMIO_DECODE_FAILED returned.
|
||||
* @bytes. If decode failed, INSN_MMIO_DECODE_FAILED returned.
|
||||
*/
|
||||
enum mmio_type insn_decode_mmio(struct insn *insn, int *bytes)
|
||||
enum insn_mmio_type insn_decode_mmio(struct insn *insn, int *bytes)
|
||||
{
|
||||
enum mmio_type type = MMIO_DECODE_FAILED;
|
||||
enum insn_mmio_type type = INSN_MMIO_DECODE_FAILED;
|
||||
|
||||
*bytes = 0;
|
||||
|
||||
if (insn_get_opcode(insn))
|
||||
return MMIO_DECODE_FAILED;
|
||||
return INSN_MMIO_DECODE_FAILED;
|
||||
|
||||
switch (insn->opcode.bytes[0]) {
|
||||
case 0x88: /* MOV m8,r8 */
|
||||
@ -1613,7 +1613,7 @@ enum mmio_type insn_decode_mmio(struct insn *insn, int *bytes)
|
||||
case 0x89: /* MOV m16/m32/m64, r16/m32/m64 */
|
||||
if (!*bytes)
|
||||
*bytes = insn->opnd_bytes;
|
||||
type = MMIO_WRITE;
|
||||
type = INSN_MMIO_WRITE;
|
||||
break;
|
||||
|
||||
case 0xc6: /* MOV m8, imm8 */
|
||||
@ -1622,7 +1622,7 @@ enum mmio_type insn_decode_mmio(struct insn *insn, int *bytes)
|
||||
case 0xc7: /* MOV m16/m32/m64, imm16/imm32/imm64 */
|
||||
if (!*bytes)
|
||||
*bytes = insn->opnd_bytes;
|
||||
type = MMIO_WRITE_IMM;
|
||||
type = INSN_MMIO_WRITE_IMM;
|
||||
break;
|
||||
|
||||
case 0x8a: /* MOV r8, m8 */
|
||||
@ -1631,7 +1631,7 @@ enum mmio_type insn_decode_mmio(struct insn *insn, int *bytes)
|
||||
case 0x8b: /* MOV r16/r32/r64, m16/m32/m64 */
|
||||
if (!*bytes)
|
||||
*bytes = insn->opnd_bytes;
|
||||
type = MMIO_READ;
|
||||
type = INSN_MMIO_READ;
|
||||
break;
|
||||
|
||||
case 0xa4: /* MOVS m8, m8 */
|
||||
@ -1640,7 +1640,7 @@ enum mmio_type insn_decode_mmio(struct insn *insn, int *bytes)
|
||||
case 0xa5: /* MOVS m16/m32/m64, m16/m32/m64 */
|
||||
if (!*bytes)
|
||||
*bytes = insn->opnd_bytes;
|
||||
type = MMIO_MOVS;
|
||||
type = INSN_MMIO_MOVS;
|
||||
break;
|
||||
|
||||
case 0x0f: /* Two-byte instruction */
|
||||
@ -1651,7 +1651,7 @@ enum mmio_type insn_decode_mmio(struct insn *insn, int *bytes)
|
||||
case 0xb7: /* MOVZX r32/r64, m16 */
|
||||
if (!*bytes)
|
||||
*bytes = 2;
|
||||
type = MMIO_READ_ZERO_EXTEND;
|
||||
type = INSN_MMIO_READ_ZERO_EXTEND;
|
||||
break;
|
||||
|
||||
case 0xbe: /* MOVSX r16/r32/r64, m8 */
|
||||
@ -1660,7 +1660,7 @@ enum mmio_type insn_decode_mmio(struct insn *insn, int *bytes)
|
||||
case 0xbf: /* MOVSX r32/r64, m16 */
|
||||
if (!*bytes)
|
||||
*bytes = 2;
|
||||
type = MMIO_READ_SIGN_EXTEND;
|
||||
type = INSN_MMIO_READ_SIGN_EXTEND;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -10,6 +10,6 @@
|
||||
*/
|
||||
SYM_FUNC_START(__iowrite32_copy)
|
||||
movl %edx,%ecx
|
||||
rep movsd
|
||||
rep movsl
|
||||
RET
|
||||
SYM_FUNC_END(__iowrite32_copy)
|
||||
|
@ -724,19 +724,19 @@ void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
* sure that the reference to cgroup is valid across the call (see
|
||||
* comments in bfq_bic_update_cgroup on this issue)
|
||||
*/
|
||||
static void *__bfq_bic_change_cgroup(struct bfq_data *bfqd,
|
||||
struct bfq_io_cq *bic,
|
||||
struct bfq_group *bfqg)
|
||||
static void __bfq_bic_change_cgroup(struct bfq_data *bfqd,
|
||||
struct bfq_io_cq *bic,
|
||||
struct bfq_group *bfqg)
|
||||
{
|
||||
struct bfq_queue *async_bfqq = bic_to_bfqq(bic, 0);
|
||||
struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, 1);
|
||||
struct bfq_queue *async_bfqq = bic_to_bfqq(bic, false);
|
||||
struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, true);
|
||||
struct bfq_entity *entity;
|
||||
|
||||
if (async_bfqq) {
|
||||
entity = &async_bfqq->entity;
|
||||
|
||||
if (entity->sched_data != &bfqg->sched_data) {
|
||||
bic_set_bfqq(bic, NULL, 0);
|
||||
bic_set_bfqq(bic, NULL, false);
|
||||
bfq_release_process_ref(bfqd, async_bfqq);
|
||||
}
|
||||
}
|
||||
@ -772,12 +772,10 @@ static void *__bfq_bic_change_cgroup(struct bfq_data *bfqd,
|
||||
*/
|
||||
bfq_put_cooperator(sync_bfqq);
|
||||
bfq_release_process_ref(bfqd, sync_bfqq);
|
||||
bic_set_bfqq(bic, NULL, 1);
|
||||
bic_set_bfqq(bic, NULL, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bfqg;
|
||||
}
|
||||
|
||||
void bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio)
|
||||
|
@ -386,6 +386,12 @@ static void bfq_put_stable_ref(struct bfq_queue *bfqq);
|
||||
|
||||
void bic_set_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq, bool is_sync)
|
||||
{
|
||||
struct bfq_queue *old_bfqq = bic->bfqq[is_sync];
|
||||
|
||||
/* Clear bic pointer if bfqq is detached from this bic */
|
||||
if (old_bfqq && old_bfqq->bic == bic)
|
||||
old_bfqq->bic = NULL;
|
||||
|
||||
/*
|
||||
* If bfqq != NULL, then a non-stable queue merge between
|
||||
* bic->bfqq and bfqq is happening here. This causes troubles
|
||||
@ -3108,7 +3114,7 @@ bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic,
|
||||
/*
|
||||
* Merge queues (that is, let bic redirect its requests to new_bfqq)
|
||||
*/
|
||||
bic_set_bfqq(bic, new_bfqq, 1);
|
||||
bic_set_bfqq(bic, new_bfqq, true);
|
||||
bfq_mark_bfqq_coop(new_bfqq);
|
||||
/*
|
||||
* new_bfqq now belongs to at least two bics (it is a shared queue):
|
||||
@ -5311,9 +5317,8 @@ static void bfq_exit_icq_bfqq(struct bfq_io_cq *bic, bool is_sync)
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&bfqd->lock, flags);
|
||||
bfqq->bic = NULL;
|
||||
bfq_exit_bfqq(bfqd, bfqq);
|
||||
bic_set_bfqq(bic, NULL, is_sync);
|
||||
bfq_exit_bfqq(bfqd, bfqq);
|
||||
spin_unlock_irqrestore(&bfqd->lock, flags);
|
||||
}
|
||||
}
|
||||
@ -6557,7 +6562,7 @@ bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq)
|
||||
return bfqq;
|
||||
}
|
||||
|
||||
bic_set_bfqq(bic, NULL, 1);
|
||||
bic_set_bfqq(bic, NULL, true);
|
||||
|
||||
bfq_put_cooperator(bfqq);
|
||||
|
||||
@ -7058,7 +7063,9 @@ static int bfq_init_queue(struct request_queue *q, struct elevator_type *e)
|
||||
bfqd->idle_slice_timer.function = bfq_idle_slice_timer;
|
||||
|
||||
bfqd->queue_weights_tree = RB_ROOT_CACHED;
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
bfqd->num_groups_with_pending_reqs = 0;
|
||||
#endif
|
||||
|
||||
INIT_LIST_HEAD(&bfqd->active_list);
|
||||
INIT_LIST_HEAD(&bfqd->idle_list);
|
||||
|
@ -197,8 +197,10 @@ struct bfq_entity {
|
||||
/* flag, set to request a weight, ioprio or ioprio_class change */
|
||||
int prio_changed;
|
||||
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
/* flag, set if the entity is counted in groups_with_pending_reqs */
|
||||
bool in_groups_with_pending_reqs;
|
||||
#endif
|
||||
|
||||
/* last child queue of entity created (for non-leaf entities) */
|
||||
struct bfq_queue *last_bfqq_created;
|
||||
@ -491,6 +493,7 @@ struct bfq_data {
|
||||
*/
|
||||
struct rb_root_cached queue_weights_tree;
|
||||
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
/*
|
||||
* Number of groups with at least one process that
|
||||
* has at least one request waiting for completion. Note that
|
||||
@ -538,6 +541,7 @@ struct bfq_data {
|
||||
* with no request waiting for completion.
|
||||
*/
|
||||
unsigned int num_groups_with_pending_reqs;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Per-class (RT, BE, IDLE) number of bfq_queues containing
|
||||
|
@ -1612,28 +1612,28 @@ void bfq_requeue_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
|
||||
void bfq_add_bfqq_in_groups_with_pending_reqs(struct bfq_queue *bfqq)
|
||||
{
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
struct bfq_entity *entity = &bfqq->entity;
|
||||
|
||||
if (!entity->in_groups_with_pending_reqs) {
|
||||
entity->in_groups_with_pending_reqs = true;
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
if (!(bfqq_group(bfqq)->num_queues_with_pending_reqs++))
|
||||
bfqq->bfqd->num_groups_with_pending_reqs++;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void bfq_del_bfqq_in_groups_with_pending_reqs(struct bfq_queue *bfqq)
|
||||
{
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
struct bfq_entity *entity = &bfqq->entity;
|
||||
|
||||
if (entity->in_groups_with_pending_reqs) {
|
||||
entity->in_groups_with_pending_reqs = false;
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
if (!(--bfqq_group(bfqq)->num_queues_with_pending_reqs))
|
||||
bfqq->bfqd->num_groups_with_pending_reqs--;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "blk-cgroup.h"
|
||||
#include "blk-ioprio.h"
|
||||
#include "blk-throttle.h"
|
||||
#include "blk-rq-qos.h"
|
||||
|
||||
/*
|
||||
* blkcg_pol_mutex protects blkcg_policy[] and policy [de]activation.
|
||||
@ -1322,6 +1323,7 @@ err_unlock:
|
||||
void blkcg_exit_disk(struct gendisk *disk)
|
||||
{
|
||||
blkg_destroy_all(disk);
|
||||
rq_qos_exit(disk->queue);
|
||||
blk_throtl_exit(disk);
|
||||
}
|
||||
|
||||
|
@ -254,14 +254,15 @@ EXPORT_SYMBOL_GPL(blk_clear_pm_only);
|
||||
|
||||
static void blk_free_queue_rcu(struct rcu_head *rcu_head)
|
||||
{
|
||||
kmem_cache_free(blk_requestq_cachep,
|
||||
container_of(rcu_head, struct request_queue, rcu_head));
|
||||
struct request_queue *q = container_of(rcu_head,
|
||||
struct request_queue, rcu_head);
|
||||
|
||||
percpu_ref_exit(&q->q_usage_counter);
|
||||
kmem_cache_free(blk_requestq_cachep, q);
|
||||
}
|
||||
|
||||
static void blk_free_queue(struct request_queue *q)
|
||||
{
|
||||
percpu_ref_exit(&q->q_usage_counter);
|
||||
|
||||
if (q->poll_stat)
|
||||
blk_stat_remove_callback(q, q->poll_cb);
|
||||
blk_stat_free_callback(q->poll_cb);
|
||||
|
@ -232,7 +232,9 @@ enum {
|
||||
|
||||
/* 1/64k is granular enough and can easily be handled w/ u32 */
|
||||
WEIGHT_ONE = 1 << 16,
|
||||
};
|
||||
|
||||
enum {
|
||||
/*
|
||||
* As vtime is used to calculate the cost of each IO, it needs to
|
||||
* be fairly high precision. For example, it should be able to
|
||||
@ -2818,7 +2820,7 @@ static void ioc_rqos_exit(struct rq_qos *rqos)
|
||||
ioc->running = IOC_STOP;
|
||||
spin_unlock_irq(&ioc->lock);
|
||||
|
||||
del_timer_sync(&ioc->timer);
|
||||
timer_shutdown_sync(&ioc->timer);
|
||||
free_percpu(ioc->pcpu_stat);
|
||||
kfree(ioc);
|
||||
}
|
||||
|
@ -644,7 +644,7 @@ static void blkcg_iolatency_exit(struct rq_qos *rqos)
|
||||
{
|
||||
struct blk_iolatency *blkiolat = BLKIOLATENCY(rqos);
|
||||
|
||||
del_timer_sync(&blkiolat->timer);
|
||||
timer_shutdown_sync(&blkiolat->timer);
|
||||
flush_work(&blkiolat->enable_work);
|
||||
blkcg_deactivate_policy(rqos->q, &blkcg_policy_iolatency);
|
||||
kfree(blkiolat);
|
||||
|
@ -434,7 +434,7 @@ static void kyber_exit_sched(struct elevator_queue *e)
|
||||
struct kyber_queue_data *kqd = e->elevator_data;
|
||||
int i;
|
||||
|
||||
del_timer_sync(&kqd->timer);
|
||||
timer_shutdown_sync(&kqd->timer);
|
||||
blk_stat_disable_accounting(kqd->q);
|
||||
|
||||
for (i = 0; i < KYBER_NUM_DOMAINS; i++)
|
||||
|
@ -70,11 +70,7 @@ module_param(device_id_scheme, bool, 0444);
|
||||
static int only_lcd = -1;
|
||||
module_param(only_lcd, int, 0444);
|
||||
|
||||
/*
|
||||
* Display probing is known to take up to 5 seconds, so delay the fallback
|
||||
* backlight registration by 5 seconds + 3 seconds for some extra margin.
|
||||
*/
|
||||
static int register_backlight_delay = 8;
|
||||
static int register_backlight_delay;
|
||||
module_param(register_backlight_delay, int, 0444);
|
||||
MODULE_PARM_DESC(register_backlight_delay,
|
||||
"Delay in seconds before doing fallback (non GPU driver triggered) "
|
||||
@ -2176,6 +2172,17 @@ static bool should_check_lcd_flag(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* At least one graphics driver has reported that no LCD is connected
|
||||
* via the native interface. cancel the registration for fallback acpi_video0.
|
||||
* If another driver still deems this necessary, it can explicitly register it.
|
||||
*/
|
||||
void acpi_video_report_nolcd(void)
|
||||
{
|
||||
cancel_delayed_work(&video_bus_register_backlight_work);
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_video_report_nolcd);
|
||||
|
||||
int acpi_video_register(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -1431,7 +1431,7 @@ static int ghes_remove(struct platform_device *ghes_dev)
|
||||
ghes->flags |= GHES_EXITING;
|
||||
switch (generic->notify.type) {
|
||||
case ACPI_HEST_NOTIFY_POLLED:
|
||||
del_timer_sync(&ghes->timer);
|
||||
timer_shutdown_sync(&ghes->timer);
|
||||
break;
|
||||
case ACPI_HEST_NOTIFY_EXTERNAL:
|
||||
free_irq(ghes->irq, ghes);
|
||||
|
@ -432,10 +432,24 @@ static const struct dmi_system_id asus_laptop[] = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "S5602ZA"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Asus ExpertBook B2502",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "B2502CBA"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct dmi_system_id lenovo_82ra[] = {
|
||||
static const struct dmi_system_id lenovo_laptop[] = {
|
||||
{
|
||||
.ident = "LENOVO IdeaPad Flex 5 14ALC7",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "82R9"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "LENOVO IdeaPad Flex 5 16ALC7",
|
||||
.matches = {
|
||||
@ -446,6 +460,17 @@ static const struct dmi_system_id lenovo_82ra[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct dmi_system_id schenker_gm_rg[] = {
|
||||
{
|
||||
.ident = "XMG CORE 15 (M22)",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "GMxRGxx"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
struct irq_override_cmp {
|
||||
const struct dmi_system_id *system;
|
||||
unsigned char irq;
|
||||
@ -458,8 +483,9 @@ struct irq_override_cmp {
|
||||
static const struct irq_override_cmp override_table[] = {
|
||||
{ medion_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, false },
|
||||
{ asus_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, false },
|
||||
{ lenovo_82ra, 6, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, true },
|
||||
{ lenovo_82ra, 10, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, true },
|
||||
{ lenovo_laptop, 6, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, true },
|
||||
{ lenovo_laptop, 10, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, true },
|
||||
{ schenker_gm_rg, 1, ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_LOW, 1, true },
|
||||
};
|
||||
|
||||
static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity,
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_data/x86/nvidia-wmi-ec-backlight.h>
|
||||
#include <linux/pnp.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <acpi/video.h>
|
||||
@ -105,6 +106,26 @@ static bool nvidia_wmi_ec_supported(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool apple_gmux_backlight_present(void)
|
||||
{
|
||||
struct acpi_device *adev;
|
||||
struct device *dev;
|
||||
|
||||
adev = acpi_dev_get_first_match_dev(GMUX_ACPI_HID, NULL, -1);
|
||||
if (!adev)
|
||||
return false;
|
||||
|
||||
dev = acpi_get_first_physical_node(adev);
|
||||
if (!dev)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* drivers/platform/x86/apple-gmux.c only supports old style
|
||||
* Apple GMUX with an IO-resource.
|
||||
*/
|
||||
return pnp_get_resource(to_pnp_dev(dev), IORESOURCE_IO, 0) != NULL;
|
||||
}
|
||||
|
||||
/* Force to use vendor driver when the ACPI device is known to be
|
||||
* buggy */
|
||||
static int video_detect_force_vendor(const struct dmi_system_id *d)
|
||||
@ -767,7 +788,7 @@ static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
|
||||
if (nvidia_wmi_ec_present)
|
||||
return acpi_backlight_nvidia_wmi_ec;
|
||||
|
||||
if (apple_gmux_present())
|
||||
if (apple_gmux_backlight_present())
|
||||
return acpi_backlight_apple_gmux;
|
||||
|
||||
/* Use ACPI video if available, except when native should be preferred. */
|
||||
|
@ -28,10 +28,6 @@ static bool sleep_no_lps0 __read_mostly;
|
||||
module_param(sleep_no_lps0, bool, 0644);
|
||||
MODULE_PARM_DESC(sleep_no_lps0, "Do not use the special LPS0 device interface");
|
||||
|
||||
static bool prefer_microsoft_dsm_guid __read_mostly;
|
||||
module_param(prefer_microsoft_dsm_guid, bool, 0644);
|
||||
MODULE_PARM_DESC(prefer_microsoft_dsm_guid, "Prefer using Microsoft GUID in LPS0 device _DSM evaluation");
|
||||
|
||||
static const struct acpi_device_id lps0_device_ids[] = {
|
||||
{"PNP0D80", },
|
||||
{"", },
|
||||
@ -369,27 +365,15 @@ out:
|
||||
}
|
||||
|
||||
struct amd_lps0_hid_device_data {
|
||||
const unsigned int rev_id;
|
||||
const bool check_off_by_one;
|
||||
const bool prefer_amd_guid;
|
||||
};
|
||||
|
||||
static const struct amd_lps0_hid_device_data amd_picasso = {
|
||||
.rev_id = 0,
|
||||
.check_off_by_one = true,
|
||||
.prefer_amd_guid = false,
|
||||
};
|
||||
|
||||
static const struct amd_lps0_hid_device_data amd_cezanne = {
|
||||
.rev_id = 0,
|
||||
.check_off_by_one = false,
|
||||
.prefer_amd_guid = false,
|
||||
};
|
||||
|
||||
static const struct amd_lps0_hid_device_data amd_rembrandt = {
|
||||
.rev_id = 2,
|
||||
.check_off_by_one = false,
|
||||
.prefer_amd_guid = true,
|
||||
};
|
||||
|
||||
static const struct acpi_device_id amd_hid_ids[] = {
|
||||
@ -397,69 +381,27 @@ static const struct acpi_device_id amd_hid_ids[] = {
|
||||
{"AMD0005", (kernel_ulong_t)&amd_picasso, },
|
||||
{"AMDI0005", (kernel_ulong_t)&amd_picasso, },
|
||||
{"AMDI0006", (kernel_ulong_t)&amd_cezanne, },
|
||||
{"AMDI0007", (kernel_ulong_t)&amd_rembrandt, },
|
||||
{}
|
||||
};
|
||||
|
||||
static int lps0_prefer_microsoft(const struct dmi_system_id *id)
|
||||
static int lps0_prefer_amd(const struct dmi_system_id *id)
|
||||
{
|
||||
pr_debug("Preferring Microsoft GUID.\n");
|
||||
prefer_microsoft_dsm_guid = true;
|
||||
pr_debug("Using AMD GUID w/ _REV 2.\n");
|
||||
rev_id = 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dmi_system_id s2idle_dmi_table[] __initconst = {
|
||||
{
|
||||
/*
|
||||
* ASUS TUF Gaming A17 FA707RE
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=216101
|
||||
* AMD Rembrandt based HP EliteBook 835/845/865 G9
|
||||
* Contains specialized AML in AMD/_REV 2 path to avoid
|
||||
* triggering a bug in Qualcomm WLAN firmware. This may be
|
||||
* removed in the future if that firmware is fixed.
|
||||
*/
|
||||
.callback = lps0_prefer_microsoft,
|
||||
.callback = lps0_prefer_amd,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "ASUS TUF Gaming A17"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* ASUS ROG Zephyrus G14 (2022) */
|
||||
.callback = lps0_prefer_microsoft,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "ROG Zephyrus G14 GA402"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Lenovo Yoga Slim 7 Pro X 14ARH7
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=216473 : 82V2
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=216438 : 82TL
|
||||
*/
|
||||
.callback = lps0_prefer_microsoft,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "82"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/*
|
||||
* ASUSTeK COMPUTER INC. ROG Flow X13 GV301RE_GV301RE
|
||||
* https://gitlab.freedesktop.org/drm/amd/-/issues/2148
|
||||
*/
|
||||
.callback = lps0_prefer_microsoft,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "ROG Flow X13 GV301"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/*
|
||||
* ASUSTeK COMPUTER INC. ROG Flow X16 GV601RW_GV601RW
|
||||
* https://gitlab.freedesktop.org/drm/amd/-/issues/2148
|
||||
*/
|
||||
.callback = lps0_prefer_microsoft,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "ROG Flow X16 GV601"),
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "8990"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
@ -484,16 +426,14 @@ static int lps0_device_attach(struct acpi_device *adev,
|
||||
if (dev_id->id[0])
|
||||
data = (const struct amd_lps0_hid_device_data *) dev_id->driver_data;
|
||||
else
|
||||
data = &amd_rembrandt;
|
||||
rev_id = data->rev_id;
|
||||
data = &amd_cezanne;
|
||||
lps0_dsm_func_mask = validate_dsm(adev->handle,
|
||||
ACPI_LPS0_DSM_UUID_AMD, rev_id, &lps0_dsm_guid);
|
||||
if (lps0_dsm_func_mask > 0x3 && data->check_off_by_one) {
|
||||
lps0_dsm_func_mask = (lps0_dsm_func_mask << 1) | 0x1;
|
||||
acpi_handle_debug(adev->handle, "_DSM UUID %s: Adjusted function mask: 0x%x\n",
|
||||
ACPI_LPS0_DSM_UUID_AMD, lps0_dsm_func_mask);
|
||||
} else if (lps0_dsm_func_mask_microsoft > 0 && data->prefer_amd_guid &&
|
||||
!prefer_microsoft_dsm_guid) {
|
||||
} else if (lps0_dsm_func_mask_microsoft > 0 && rev_id) {
|
||||
lps0_dsm_func_mask_microsoft = -EINVAL;
|
||||
acpi_handle_debug(adev->handle, "_DSM Using AMD method\n");
|
||||
}
|
||||
@ -501,8 +441,7 @@ static int lps0_device_attach(struct acpi_device *adev,
|
||||
rev_id = 1;
|
||||
lps0_dsm_func_mask = validate_dsm(adev->handle,
|
||||
ACPI_LPS0_DSM_UUID, rev_id, &lps0_dsm_guid);
|
||||
if (!prefer_microsoft_dsm_guid)
|
||||
lps0_dsm_func_mask_microsoft = -EINVAL;
|
||||
lps0_dsm_func_mask_microsoft = -EINVAL;
|
||||
}
|
||||
|
||||
if (lps0_dsm_func_mask < 0 && lps0_dsm_func_mask_microsoft < 0)
|
||||
|
@ -83,6 +83,7 @@ enum board_ids {
|
||||
static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
|
||||
static void ahci_remove_one(struct pci_dev *dev);
|
||||
static void ahci_shutdown_one(struct pci_dev *dev);
|
||||
static void ahci_intel_pcs_quirk(struct pci_dev *pdev, struct ahci_host_priv *hpriv);
|
||||
static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
|
||||
unsigned long deadline);
|
||||
static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
|
||||
@ -676,6 +677,25 @@ static void ahci_pci_save_initial_config(struct pci_dev *pdev,
|
||||
ahci_save_initial_config(&pdev->dev, hpriv);
|
||||
}
|
||||
|
||||
static int ahci_pci_reset_controller(struct ata_host *host)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(host->dev);
|
||||
struct ahci_host_priv *hpriv = host->private_data;
|
||||
int rc;
|
||||
|
||||
rc = ahci_reset_controller(host);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/*
|
||||
* If platform firmware failed to enable ports, try to enable
|
||||
* them here.
|
||||
*/
|
||||
ahci_intel_pcs_quirk(pdev, hpriv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ahci_pci_init_controller(struct ata_host *host)
|
||||
{
|
||||
struct ahci_host_priv *hpriv = host->private_data;
|
||||
@ -870,7 +890,7 @@ static int ahci_pci_device_runtime_resume(struct device *dev)
|
||||
struct ata_host *host = pci_get_drvdata(pdev);
|
||||
int rc;
|
||||
|
||||
rc = ahci_reset_controller(host);
|
||||
rc = ahci_pci_reset_controller(host);
|
||||
if (rc)
|
||||
return rc;
|
||||
ahci_pci_init_controller(host);
|
||||
@ -906,7 +926,7 @@ static int ahci_pci_device_resume(struct device *dev)
|
||||
ahci_mcp89_apple_enable(pdev);
|
||||
|
||||
if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
|
||||
rc = ahci_reset_controller(host);
|
||||
rc = ahci_pci_reset_controller(host);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@ -1784,12 +1804,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
/* save initial config */
|
||||
ahci_pci_save_initial_config(pdev, hpriv);
|
||||
|
||||
/*
|
||||
* If platform firmware failed to enable ports, try to enable
|
||||
* them here.
|
||||
*/
|
||||
ahci_intel_pcs_quirk(pdev, hpriv);
|
||||
|
||||
/* prepare host */
|
||||
if (hpriv->cap & HOST_CAP_NCQ) {
|
||||
pi.flags |= ATA_FLAG_NCQ;
|
||||
@ -1899,7 +1913,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = ahci_reset_controller(host);
|
||||
rc = ahci_pci_reset_controller(host);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user