mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 11:06:41 -05:00
Merge tag 'asoc-v6.17' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: Updates for v6.17 There's a few new drivers here and quite a lot of cleanup work from Morimoto-san but generally this has been quite a quiet release, resulting in a fairly small diffstat. Highlights include: - Refactoring of the Kconfig menus to be hopefully more consistant and easier to navigate. - Refactoring of the DAPM code, mainly hiding functionality that doesn't need to be exposed to drivers. - Removal of the unused upstream weak paths DAPM functionality. - Further work on the generic handling for SoundWire SDCA devices. - Cleanups of our usage of the PM autosuspend functions, this pulls in some PM core changes on a shared tag. - Support for AMD ACP7.2 and SoundWire on ACP 7.1, Fairphone 4 & 5, various Intel systems, Qualcomm QCS8275, Richtek RTQ9124 and TI TAS5753.
This commit is contained in:
1
.mailmap
1
.mailmap
@@ -416,6 +416,7 @@ Kenneth W Chen <kenneth.w.chen@intel.com>
|
||||
Kenneth Westfield <quic_kwestfie@quicinc.com> <kwestfie@codeaurora.org>
|
||||
Kiran Gunda <quic_kgunda@quicinc.com> <kgunda@codeaurora.org>
|
||||
Kirill Tkhai <tkhai@ya.ru> <ktkhai@virtuozzo.com>
|
||||
Kirill A. Shutemov <kas@kernel.org> <kirill.shutemov@linux.intel.com>
|
||||
Kishon Vijay Abraham I <kishon@kernel.org> <kishon@ti.com>
|
||||
Konrad Dybcio <konradybcio@kernel.org> <konrad.dybcio@linaro.org>
|
||||
Konrad Dybcio <konradybcio@kernel.org> <konrad.dybcio@somainline.org>
|
||||
|
||||
@@ -56,7 +56,7 @@ Date: January 2009
|
||||
Contact: Rafael J. Wysocki <rjw@rjwysocki.net>
|
||||
Description:
|
||||
The /sys/devices/.../async attribute allows the user space to
|
||||
enable or diasble the device's suspend and resume callbacks to
|
||||
enable or disable the device's suspend and resume callbacks to
|
||||
be executed asynchronously (ie. in separate threads, in parallel
|
||||
with the main suspend/resume thread) during system-wide power
|
||||
transitions (eg. suspend to RAM, hibernation).
|
||||
|
||||
@@ -584,6 +584,7 @@ What: /sys/devices/system/cpu/vulnerabilities
|
||||
/sys/devices/system/cpu/vulnerabilities/spectre_v1
|
||||
/sys/devices/system/cpu/vulnerabilities/spectre_v2
|
||||
/sys/devices/system/cpu/vulnerabilities/srbds
|
||||
/sys/devices/system/cpu/vulnerabilities/tsa
|
||||
/sys/devices/system/cpu/vulnerabilities/tsx_async_abort
|
||||
Date: January 2018
|
||||
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
|
||||
|
||||
@@ -711,7 +711,7 @@ Description: This file shows the thin provisioning type. This is one of
|
||||
|
||||
The file is read only.
|
||||
|
||||
What: /sys/class/scsi_device/*/device/unit_descriptor/physical_memory_resourse_count
|
||||
What: /sys/class/scsi_device/*/device/unit_descriptor/physical_memory_resource_count
|
||||
Date: February 2018
|
||||
Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com>
|
||||
Description: This file shows the total physical memory resources. This is
|
||||
|
||||
@@ -1732,12 +1732,6 @@ The following nested keys are defined.
|
||||
numa_hint_faults (npn)
|
||||
Number of NUMA hinting faults.
|
||||
|
||||
numa_task_migrated (npn)
|
||||
Number of task migration by NUMA balancing.
|
||||
|
||||
numa_task_swapped (npn)
|
||||
Number of task swap by NUMA balancing.
|
||||
|
||||
pgdemote_kswapd
|
||||
Number of pages demoted by kswapd.
|
||||
|
||||
|
||||
@@ -157,9 +157,7 @@ This is achieved by using the otherwise unused and obsolete VERW instruction in
|
||||
combination with a microcode update. The microcode clears the affected CPU
|
||||
buffers when the VERW instruction is executed.
|
||||
|
||||
Kernel reuses the MDS function to invoke the buffer clearing:
|
||||
|
||||
mds_clear_cpu_buffers()
|
||||
Kernel does the buffer clearing with x86_clear_cpu_buffers().
|
||||
|
||||
On MDS affected CPUs, the kernel already invokes CPU buffer clear on
|
||||
kernel/userspace, hypervisor/guest and C-state (idle) transitions. No
|
||||
|
||||
@@ -7488,6 +7488,19 @@
|
||||
having this key zero'ed is acceptable. E.g. in testing
|
||||
scenarios.
|
||||
|
||||
tsa= [X86] Control mitigation for Transient Scheduler
|
||||
Attacks on AMD CPUs. Search the following in your
|
||||
favourite search engine for more details:
|
||||
|
||||
"Technical guidance for mitigating transient scheduler
|
||||
attacks".
|
||||
|
||||
off - disable the mitigation
|
||||
on - enable the mitigation (default)
|
||||
user - mitigate only user/kernel transitions
|
||||
vm - mitigate only guest/host transitions
|
||||
|
||||
|
||||
tsc= Disable clocksource stability checks for TSC.
|
||||
Format: <string>
|
||||
[x86] reliable: mark tsc clocksource as reliable, this
|
||||
|
||||
@@ -93,7 +93,7 @@ enters a C-state.
|
||||
|
||||
The kernel provides a function to invoke the buffer clearing:
|
||||
|
||||
mds_clear_cpu_buffers()
|
||||
x86_clear_cpu_buffers()
|
||||
|
||||
Also macro CLEAR_CPU_BUFFERS can be used in ASM late in exit-to-user path.
|
||||
Other than CFLAGS.ZF, this macro doesn't clobber any registers.
|
||||
@@ -185,9 +185,9 @@ Mitigation points
|
||||
idle clearing would be a window dressing exercise and is therefore not
|
||||
activated.
|
||||
|
||||
The invocation is controlled by the static key mds_idle_clear which is
|
||||
switched depending on the chosen mitigation mode and the SMT state of
|
||||
the system.
|
||||
The invocation is controlled by the static key cpu_buf_idle_clear which is
|
||||
switched depending on the chosen mitigation mode and the SMT state of the
|
||||
system.
|
||||
|
||||
The buffer clear is only invoked before entering the C-State to prevent
|
||||
that stale data from the idling CPU from spilling to the Hyper-Thread
|
||||
|
||||
@@ -52,6 +52,9 @@ properties:
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
'#reset-cells':
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
@@ -26,7 +26,8 @@ properties:
|
||||
- const: realtek,rtl9301-i2c
|
||||
|
||||
reg:
|
||||
description: Register offset and size this I2C controller.
|
||||
items:
|
||||
- description: Register offset and size this I2C controller.
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
$id: http://devicetree.org/schemas/input/elan,ekth6915.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Elan eKTH6915 touchscreen controller
|
||||
title: Elan I2C-HID touchscreen controllers
|
||||
|
||||
maintainers:
|
||||
- Douglas Anderson <dianders@chromium.org>
|
||||
|
||||
description:
|
||||
Supports the Elan eKTH6915 touchscreen controller.
|
||||
This touchscreen controller uses the i2c-hid protocol with a reset GPIO.
|
||||
Supports the Elan eKTH6915 and other I2C-HID touchscreen controllers.
|
||||
These touchscreen controller use the i2c-hid protocol with a reset GPIO.
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/input/touchscreen/touchscreen.yaml#
|
||||
@@ -23,12 +23,14 @@ properties:
|
||||
- enum:
|
||||
- elan,ekth5015m
|
||||
- const: elan,ekth6915
|
||||
- items:
|
||||
- const: elan,ekth8d18
|
||||
- const: elan,ekth6a12nay
|
||||
- enum:
|
||||
- elan,ekth6915
|
||||
- elan,ekth6a12nay
|
||||
|
||||
reg:
|
||||
const: 0x10
|
||||
reg: true
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
@@ -23,7 +23,7 @@ properties:
|
||||
- allwinner,sun20i-d1-emac
|
||||
- allwinner,sun50i-h6-emac
|
||||
- allwinner,sun50i-h616-emac0
|
||||
- allwinner,sun55i-a523-emac0
|
||||
- allwinner,sun55i-a523-gmac0
|
||||
- const: allwinner,sun50i-a64-emac
|
||||
|
||||
reg:
|
||||
|
||||
@@ -80,6 +80,8 @@ examples:
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <296 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "macirq";
|
||||
phy-handle = <&phy0>;
|
||||
phy-mode = "rgmii-id";
|
||||
resets = <&rst 30>;
|
||||
reset-names = "stmmaceth";
|
||||
snps,multicast-filter-bins = <0>;
|
||||
@@ -91,7 +93,6 @@ examples:
|
||||
snps,mtl-rx-config = <&gmac0_mtl_rx_setup>;
|
||||
snps,mtl-tx-config = <&gmac0_mtl_tx_setup>;
|
||||
snps,axi-config = <&gmac0_stmmac_axi_setup>;
|
||||
status = "disabled";
|
||||
|
||||
gmac0_mtl_rx_setup: rx-queues-config {
|
||||
snps,rx-queues-to-use = <8>;
|
||||
|
||||
@@ -41,6 +41,10 @@ properties:
|
||||
description: This pin is connected to the chip's RESET pin.
|
||||
maxItems: 1
|
||||
|
||||
port:
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/fsl,mxs-audio-sgtl5000.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Freescale MXS audio complex with SGTL5000 codec
|
||||
|
||||
maintainers:
|
||||
- Frank Li <Frank.Li@nxp.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- bluegiga,apx4devkit-sgtl5000
|
||||
- denx,m28evk-sgtl5000
|
||||
- fsl,imx28-evk-sgtl5000
|
||||
- fsl,imx28-mbmx28lc-sgtl5000
|
||||
- fsl,imx28-tx28-sgtl5000
|
||||
- const: fsl,mxs-audio-sgtl5000
|
||||
|
||||
model:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description: The user-visible name of this sound complex
|
||||
|
||||
saif-controllers:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
description: The phandle list of the MXS SAIF controller
|
||||
|
||||
audio-codec:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description: The phandle of the SGTL5000 audio codec
|
||||
|
||||
audio-routing:
|
||||
$ref: /schemas/types.yaml#/definitions/non-unique-string-array
|
||||
description: |
|
||||
A list of the connections between audio components.
|
||||
Each entry is a pair of strings, the first being the
|
||||
connection's sink, the second being the connection's
|
||||
source. Valid names could be power supplies, SGTL5000
|
||||
pins, and the jacks on the board:
|
||||
|
||||
Power supplies:
|
||||
* Mic Bias
|
||||
|
||||
SGTL5000 pins:
|
||||
* MIC_IN
|
||||
* LINE_IN
|
||||
* HP_OUT
|
||||
* LINE_OUT
|
||||
|
||||
Board connectors:
|
||||
* Mic Jack
|
||||
* Line In Jack
|
||||
* Headphone Jack
|
||||
* Line Out Jack
|
||||
* Ext Spk
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- saif-controllers
|
||||
- audio-codec
|
||||
|
||||
allOf:
|
||||
- $ref: dai-common.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
sound {
|
||||
compatible = "fsl,imx28-evk-sgtl5000", "fsl,mxs-audio-sgtl5000";
|
||||
model = "imx28-evk-sgtl5000";
|
||||
saif-controllers = <&saif0 &saif1>;
|
||||
audio-codec = <&sgtl5000>;
|
||||
audio-routing =
|
||||
"MIC_IN", "Mic Jack",
|
||||
"Mic Jack", "Mic Bias",
|
||||
"Headphone Jack", "HP_OUT";
|
||||
};
|
||||
@@ -0,0 +1,98 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/mediatek,mt8173-afe-pcm.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Mediatek AFE PCM controller for MT8173
|
||||
|
||||
maintainers:
|
||||
- Trevor Wu <trevor.wu@mediatek.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: mediatek,mt8173-afe-pcm
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: audio infra sys clock
|
||||
- description: audio top mux
|
||||
- description: audio intbus mux
|
||||
- description: apll1 clock
|
||||
- description: apll2 clock
|
||||
- description: i2s0 mclk mux
|
||||
- description: i2s1 mclk mux
|
||||
- description: i2s2 mclk mux
|
||||
- description: i2s3 mclk mux
|
||||
- description: i2s3 bclk mux
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: infra_sys_audio_clk
|
||||
- const: top_pdn_audio
|
||||
- const: top_pdn_aud_intbus
|
||||
- const: bck0
|
||||
- const: bck1
|
||||
- const: i2s0_m
|
||||
- const: i2s1_m
|
||||
- const: i2s2_m
|
||||
- const: i2s3_m
|
||||
- const: i2s3_b
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
memory-region:
|
||||
description: memory region for audio DMA buffers
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- power-domains
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/mt8173-clk.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/power/mt8173-power.h>
|
||||
|
||||
mt8173-afe-pcm@11220000 {
|
||||
compatible = "mediatek,mt8173-afe-pcm";
|
||||
reg = <0x11220000 0x1000>;
|
||||
interrupts = <GIC_SPI 134 IRQ_TYPE_EDGE_FALLING>;
|
||||
power-domains = <&spm MT8173_POWER_DOMAIN_AUDIO>;
|
||||
clocks = <&infracfg CLK_INFRA_AUDIO>,
|
||||
<&topckgen CLK_TOP_AUDIO_SEL>,
|
||||
<&topckgen CLK_TOP_AUD_INTBUS_SEL>,
|
||||
<&topckgen CLK_TOP_APLL1_DIV0>,
|
||||
<&topckgen CLK_TOP_APLL2_DIV0>,
|
||||
<&topckgen CLK_TOP_I2S0_M_SEL>,
|
||||
<&topckgen CLK_TOP_I2S1_M_SEL>,
|
||||
<&topckgen CLK_TOP_I2S2_M_SEL>,
|
||||
<&topckgen CLK_TOP_I2S3_M_SEL>,
|
||||
<&topckgen CLK_TOP_I2S3_B_SEL>;
|
||||
clock-names = "infra_sys_audio_clk",
|
||||
"top_pdn_audio",
|
||||
"top_pdn_aud_intbus",
|
||||
"bck0",
|
||||
"bck1",
|
||||
"i2s0_m",
|
||||
"i2s1_m",
|
||||
"i2s2_m",
|
||||
"i2s3_m",
|
||||
"i2s3_b";
|
||||
memory-region = <&afe_dma_mem>;
|
||||
};
|
||||
@@ -25,6 +25,10 @@ properties:
|
||||
reset-names:
|
||||
const: audiosys
|
||||
|
||||
memory-region:
|
||||
description: memory region for audio DMA buffers
|
||||
maxItems: 1
|
||||
|
||||
mediatek,apmixedsys:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description: The phandle of the mediatek apmixedsys controller
|
||||
@@ -170,6 +174,7 @@ examples:
|
||||
"top_apll12_div_tdm",
|
||||
"top_mux_audio_h",
|
||||
"top_clk26m_clk";
|
||||
memory-region = <&afe_dma_mem>;
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
@@ -23,6 +23,10 @@ properties:
|
||||
reset-names:
|
||||
const: audiosys
|
||||
|
||||
memory-region:
|
||||
description: memory region for audio DMA buffers
|
||||
maxItems: 1
|
||||
|
||||
mediatek,apmixedsys:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description: The phandle of the mediatek apmixedsys controller
|
||||
@@ -95,6 +99,7 @@ examples:
|
||||
"aud_dac_predis_clk",
|
||||
"aud_infra_clk",
|
||||
"aud_infra_26m_clk";
|
||||
memory-region = <&afe_dma_mem>;
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
Mediatek AFE PCM controller
|
||||
|
||||
Required properties:
|
||||
- compatible = "mediatek,mt8173-afe-pcm";
|
||||
- reg: register location and size
|
||||
- interrupts: Should contain AFE interrupt
|
||||
- clock-names: should have these clock names:
|
||||
"infra_sys_audio_clk",
|
||||
"top_pdn_audio",
|
||||
"top_pdn_aud_intbus",
|
||||
"bck0",
|
||||
"bck1",
|
||||
"i2s0_m",
|
||||
"i2s1_m",
|
||||
"i2s2_m",
|
||||
"i2s3_m",
|
||||
"i2s3_b";
|
||||
|
||||
Example:
|
||||
|
||||
afe: mt8173-afe-pcm@11220000 {
|
||||
compatible = "mediatek,mt8173-afe-pcm";
|
||||
reg = <0 0x11220000 0 0x1000>;
|
||||
interrupts = <GIC_SPI 134 IRQ_TYPE_EDGE_FALLING>;
|
||||
clocks = <&infracfg INFRA_AUDIO>,
|
||||
<&topckgen TOP_AUDIO_SEL>,
|
||||
<&topckgen TOP_AUD_INTBUS_SEL>,
|
||||
<&topckgen TOP_APLL1_DIV0>,
|
||||
<&topckgen TOP_APLL2_DIV0>,
|
||||
<&topckgen TOP_I2S0_M_CK_SEL>,
|
||||
<&topckgen TOP_I2S1_M_CK_SEL>,
|
||||
<&topckgen TOP_I2S2_M_CK_SEL>,
|
||||
<&topckgen TOP_I2S3_M_CK_SEL>,
|
||||
<&topckgen TOP_I2S3_B_CK_SEL>;
|
||||
clock-names = "infra_sys_audio_clk",
|
||||
"top_pdn_audio",
|
||||
"top_pdn_aud_intbus",
|
||||
"bck0",
|
||||
"bck1",
|
||||
"i2s0_m",
|
||||
"i2s1_m",
|
||||
"i2s2_m",
|
||||
"i2s3_m",
|
||||
"i2s3_b";
|
||||
};
|
||||
@@ -1,42 +0,0 @@
|
||||
* Freescale MXS audio complex with SGTL5000 codec
|
||||
|
||||
Required properties:
|
||||
- compatible : "fsl,mxs-audio-sgtl5000"
|
||||
- model : The user-visible name of this sound complex
|
||||
- saif-controllers : The phandle list of the MXS SAIF controller
|
||||
- audio-codec : The phandle of the SGTL5000 audio codec
|
||||
- audio-routing : A list of the connections between audio components.
|
||||
Each entry is a pair of strings, the first being the
|
||||
connection's sink, the second being the connection's
|
||||
source. Valid names could be power supplies, SGTL5000
|
||||
pins, and the jacks on the board:
|
||||
|
||||
Power supplies:
|
||||
* Mic Bias
|
||||
|
||||
SGTL5000 pins:
|
||||
* MIC_IN
|
||||
* LINE_IN
|
||||
* HP_OUT
|
||||
* LINE_OUT
|
||||
|
||||
Board connectors:
|
||||
* Mic Jack
|
||||
* Line In Jack
|
||||
* Headphone Jack
|
||||
* Line Out Jack
|
||||
* Ext Spk
|
||||
|
||||
Example:
|
||||
|
||||
sound {
|
||||
compatible = "fsl,imx28-evk-sgtl5000",
|
||||
"fsl,mxs-audio-sgtl5000";
|
||||
model = "imx28-evk-sgtl5000";
|
||||
saif-controllers = <&saif0 &saif1>;
|
||||
audio-codec = <&sgtl5000>;
|
||||
audio-routing =
|
||||
"MIC_IN", "Mic Jack",
|
||||
"Mic Jack", "Mic Bias",
|
||||
"Headphone Jack", "HP_OUT";
|
||||
};
|
||||
@@ -40,7 +40,11 @@ properties:
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
items:
|
||||
- const: mclk
|
||||
- const: macro
|
||||
- const: dcodec
|
||||
- const: npl
|
||||
|
||||
clock-output-names:
|
||||
maxItems: 1
|
||||
@@ -80,8 +84,7 @@ allOf:
|
||||
clocks:
|
||||
maxItems: 1
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
maxItems: 1
|
||||
|
||||
- if:
|
||||
properties:
|
||||
@@ -94,10 +97,8 @@ allOf:
|
||||
minItems: 3
|
||||
maxItems: 3
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
- const: macro
|
||||
- const: dcodec
|
||||
minItems: 3
|
||||
maxItems: 3
|
||||
|
||||
- if:
|
||||
properties:
|
||||
@@ -112,11 +113,8 @@ allOf:
|
||||
minItems: 4
|
||||
maxItems: 4
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
- const: macro
|
||||
- const: dcodec
|
||||
- const: npl
|
||||
minItems: 4
|
||||
maxItems: 4
|
||||
|
||||
- if:
|
||||
properties:
|
||||
@@ -130,10 +128,8 @@ allOf:
|
||||
minItems: 3
|
||||
maxItems: 3
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
- const: macro
|
||||
- const: dcodec
|
||||
minItems: 3
|
||||
maxItems: 3
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
|
||||
@@ -29,6 +29,12 @@ properties:
|
||||
unevaluatedProperties: false
|
||||
description: Qualcomm DSP audio ports
|
||||
|
||||
usbd:
|
||||
type: object
|
||||
$ref: /schemas/sound/qcom,q6usb.yaml#
|
||||
unevaluatedProperties: false
|
||||
description: Qualcomm DSP USB audio ports
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- dais
|
||||
@@ -64,5 +70,12 @@ examples:
|
||||
qcom,sd-lines = <0 1 2 3>;
|
||||
};
|
||||
};
|
||||
|
||||
usbd {
|
||||
compatible = "qcom,q6usb";
|
||||
#sound-dai-cells = <1>;
|
||||
iommus = <&apps_smmu 0x180f 0x0>;
|
||||
qcom,usb-audio-intr-idx = /bits/ 16 <2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -28,10 +28,12 @@ properties:
|
||||
- qcom,sm8750-sndcard
|
||||
- const: qcom,sm8450-sndcard
|
||||
- enum:
|
||||
- fairphone,fp4-sndcard
|
||||
- fairphone,fp5-sndcard
|
||||
- qcom,apq8096-sndcard
|
||||
- qcom,qcm6490-idp-sndcard
|
||||
- qcom,qcs6490-rb3gen2-sndcard
|
||||
- qcom,qcs8275-sndcard
|
||||
- qcom,qcs9075-sndcard
|
||||
- qcom,qcs9100-sndcard
|
||||
- qcom,qrb4210-rb2-sndcard
|
||||
|
||||
@@ -45,6 +45,9 @@ properties:
|
||||
purpose of handling altmode muxing and orientation switching to detect and
|
||||
enable Audio Accessory Mode.
|
||||
|
||||
vdd-px-supply:
|
||||
description: A reference to the 1.2V PX supply
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
$id: http://devicetree.org/schemas/sound/richtek,rt9123.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Richtek RT9123 Audio Amplifier
|
||||
title: Richtek RT9123/RTQ9124 Audio Amplifier
|
||||
|
||||
maintainers:
|
||||
- ChiYuan Huang <cy_huang@richtek.com>
|
||||
@@ -15,6 +15,12 @@ description:
|
||||
support various formats, including I2S, left-justified, right-justified, and
|
||||
TDM formats.
|
||||
|
||||
RTQ9124 is an ultra-low output noise, digital input, mono-channel Class-D
|
||||
power amplifier that supports a 2.1MHz switching frequency. It integrates
|
||||
both DC and AC load diagnostics, as well as real-time load monitoring to
|
||||
assess speaker condition. The device operates from 4.5V to 18V and delivers
|
||||
up to 30W output power.
|
||||
|
||||
allOf:
|
||||
- $ref: dai-common.yaml#
|
||||
|
||||
@@ -22,6 +28,7 @@ properties:
|
||||
compatible:
|
||||
enum:
|
||||
- richtek,rt9123
|
||||
- richtek,rtq9124
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
@@ -18,6 +18,7 @@ properties:
|
||||
- ti,tas5719
|
||||
- ti,tas5721
|
||||
- ti,tas5733
|
||||
- ti,tas5753
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@@ -98,6 +99,7 @@ allOf:
|
||||
contains:
|
||||
enum:
|
||||
- ti,tas5721
|
||||
- ti,tas5753
|
||||
then:
|
||||
properties:
|
||||
HPVDD-supply: false
|
||||
|
||||
@@ -16,11 +16,13 @@ User interface
|
||||
Creating a TLS connection
|
||||
-------------------------
|
||||
|
||||
First create a new TCP socket and set the TLS ULP.
|
||||
First create a new TCP socket and once the connection is established set the
|
||||
TLS ULP.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
connect(sock, addr, addrlen);
|
||||
setsockopt(sock, SOL_TCP, TCP_ULP, "tls", sizeof("tls"));
|
||||
|
||||
Setting the TLS ULP allows us to set/get TLS socket options. Currently
|
||||
|
||||
@@ -312,7 +312,7 @@ Posting as one thread is discouraged because it confuses patchwork
|
||||
(as of patchwork 2.2.2).
|
||||
|
||||
Co-posting selftests
|
||||
--------------------
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Selftests should be part of the same series as the code changes.
|
||||
Specifically for fixes both code change and related test should go into
|
||||
|
||||
@@ -7196,6 +7196,10 @@ The valid value for 'flags' is:
|
||||
u64 leaf;
|
||||
u64 r11, r12, r13, r14;
|
||||
} get_tdvmcall_info;
|
||||
struct {
|
||||
u64 ret;
|
||||
u64 vector;
|
||||
} setup_event_notify;
|
||||
};
|
||||
} tdx;
|
||||
|
||||
@@ -7210,21 +7214,24 @@ number from register R11. The remaining field of the union provide the
|
||||
inputs and outputs of the TDVMCALL. Currently the following values of
|
||||
``nr`` are defined:
|
||||
|
||||
* ``TDVMCALL_GET_QUOTE``: the guest has requested to generate a TD-Quote
|
||||
signed by a service hosting TD-Quoting Enclave operating on the host.
|
||||
Parameters and return value are in the ``get_quote`` field of the union.
|
||||
The ``gpa`` field and ``size`` specify the guest physical address
|
||||
(without the shared bit set) and the size of a shared-memory buffer, in
|
||||
which the TDX guest passes a TD Report. The ``ret`` field represents
|
||||
the return value of the GetQuote request. When the request has been
|
||||
queued successfully, the TDX guest can poll the status field in the
|
||||
shared-memory area to check whether the Quote generation is completed or
|
||||
not. When completed, the generated Quote is returned via the same buffer.
|
||||
* ``TDVMCALL_GET_QUOTE``: the guest has requested to generate a TD-Quote
|
||||
signed by a service hosting TD-Quoting Enclave operating on the host.
|
||||
Parameters and return value are in the ``get_quote`` field of the union.
|
||||
The ``gpa`` field and ``size`` specify the guest physical address
|
||||
(without the shared bit set) and the size of a shared-memory buffer, in
|
||||
which the TDX guest passes a TD Report. The ``ret`` field represents
|
||||
the return value of the GetQuote request. When the request has been
|
||||
queued successfully, the TDX guest can poll the status field in the
|
||||
shared-memory area to check whether the Quote generation is completed or
|
||||
not. When completed, the generated Quote is returned via the same buffer.
|
||||
|
||||
* ``TDVMCALL_GET_TD_VM_CALL_INFO``: the guest has requested the support
|
||||
status of TDVMCALLs. The output values for the given leaf should be
|
||||
placed in fields from ``r11`` to ``r14`` of the ``get_tdvmcall_info``
|
||||
field of the union.
|
||||
* ``TDVMCALL_GET_TD_VM_CALL_INFO``: the guest has requested the support
|
||||
status of TDVMCALLs. The output values for the given leaf should be
|
||||
placed in fields from ``r11`` to ``r14`` of the ``get_tdvmcall_info``
|
||||
field of the union.
|
||||
|
||||
* ``TDVMCALL_SETUP_EVENT_NOTIFY_INTERRUPT``: the guest has requested to
|
||||
set up a notification interrupt for vector ``vector``.
|
||||
|
||||
KVM may add support for more values in the future that may cause a userspace
|
||||
exit, even without calls to ``KVM_ENABLE_CAP`` or similar. In this case,
|
||||
|
||||
@@ -79,7 +79,20 @@ to be configured to the TDX guest.
|
||||
struct kvm_tdx_capabilities {
|
||||
__u64 supported_attrs;
|
||||
__u64 supported_xfam;
|
||||
__u64 reserved[254];
|
||||
|
||||
/* TDG.VP.VMCALL hypercalls executed in kernel and forwarded to
|
||||
* userspace, respectively
|
||||
*/
|
||||
__u64 kernel_tdvmcallinfo_1_r11;
|
||||
__u64 user_tdvmcallinfo_1_r11;
|
||||
|
||||
/* TDG.VP.VMCALL instruction executions subfunctions executed in kernel
|
||||
* and forwarded to userspace, respectively
|
||||
*/
|
||||
__u64 kernel_tdvmcallinfo_1_r12;
|
||||
__u64 user_tdvmcallinfo_1_r12;
|
||||
|
||||
__u64 reserved[250];
|
||||
|
||||
/* Configurable CPUID bits for userspace */
|
||||
struct kvm_cpuid2 cpuid;
|
||||
|
||||
@@ -36,7 +36,7 @@ Offset Size (in bytes) Content
|
||||
|
||||
The WMI object flags control whether the method or notification ID is used:
|
||||
|
||||
- 0x1: Data block usage is expensive and must be explicitly enabled/disabled.
|
||||
- 0x1: Data block is expensive to collect.
|
||||
- 0x2: Data block contains WMI methods.
|
||||
- 0x4: Data block contains ASCIZ string.
|
||||
- 0x8: Data block describes a WMI event, use notification ID instead
|
||||
@@ -83,14 +83,18 @@ event as hexadecimal value. Their first parameter is an integer with a value
|
||||
of 0 if the WMI event should be disabled, other values will enable
|
||||
the WMI event.
|
||||
|
||||
Those ACPI methods are always called even for WMI events not registered as
|
||||
being expensive to collect to match the behavior of the Windows driver.
|
||||
|
||||
WCxx ACPI methods
|
||||
-----------------
|
||||
Similar to the ``WExx`` ACPI methods, except that it controls data collection
|
||||
instead of events and thus the last two characters of the ACPI method name are
|
||||
the method ID of the data block to enable/disable.
|
||||
Similar to the ``WExx`` ACPI methods, except that instead of WMI events it controls
|
||||
data collection of data blocks registered as being expensive to collect. Thus the
|
||||
last two characters of the ACPI method name are the method ID of the data block
|
||||
to enable/disable.
|
||||
|
||||
Those ACPI methods are also called before setting data blocks to match the
|
||||
behaviour of the Windows driver.
|
||||
behavior of the Windows driver.
|
||||
|
||||
_WED ACPI method
|
||||
----------------
|
||||
|
||||
43
MAINTAINERS
43
MAINTAINERS
@@ -4181,6 +4181,7 @@ F: include/linux/cpumask_types.h
|
||||
F: include/linux/find.h
|
||||
F: include/linux/nodemask.h
|
||||
F: include/linux/nodemask_types.h
|
||||
F: include/uapi/linux/bits.h
|
||||
F: include/vdso/bits.h
|
||||
F: lib/bitmap-str.c
|
||||
F: lib/bitmap.c
|
||||
@@ -4193,6 +4194,7 @@ F: tools/include/linux/bitfield.h
|
||||
F: tools/include/linux/bitmap.h
|
||||
F: tools/include/linux/bits.h
|
||||
F: tools/include/linux/find.h
|
||||
F: tools/include/uapi/linux/bits.h
|
||||
F: tools/include/vdso/bits.h
|
||||
F: tools/lib/bitmap.c
|
||||
F: tools/lib/find_bit.c
|
||||
@@ -10504,7 +10506,7 @@ S: Maintained
|
||||
F: block/partitions/efi.*
|
||||
|
||||
HABANALABS PCI DRIVER
|
||||
M: Ofir Bitton <obitton@habana.ai>
|
||||
M: Yaron Avizrat <yaron.avizrat@intel.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
S: Supported
|
||||
C: irc://irc.oftc.net/dri-devel
|
||||
@@ -15550,6 +15552,7 @@ F: drivers/net/ethernet/mellanox/mlx4/en_*
|
||||
MELLANOX ETHERNET DRIVER (mlx5e)
|
||||
M: Saeed Mahameed <saeedm@nvidia.com>
|
||||
M: Tariq Toukan <tariqt@nvidia.com>
|
||||
M: Mark Bloch <mbloch@nvidia.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://www.nvidia.com/networking/
|
||||
@@ -15619,6 +15622,7 @@ MELLANOX MLX5 core VPI driver
|
||||
M: Saeed Mahameed <saeedm@nvidia.com>
|
||||
M: Leon Romanovsky <leonro@nvidia.com>
|
||||
M: Tariq Toukan <tariqt@nvidia.com>
|
||||
M: Mark Bloch <mbloch@nvidia.com>
|
||||
L: netdev@vger.kernel.org
|
||||
L: linux-rdma@vger.kernel.org
|
||||
S: Maintained
|
||||
@@ -16820,8 +16824,8 @@ F: include/dt-bindings/clock/mobileye,eyeq5-clk.h
|
||||
MODULE SUPPORT
|
||||
M: Luis Chamberlain <mcgrof@kernel.org>
|
||||
M: Petr Pavlu <petr.pavlu@suse.com>
|
||||
M: Daniel Gomez <da.gomez@kernel.org>
|
||||
R: Sami Tolvanen <samitolvanen@google.com>
|
||||
R: Daniel Gomez <da.gomez@samsung.com>
|
||||
L: linux-modules@vger.kernel.org
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Maintained
|
||||
@@ -17220,10 +17224,10 @@ F: drivers/rtc/rtc-ntxec.c
|
||||
F: include/linux/mfd/ntxec.h
|
||||
|
||||
NETRONOME ETHERNET DRIVERS
|
||||
M: Louis Peens <louis.peens@corigine.com>
|
||||
R: Jakub Kicinski <kuba@kernel.org>
|
||||
R: Simon Horman <horms@kernel.org>
|
||||
L: oss-drivers@corigine.com
|
||||
S: Maintained
|
||||
S: Odd Fixes
|
||||
F: drivers/net/ethernet/netronome/
|
||||
|
||||
NETWORK BLOCK DEVICE (NBD)
|
||||
@@ -19599,8 +19603,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git
|
||||
F: drivers/pinctrl/intel/
|
||||
|
||||
PIN CONTROLLER - KEEMBAY
|
||||
M: Lakshmi Sowjanya D <lakshmi.sowjanya.d@intel.com>
|
||||
S: Supported
|
||||
S: Orphan
|
||||
F: drivers/pinctrl/pinctrl-keembay*
|
||||
|
||||
PIN CONTROLLER - MEDIATEK
|
||||
@@ -21192,7 +21195,7 @@ M: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
|
||||
L: netdev@vger.kernel.org
|
||||
L: linux-renesas-soc@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/renesas,r9a09g057-gbeth.yaml
|
||||
F: Documentation/devicetree/bindings/net/renesas,rzv2h-gbeth.yaml
|
||||
F: drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c
|
||||
|
||||
RENESAS RZ/V2H(P) USB2PHY PORT RESET DRIVER
|
||||
@@ -22328,6 +22331,17 @@ M: Jim Cromie <jim.cromie@gmail.com>
|
||||
S: Maintained
|
||||
F: drivers/clocksource/scx200_hrt.c
|
||||
|
||||
SDCA LIBRARY AND CLASS DRIVER
|
||||
M: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
M: Maciej Strozek <mstrozek@opensource.cirrus.com>
|
||||
R: Bard Liao <yung-chuan.liao@linux.intel.com>
|
||||
R: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
|
||||
L: linux-sound@vger.kernel.org
|
||||
L: patches@opensource.cirrus.com
|
||||
S: Maintained
|
||||
F: include/sound/sdca*
|
||||
F: sound/soc/sdca/*
|
||||
|
||||
SDRICOH_CS MMC/SD HOST CONTROLLER INTERFACE DRIVER
|
||||
M: Sascha Sommer <saschasommer@freenet.de>
|
||||
L: sdricohcs-devel@lists.sourceforge.net (subscribers-only)
|
||||
@@ -22580,9 +22594,11 @@ S: Maintained
|
||||
F: drivers/misc/sgi-xp/
|
||||
|
||||
SHARED MEMORY COMMUNICATIONS (SMC) SOCKETS
|
||||
M: D. Wythe <alibuda@linux.alibaba.com>
|
||||
M: Dust Li <dust.li@linux.alibaba.com>
|
||||
M: Sidraya Jayagond <sidraya@linux.ibm.com>
|
||||
M: Wenjia Zhang <wenjia@linux.ibm.com>
|
||||
M: Jan Karcher <jaka@linux.ibm.com>
|
||||
R: D. Wythe <alibuda@linux.alibaba.com>
|
||||
R: Mahanta Jambigi <mjambigi@linux.ibm.com>
|
||||
R: Tony Lu <tonylu@linux.alibaba.com>
|
||||
R: Wen Gu <guwen@linux.alibaba.com>
|
||||
L: linux-rdma@vger.kernel.org
|
||||
@@ -26934,7 +26950,7 @@ F: arch/x86/kernel/stacktrace.c
|
||||
F: arch/x86/kernel/unwind_*.c
|
||||
|
||||
X86 TRUST DOMAIN EXTENSIONS (TDX)
|
||||
M: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
|
||||
M: Kirill A. Shutemov <kas@kernel.org>
|
||||
R: Dave Hansen <dave.hansen@linux.intel.com>
|
||||
L: x86@kernel.org
|
||||
L: linux-coco@lists.linux.dev
|
||||
@@ -27303,13 +27319,6 @@ S: Supported
|
||||
W: http://www.marvell.com
|
||||
F: drivers/i2c/busses/i2c-xlp9xx.c
|
||||
|
||||
XRA1403 GPIO EXPANDER
|
||||
M: Nandor Han <nandor.han@ge.com>
|
||||
L: linux-gpio@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/gpio/gpio-xra1403.txt
|
||||
F: drivers/gpio/gpio-xra1403.c
|
||||
|
||||
XTENSA XTFPGA PLATFORM SUPPORT
|
||||
M: Max Filippov <jcmvbkbc@gmail.com>
|
||||
S: Maintained
|
||||
|
||||
2
Makefile
2
Makefile
@@ -2,7 +2,7 @@
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 16
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc4
|
||||
EXTRAVERSION = -rc6
|
||||
NAME = Baby Opossum Posse
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
||||
@@ -256,6 +256,7 @@ config ARM64
|
||||
select HOTPLUG_SMT if HOTPLUG_CPU
|
||||
select IRQ_DOMAIN
|
||||
select IRQ_FORCED_THREADING
|
||||
select JUMP_LABEL
|
||||
select KASAN_VMALLOC if KASAN
|
||||
select LOCK_MM_AND_FIND_VMA
|
||||
select MODULES_USE_ELF_RELA
|
||||
|
||||
@@ -20,8 +20,6 @@ flash@0 {
|
||||
compatible = "jedec,spi-nor";
|
||||
reg = <0x0>;
|
||||
spi-max-frequency = <25000000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
|
||||
@@ -100,6 +100,8 @@ dfr_mipi_out_panel: endpoint@0 {
|
||||
|
||||
&displaydfr_mipi {
|
||||
status = "okay";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
dfr_panel: panel@0 {
|
||||
compatible = "apple,j293-summit", "apple,summit";
|
||||
|
||||
@@ -71,7 +71,7 @@ hpm1: usb-pd@3f {
|
||||
*/
|
||||
&port00 {
|
||||
bus-range = <1 1>;
|
||||
wifi0: network@0,0 {
|
||||
wifi0: wifi@0,0 {
|
||||
compatible = "pci14e4,4425";
|
||||
reg = <0x10000 0x0 0x0 0x0 0x0>;
|
||||
/* To be filled by the loader */
|
||||
|
||||
@@ -405,8 +405,6 @@ displaydfr_mipi: dsi@228600000 {
|
||||
compatible = "apple,t8103-display-pipe-mipi", "apple,h7-display-pipe-mipi";
|
||||
reg = <0x2 0x28600000 0x0 0x100000>;
|
||||
power-domains = <&ps_mipi_dsi>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
|
||||
ports {
|
||||
|
||||
@@ -63,6 +63,8 @@ dfr_mipi_out_panel: endpoint@0 {
|
||||
|
||||
&displaydfr_mipi {
|
||||
status = "okay";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
dfr_panel: panel@0 {
|
||||
compatible = "apple,j493-summit", "apple,summit";
|
||||
|
||||
@@ -420,8 +420,6 @@ displaydfr_mipi: dsi@228600000 {
|
||||
compatible = "apple,t8112-display-pipe-mipi", "apple,h7-display-pipe-mipi";
|
||||
reg = <0x2 0x28600000 0x0 0x100000>;
|
||||
power-domains = <&ps_mipi_dsi>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
|
||||
ports {
|
||||
|
||||
@@ -1573,6 +1573,7 @@ CONFIG_RESET_QCOM_AOSS=y
|
||||
CONFIG_RESET_QCOM_PDC=m
|
||||
CONFIG_RESET_RZG2L_USBPHY_CTRL=y
|
||||
CONFIG_RESET_TI_SCI=y
|
||||
CONFIG_PHY_SNPS_EUSB2=m
|
||||
CONFIG_PHY_XGENE=y
|
||||
CONFIG_PHY_CAN_TRANSCEIVER=m
|
||||
CONFIG_PHY_NXP_PTN3222=m
|
||||
@@ -1597,7 +1598,6 @@ CONFIG_PHY_QCOM_EDP=m
|
||||
CONFIG_PHY_QCOM_PCIE2=m
|
||||
CONFIG_PHY_QCOM_QMP=m
|
||||
CONFIG_PHY_QCOM_QUSB2=m
|
||||
CONFIG_PHY_QCOM_SNPS_EUSB2=m
|
||||
CONFIG_PHY_QCOM_EUSB2_REPEATER=m
|
||||
CONFIG_PHY_QCOM_M31_USB=m
|
||||
CONFIG_PHY_QCOM_USB_HS=m
|
||||
|
||||
@@ -287,17 +287,6 @@
|
||||
.Lskip_fgt2_\@:
|
||||
.endm
|
||||
|
||||
.macro __init_el2_gcs
|
||||
mrs_s x1, SYS_ID_AA64PFR1_EL1
|
||||
ubfx x1, x1, #ID_AA64PFR1_EL1_GCS_SHIFT, #4
|
||||
cbz x1, .Lskip_gcs_\@
|
||||
|
||||
/* Ensure GCS is not enabled when we start trying to do BLs */
|
||||
msr_s SYS_GCSCR_EL1, xzr
|
||||
msr_s SYS_GCSCRE0_EL1, xzr
|
||||
.Lskip_gcs_\@:
|
||||
.endm
|
||||
|
||||
/**
|
||||
* Initialize EL2 registers to sane values. This should be called early on all
|
||||
* cores that were booted in EL2. Note that everything gets initialised as
|
||||
@@ -319,7 +308,6 @@
|
||||
__init_el2_cptr
|
||||
__init_el2_fgt
|
||||
__init_el2_fgt2
|
||||
__init_el2_gcs
|
||||
.endm
|
||||
|
||||
#ifndef __KVM_NVHE_HYPERVISOR__
|
||||
@@ -371,6 +359,13 @@
|
||||
msr_s SYS_MPAMHCR_EL2, xzr // clear TRAP_MPAMIDR_EL1 -> EL2
|
||||
|
||||
.Lskip_mpam_\@:
|
||||
check_override id_aa64pfr1, ID_AA64PFR1_EL1_GCS_SHIFT, .Linit_gcs_\@, .Lskip_gcs_\@, x1, x2
|
||||
|
||||
.Linit_gcs_\@:
|
||||
msr_s SYS_GCSCR_EL1, xzr
|
||||
msr_s SYS_GCSCRE0_EL1, xzr
|
||||
|
||||
.Lskip_gcs_\@:
|
||||
check_override id_aa64pfr0, ID_AA64PFR0_EL1_SVE_SHIFT, .Linit_sve_\@, .Lskip_sve_\@, x1, x2
|
||||
|
||||
.Linit_sve_\@: /* SVE register access */
|
||||
|
||||
@@ -1480,7 +1480,6 @@ int kvm_vm_ioctl_get_reg_writable_masks(struct kvm *kvm,
|
||||
struct reg_mask_range *range);
|
||||
|
||||
/* Guest/host FPSIMD coordination helpers */
|
||||
int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu);
|
||||
void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu);
|
||||
void kvm_arch_vcpu_ctxflush_fp(struct kvm_vcpu *vcpu);
|
||||
void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu);
|
||||
|
||||
@@ -34,7 +34,7 @@ obj-y := debug-monitors.o entry.o irq.o fpsimd.o \
|
||||
cpufeature.o alternative.o cacheinfo.o \
|
||||
smp.o smp_spin_table.o topology.o smccc-call.o \
|
||||
syscall.o proton-pack.o idle.o patching.o pi/ \
|
||||
rsi.o
|
||||
rsi.o jump_label.o
|
||||
|
||||
obj-$(CONFIG_COMPAT) += sys32.o signal32.o \
|
||||
sys_compat.o
|
||||
@@ -47,7 +47,6 @@ obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o
|
||||
obj-$(CONFIG_HARDLOCKUP_DETECTOR_PERF) += watchdog_hld.o
|
||||
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
|
||||
obj-$(CONFIG_CPU_PM) += sleep.o suspend.o
|
||||
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
|
||||
obj-$(CONFIG_KGDB) += kgdb.o
|
||||
obj-$(CONFIG_EFI) += efi.o efi-rt-wrapper.o
|
||||
obj-$(CONFIG_PCI) += pci.o
|
||||
|
||||
@@ -3135,6 +3135,13 @@ static bool has_sve_feature(const struct arm64_cpu_capabilities *cap, int scope)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARM64_SME
|
||||
static bool has_sme_feature(const struct arm64_cpu_capabilities *cap, int scope)
|
||||
{
|
||||
return system_supports_sme() && has_user_cpuid_feature(cap, scope);
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
|
||||
HWCAP_CAP(ID_AA64ISAR0_EL1, AES, PMULL, CAP_HWCAP, KERNEL_HWCAP_PMULL),
|
||||
HWCAP_CAP(ID_AA64ISAR0_EL1, AES, AES, CAP_HWCAP, KERNEL_HWCAP_AES),
|
||||
@@ -3223,31 +3230,31 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
|
||||
HWCAP_CAP(ID_AA64ISAR2_EL1, BC, IMP, CAP_HWCAP, KERNEL_HWCAP_HBC),
|
||||
#ifdef CONFIG_ARM64_SME
|
||||
HWCAP_CAP(ID_AA64PFR1_EL1, SME, IMP, CAP_HWCAP, KERNEL_HWCAP_SME),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, FA64, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_FA64),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, LUTv2, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_LUTV2),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, SMEver, SME2p2, CAP_HWCAP, KERNEL_HWCAP_SME2P2),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, SMEver, SME2p1, CAP_HWCAP, KERNEL_HWCAP_SME2P1),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, SMEver, SME2, CAP_HWCAP, KERNEL_HWCAP_SME2),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, I16I64, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_I16I64),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, F64F64, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F64F64),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, I16I32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_I16I32),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, B16B16, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_B16B16),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, F16F16, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F16F16),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, F8F16, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F8F16),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, F8F32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F8F32),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, I8I32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_I8I32),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, F16F32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F16F32),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, B16F32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_B16F32),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, BI32I32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_BI32I32),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, F32F32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F32F32),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, SF8FMA, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8FMA),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, SF8DP4, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8DP4),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, SF8DP2, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8DP2),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, SBitPerm, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SBITPERM),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, AES, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_AES),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, SFEXPA, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SFEXPA),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, STMOP, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_STMOP),
|
||||
HWCAP_CAP(ID_AA64SMFR0_EL1, SMOP4, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SMOP4),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, FA64, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_FA64),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, LUTv2, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_LUTV2),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, SMEver, SME2p2, CAP_HWCAP, KERNEL_HWCAP_SME2P2),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, SMEver, SME2p1, CAP_HWCAP, KERNEL_HWCAP_SME2P1),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, SMEver, SME2, CAP_HWCAP, KERNEL_HWCAP_SME2),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, I16I64, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_I16I64),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, F64F64, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F64F64),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, I16I32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_I16I32),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, B16B16, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_B16B16),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, F16F16, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F16F16),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, F8F16, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F8F16),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, F8F32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F8F32),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, I8I32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_I8I32),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, F16F32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F16F32),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, B16F32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_B16F32),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, BI32I32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_BI32I32),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, F32F32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F32F32),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, SF8FMA, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8FMA),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, SF8DP4, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8DP4),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, SF8DP2, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8DP2),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, SBitPerm, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SBITPERM),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, AES, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_AES),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, SFEXPA, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SFEXPA),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, STMOP, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_STMOP),
|
||||
HWCAP_CAP_MATCH_ID(has_sme_feature, ID_AA64SMFR0_EL1, SMOP4, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SMOP4),
|
||||
#endif /* CONFIG_ARM64_SME */
|
||||
HWCAP_CAP(ID_AA64FPFR0_EL1, F8CVT, IMP, CAP_HWCAP, KERNEL_HWCAP_F8CVT),
|
||||
HWCAP_CAP(ID_AA64FPFR0_EL1, F8FMA, IMP, CAP_HWCAP, KERNEL_HWCAP_F8FMA),
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include <asm/efi.h>
|
||||
#include <asm/stacktrace.h>
|
||||
#include <asm/vmap_stack.h>
|
||||
|
||||
static bool region_is_misaligned(const efi_memory_desc_t *md)
|
||||
{
|
||||
@@ -214,9 +215,13 @@ static int __init arm64_efi_rt_init(void)
|
||||
if (!efi_enabled(EFI_RUNTIME_SERVICES))
|
||||
return 0;
|
||||
|
||||
p = __vmalloc_node(THREAD_SIZE, THREAD_ALIGN, GFP_KERNEL,
|
||||
NUMA_NO_NODE, &&l);
|
||||
l: if (!p) {
|
||||
if (!IS_ENABLED(CONFIG_VMAP_STACK)) {
|
||||
clear_bit(EFI_RUNTIME_SERVICES, &efi.flags);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
p = arch_alloc_vmap_stack(THREAD_SIZE, NUMA_NO_NODE);
|
||||
if (!p) {
|
||||
pr_warn("Failed to allocate EFI runtime stack\n");
|
||||
clear_bit(EFI_RUNTIME_SERVICES, &efi.flags);
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -673,6 +673,11 @@ static void permission_overlay_switch(struct task_struct *next)
|
||||
current->thread.por_el0 = read_sysreg_s(SYS_POR_EL0);
|
||||
if (current->thread.por_el0 != next->thread.por_el0) {
|
||||
write_sysreg_s(next->thread.por_el0, SYS_POR_EL0);
|
||||
/*
|
||||
* No ISB required as we can tolerate spurious Overlay faults -
|
||||
* the fault handler will check again based on the new value
|
||||
* of POR_EL0.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1143,7 +1143,7 @@ static inline unsigned int num_other_online_cpus(void)
|
||||
void smp_send_stop(void)
|
||||
{
|
||||
static unsigned long stop_in_progress;
|
||||
cpumask_t mask;
|
||||
static cpumask_t mask;
|
||||
unsigned long timeout;
|
||||
|
||||
/*
|
||||
|
||||
@@ -825,10 +825,6 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
|
||||
if (!kvm_arm_vcpu_is_finalized(vcpu))
|
||||
return -EPERM;
|
||||
|
||||
ret = kvm_arch_vcpu_run_map_fp(vcpu);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (likely(vcpu_has_run_once(vcpu)))
|
||||
return 0;
|
||||
|
||||
@@ -2129,7 +2125,7 @@ static void cpu_hyp_init(void *discard)
|
||||
|
||||
static void cpu_hyp_uninit(void *discard)
|
||||
{
|
||||
if (__this_cpu_read(kvm_hyp_initialized)) {
|
||||
if (!is_protected_kvm_enabled() && __this_cpu_read(kvm_hyp_initialized)) {
|
||||
cpu_hyp_reset();
|
||||
__this_cpu_write(kvm_hyp_initialized, 0);
|
||||
}
|
||||
@@ -2345,8 +2341,13 @@ static void __init teardown_hyp_mode(void)
|
||||
|
||||
free_hyp_pgds();
|
||||
for_each_possible_cpu(cpu) {
|
||||
if (per_cpu(kvm_hyp_initialized, cpu))
|
||||
continue;
|
||||
|
||||
free_pages(per_cpu(kvm_arm_hyp_stack_base, cpu), NVHE_STACK_SHIFT - PAGE_SHIFT);
|
||||
free_pages(kvm_nvhe_sym(kvm_arm_hyp_percpu_base)[cpu], nvhe_percpu_order());
|
||||
|
||||
if (!kvm_nvhe_sym(kvm_arm_hyp_percpu_base)[cpu])
|
||||
continue;
|
||||
|
||||
if (free_sve) {
|
||||
struct cpu_sve_state *sve_state;
|
||||
@@ -2354,6 +2355,9 @@ static void __init teardown_hyp_mode(void)
|
||||
sve_state = per_cpu_ptr_nvhe_sym(kvm_host_data, cpu)->sve_state;
|
||||
free_pages((unsigned long) sve_state, pkvm_host_sve_state_order());
|
||||
}
|
||||
|
||||
free_pages(kvm_nvhe_sym(kvm_arm_hyp_percpu_base)[cpu], nvhe_percpu_order());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,32 +14,6 @@
|
||||
#include <asm/kvm_mmu.h>
|
||||
#include <asm/sysreg.h>
|
||||
|
||||
/*
|
||||
* Called on entry to KVM_RUN unless this vcpu previously ran at least
|
||||
* once and the most recent prior KVM_RUN for this vcpu was called from
|
||||
* the same task as current (highly likely).
|
||||
*
|
||||
* This is guaranteed to execute before kvm_arch_vcpu_load_fp(vcpu),
|
||||
* such that on entering hyp the relevant parts of current are already
|
||||
* mapped.
|
||||
*/
|
||||
int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct user_fpsimd_state *fpsimd = ¤t->thread.uw.fpsimd_state;
|
||||
int ret;
|
||||
|
||||
/* pKVM has its own tracking of the host fpsimd state. */
|
||||
if (is_protected_kvm_enabled())
|
||||
return 0;
|
||||
|
||||
/* Make sure the host task fpsimd state is visible to hyp: */
|
||||
ret = kvm_share_hyp(fpsimd, fpsimd + 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare vcpu for saving the host's FPSIMD state and loading the guest's.
|
||||
* The actual loading is done by the FPSIMD access trap taken to hyp.
|
||||
|
||||
@@ -479,6 +479,7 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
|
||||
{
|
||||
struct kvm_mem_range cur;
|
||||
kvm_pte_t pte;
|
||||
u64 granule;
|
||||
s8 level;
|
||||
int ret;
|
||||
|
||||
@@ -496,18 +497,21 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
do {
|
||||
u64 granule = kvm_granule_size(level);
|
||||
for (; level <= KVM_PGTABLE_LAST_LEVEL; level++) {
|
||||
if (!kvm_level_supports_block_mapping(level))
|
||||
continue;
|
||||
granule = kvm_granule_size(level);
|
||||
cur.start = ALIGN_DOWN(addr, granule);
|
||||
cur.end = cur.start + granule;
|
||||
level++;
|
||||
} while ((level <= KVM_PGTABLE_LAST_LEVEL) &&
|
||||
!(kvm_level_supports_block_mapping(level) &&
|
||||
range_included(&cur, range)));
|
||||
if (!range_included(&cur, range))
|
||||
continue;
|
||||
*range = cur;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*range = cur;
|
||||
WARN_ON(1);
|
||||
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int host_stage2_idmap_locked(phys_addr_t addr, u64 size,
|
||||
|
||||
@@ -1402,6 +1402,21 @@ static void kvm_map_l1_vncr(struct kvm_vcpu *vcpu)
|
||||
}
|
||||
}
|
||||
|
||||
#define has_tgran_2(__r, __sz) \
|
||||
({ \
|
||||
u64 _s1, _s2, _mmfr0 = __r; \
|
||||
\
|
||||
_s2 = SYS_FIELD_GET(ID_AA64MMFR0_EL1, \
|
||||
TGRAN##__sz##_2, _mmfr0); \
|
||||
\
|
||||
_s1 = SYS_FIELD_GET(ID_AA64MMFR0_EL1, \
|
||||
TGRAN##__sz, _mmfr0); \
|
||||
\
|
||||
((_s2 != ID_AA64MMFR0_EL1_TGRAN##__sz##_2_NI && \
|
||||
_s2 != ID_AA64MMFR0_EL1_TGRAN##__sz##_2_TGRAN##__sz) || \
|
||||
(_s2 == ID_AA64MMFR0_EL1_TGRAN##__sz##_2_TGRAN##__sz && \
|
||||
_s1 != ID_AA64MMFR0_EL1_TGRAN##__sz##_NI)); \
|
||||
})
|
||||
/*
|
||||
* Our emulated CPU doesn't support all the possible features. For the
|
||||
* sake of simplicity (and probably mental sanity), wipe out a number
|
||||
@@ -1411,6 +1426,8 @@ static void kvm_map_l1_vncr(struct kvm_vcpu *vcpu)
|
||||
*/
|
||||
u64 limit_nv_id_reg(struct kvm *kvm, u32 reg, u64 val)
|
||||
{
|
||||
u64 orig_val = val;
|
||||
|
||||
switch (reg) {
|
||||
case SYS_ID_AA64ISAR0_EL1:
|
||||
/* Support everything but TME */
|
||||
@@ -1480,13 +1497,16 @@ u64 limit_nv_id_reg(struct kvm *kvm, u32 reg, u64 val)
|
||||
*/
|
||||
switch (PAGE_SIZE) {
|
||||
case SZ_4K:
|
||||
val |= SYS_FIELD_PREP_ENUM(ID_AA64MMFR0_EL1, TGRAN4_2, IMP);
|
||||
if (has_tgran_2(orig_val, 4))
|
||||
val |= SYS_FIELD_PREP_ENUM(ID_AA64MMFR0_EL1, TGRAN4_2, IMP);
|
||||
fallthrough;
|
||||
case SZ_16K:
|
||||
val |= SYS_FIELD_PREP_ENUM(ID_AA64MMFR0_EL1, TGRAN16_2, IMP);
|
||||
if (has_tgran_2(orig_val, 16))
|
||||
val |= SYS_FIELD_PREP_ENUM(ID_AA64MMFR0_EL1, TGRAN16_2, IMP);
|
||||
fallthrough;
|
||||
case SZ_64K:
|
||||
val |= SYS_FIELD_PREP_ENUM(ID_AA64MMFR0_EL1, TGRAN64_2, IMP);
|
||||
if (has_tgran_2(orig_val, 64))
|
||||
val |= SYS_FIELD_PREP_ENUM(ID_AA64MMFR0_EL1, TGRAN64_2, IMP);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -401,9 +401,7 @@ void vgic_v3_nested_update_mi(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
bool level;
|
||||
|
||||
level = __vcpu_sys_reg(vcpu, ICH_HCR_EL2) & ICH_HCR_EL2_En;
|
||||
if (level)
|
||||
level &= vgic_v3_get_misr(vcpu);
|
||||
level = (__vcpu_sys_reg(vcpu, ICH_HCR_EL2) & ICH_HCR_EL2_En) && vgic_v3_get_misr(vcpu);
|
||||
kvm_vgic_inject_irq(vcpu->kvm, vcpu,
|
||||
vcpu->kvm->arch.vgic.mi_intid, level, vcpu);
|
||||
}
|
||||
|
||||
@@ -487,17 +487,29 @@ static void do_bad_area(unsigned long far, unsigned long esr,
|
||||
}
|
||||
}
|
||||
|
||||
static bool fault_from_pkey(unsigned long esr, struct vm_area_struct *vma,
|
||||
unsigned int mm_flags)
|
||||
static bool fault_from_pkey(struct vm_area_struct *vma, unsigned int mm_flags)
|
||||
{
|
||||
unsigned long iss2 = ESR_ELx_ISS2(esr);
|
||||
|
||||
if (!system_supports_poe())
|
||||
return false;
|
||||
|
||||
if (esr_fsc_is_permission_fault(esr) && (iss2 & ESR_ELx_Overlay))
|
||||
return true;
|
||||
|
||||
/*
|
||||
* We do not check whether an Overlay fault has occurred because we
|
||||
* cannot make a decision based solely on its value:
|
||||
*
|
||||
* - If Overlay is set, a fault did occur due to POE, but it may be
|
||||
* spurious in those cases where we update POR_EL0 without ISB (e.g.
|
||||
* on context-switch). We would then need to manually check POR_EL0
|
||||
* against vma_pkey(vma), which is exactly what
|
||||
* arch_vma_access_permitted() does.
|
||||
*
|
||||
* - If Overlay is not set, we may still need to report a pkey fault.
|
||||
* This is the case if an access was made within a mapping but with no
|
||||
* page mapped, and POR_EL0 forbids the access (according to
|
||||
* vma_pkey()). Such access will result in a SIGSEGV regardless
|
||||
* because core code checks arch_vma_access_permitted(), but in order
|
||||
* to report the correct error code - SEGV_PKUERR - we must handle
|
||||
* that case here.
|
||||
*/
|
||||
return !arch_vma_access_permitted(vma,
|
||||
mm_flags & FAULT_FLAG_WRITE,
|
||||
mm_flags & FAULT_FLAG_INSTRUCTION,
|
||||
@@ -635,7 +647,7 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
|
||||
goto bad_area;
|
||||
}
|
||||
|
||||
if (fault_from_pkey(esr, vma, mm_flags)) {
|
||||
if (fault_from_pkey(vma, mm_flags)) {
|
||||
pkey = vma_pkey(vma);
|
||||
vma_end_read(vma);
|
||||
fault = 0;
|
||||
@@ -679,7 +691,7 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
|
||||
goto bad_area;
|
||||
}
|
||||
|
||||
if (fault_from_pkey(esr, vma, mm_flags)) {
|
||||
if (fault_from_pkey(vma, mm_flags)) {
|
||||
pkey = vma_pkey(vma);
|
||||
mmap_read_unlock(mm);
|
||||
fault = 0;
|
||||
|
||||
@@ -518,7 +518,6 @@ alternative_else_nop_endif
|
||||
msr REG_PIR_EL1, x0
|
||||
|
||||
orr tcr2, tcr2, TCR2_EL1_PIE
|
||||
msr REG_TCR2_EL1, x0
|
||||
|
||||
.Lskip_indirection:
|
||||
|
||||
|
||||
@@ -50,4 +50,3 @@ CONFIG_CRYPTO_DEV_IMGTEC_HASH=y
|
||||
CONFIG_IMGPDC_WDT=y
|
||||
CONFIG_IR_IMG=y
|
||||
CONFIG_CC10001_ADC=y
|
||||
CONFIG_SND_SOC_IMG=y
|
||||
|
||||
@@ -63,7 +63,8 @@ config RISCV
|
||||
select ARCH_OPTIONAL_KERNEL_RWX_DEFAULT
|
||||
select ARCH_STACKWALK
|
||||
select ARCH_SUPPORTS_ATOMIC_RMW
|
||||
select ARCH_SUPPORTS_CFI_CLANG
|
||||
# clang >= 17: https://github.com/llvm/llvm-project/commit/62fa708ceb027713b386c7e0efda994f8bdc27e2
|
||||
select ARCH_SUPPORTS_CFI_CLANG if CLANG_VERSION >= 170000
|
||||
select ARCH_SUPPORTS_DEBUG_PAGEALLOC if MMU
|
||||
select ARCH_SUPPORTS_HUGE_PFNMAP if TRANSPARENT_HUGEPAGE
|
||||
select ARCH_SUPPORTS_HUGETLBFS if MMU
|
||||
|
||||
@@ -18,10 +18,10 @@ const struct cpu_operations cpu_ops_sbi;
|
||||
|
||||
/*
|
||||
* Ordered booting via HSM brings one cpu at a time. However, cpu hotplug can
|
||||
* be invoked from multiple threads in parallel. Define a per cpu data
|
||||
* be invoked from multiple threads in parallel. Define an array of boot data
|
||||
* to handle that.
|
||||
*/
|
||||
static DEFINE_PER_CPU(struct sbi_hart_boot_data, boot_data);
|
||||
static struct sbi_hart_boot_data boot_data[NR_CPUS];
|
||||
|
||||
static int sbi_hsm_hart_start(unsigned long hartid, unsigned long saddr,
|
||||
unsigned long priv)
|
||||
@@ -67,7 +67,7 @@ static int sbi_cpu_start(unsigned int cpuid, struct task_struct *tidle)
|
||||
unsigned long boot_addr = __pa_symbol(secondary_start_sbi);
|
||||
unsigned long hartid = cpuid_to_hartid_map(cpuid);
|
||||
unsigned long hsm_data;
|
||||
struct sbi_hart_boot_data *bdata = &per_cpu(boot_data, cpuid);
|
||||
struct sbi_hart_boot_data *bdata = &boot_data[cpuid];
|
||||
|
||||
/* Make sure tidle is updated */
|
||||
smp_mb();
|
||||
|
||||
@@ -38,6 +38,7 @@ static int s390_sha1_init(struct shash_desc *desc)
|
||||
sctx->state[4] = SHA1_H4;
|
||||
sctx->count = 0;
|
||||
sctx->func = CPACF_KIMD_SHA_1;
|
||||
sctx->first_message_part = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -60,6 +61,7 @@ static int s390_sha1_import(struct shash_desc *desc, const void *in)
|
||||
sctx->count = ictx->count;
|
||||
memcpy(sctx->state, ictx->state, sizeof(ictx->state));
|
||||
sctx->func = CPACF_KIMD_SHA_1;
|
||||
sctx->first_message_part = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ static int sha512_init(struct shash_desc *desc)
|
||||
ctx->count = 0;
|
||||
ctx->sha512.count_hi = 0;
|
||||
ctx->func = CPACF_KIMD_SHA_512;
|
||||
ctx->first_message_part = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -57,6 +58,7 @@ static int sha512_import(struct shash_desc *desc, const void *in)
|
||||
|
||||
memcpy(sctx->state, ictx->state, sizeof(ictx->state));
|
||||
sctx->func = CPACF_KIMD_SHA_512;
|
||||
sctx->first_message_part = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -97,6 +99,7 @@ static int sha384_init(struct shash_desc *desc)
|
||||
ctx->count = 0;
|
||||
ctx->sha512.count_hi = 0;
|
||||
ctx->func = CPACF_KIMD_SHA_512;
|
||||
ctx->first_message_part = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ static inline bool ers_result_indicates_abort(pci_ers_result_t ers_res)
|
||||
case PCI_ERS_RESULT_CAN_RECOVER:
|
||||
case PCI_ERS_RESULT_RECOVERED:
|
||||
case PCI_ERS_RESULT_NEED_RESET:
|
||||
case PCI_ERS_RESULT_NONE:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
@@ -78,10 +79,6 @@ static bool is_driver_supported(struct pci_driver *driver)
|
||||
return false;
|
||||
if (!driver->err_handler->error_detected)
|
||||
return false;
|
||||
if (!driver->err_handler->slot_reset)
|
||||
return false;
|
||||
if (!driver->err_handler->resume)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -106,6 +103,10 @@ static pci_ers_result_t zpci_event_do_error_state_clear(struct pci_dev *pdev,
|
||||
struct zpci_dev *zdev = to_zpci(pdev);
|
||||
int rc;
|
||||
|
||||
/* The underlying device may have been disabled by the event */
|
||||
if (!zdev_enabled(zdev))
|
||||
return PCI_ERS_RESULT_NEED_RESET;
|
||||
|
||||
pr_info("%s: Unblocking device access for examination\n", pci_name(pdev));
|
||||
rc = zpci_reset_load_store_blocked(zdev);
|
||||
if (rc) {
|
||||
@@ -114,16 +115,18 @@ static pci_ers_result_t zpci_event_do_error_state_clear(struct pci_dev *pdev,
|
||||
return PCI_ERS_RESULT_NEED_RESET;
|
||||
}
|
||||
|
||||
if (driver->err_handler->mmio_enabled) {
|
||||
if (driver->err_handler->mmio_enabled)
|
||||
ers_res = driver->err_handler->mmio_enabled(pdev);
|
||||
if (ers_result_indicates_abort(ers_res)) {
|
||||
pr_info("%s: Automatic recovery failed after MMIO re-enable\n",
|
||||
pci_name(pdev));
|
||||
return ers_res;
|
||||
} else if (ers_res == PCI_ERS_RESULT_NEED_RESET) {
|
||||
pr_debug("%s: Driver needs reset to recover\n", pci_name(pdev));
|
||||
return ers_res;
|
||||
}
|
||||
else
|
||||
ers_res = PCI_ERS_RESULT_NONE;
|
||||
|
||||
if (ers_result_indicates_abort(ers_res)) {
|
||||
pr_info("%s: Automatic recovery failed after MMIO re-enable\n",
|
||||
pci_name(pdev));
|
||||
return ers_res;
|
||||
} else if (ers_res == PCI_ERS_RESULT_NEED_RESET) {
|
||||
pr_debug("%s: Driver needs reset to recover\n", pci_name(pdev));
|
||||
return ers_res;
|
||||
}
|
||||
|
||||
pr_debug("%s: Unblocking DMA\n", pci_name(pdev));
|
||||
@@ -150,7 +153,12 @@ static pci_ers_result_t zpci_event_do_reset(struct pci_dev *pdev,
|
||||
return ers_res;
|
||||
}
|
||||
pdev->error_state = pci_channel_io_normal;
|
||||
ers_res = driver->err_handler->slot_reset(pdev);
|
||||
|
||||
if (driver->err_handler->slot_reset)
|
||||
ers_res = driver->err_handler->slot_reset(pdev);
|
||||
else
|
||||
ers_res = PCI_ERS_RESULT_NONE;
|
||||
|
||||
if (ers_result_indicates_abort(ers_res)) {
|
||||
pr_info("%s: Automatic recovery failed after slot reset\n", pci_name(pdev));
|
||||
return ers_res;
|
||||
@@ -214,7 +222,7 @@ static pci_ers_result_t zpci_event_attempt_error_recovery(struct pci_dev *pdev)
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (ers_res == PCI_ERS_RESULT_CAN_RECOVER) {
|
||||
if (ers_res != PCI_ERS_RESULT_NEED_RESET) {
|
||||
ers_res = zpci_event_do_error_state_clear(pdev, driver);
|
||||
if (ers_result_indicates_abort(ers_res)) {
|
||||
status_str = "failed (abort on MMIO enable)";
|
||||
@@ -225,6 +233,16 @@ static pci_ers_result_t zpci_event_attempt_error_recovery(struct pci_dev *pdev)
|
||||
if (ers_res == PCI_ERS_RESULT_NEED_RESET)
|
||||
ers_res = zpci_event_do_reset(pdev, driver);
|
||||
|
||||
/*
|
||||
* ers_res can be PCI_ERS_RESULT_NONE either because the driver
|
||||
* decided to return it, indicating that it abstains from voting
|
||||
* on how to recover, or because it didn't implement the callback.
|
||||
* Both cases assume, that if there is nothing else causing a
|
||||
* disconnect, we recovered successfully.
|
||||
*/
|
||||
if (ers_res == PCI_ERS_RESULT_NONE)
|
||||
ers_res = PCI_ERS_RESULT_RECOVERED;
|
||||
|
||||
if (ers_res != PCI_ERS_RESULT_RECOVERED) {
|
||||
pr_err("%s: Automatic recovery failed; operator intervention is required\n",
|
||||
pci_name(pdev));
|
||||
@@ -273,6 +291,8 @@ static void __zpci_event_error(struct zpci_ccdf_err *ccdf)
|
||||
struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
|
||||
struct pci_dev *pdev = NULL;
|
||||
pci_ers_result_t ers_res;
|
||||
u32 fh = 0;
|
||||
int rc;
|
||||
|
||||
zpci_dbg(3, "err fid:%x, fh:%x, pec:%x\n",
|
||||
ccdf->fid, ccdf->fh, ccdf->pec);
|
||||
@@ -281,6 +301,15 @@ static void __zpci_event_error(struct zpci_ccdf_err *ccdf)
|
||||
|
||||
if (zdev) {
|
||||
mutex_lock(&zdev->state_lock);
|
||||
rc = clp_refresh_fh(zdev->fid, &fh);
|
||||
if (rc)
|
||||
goto no_pdev;
|
||||
if (!fh || ccdf->fh != fh) {
|
||||
/* Ignore events with stale handles */
|
||||
zpci_dbg(3, "err fid:%x, fh:%x (stale %x)\n",
|
||||
ccdf->fid, fh, ccdf->fh);
|
||||
goto no_pdev;
|
||||
}
|
||||
zpci_update_fh(zdev, ccdf->fh);
|
||||
if (zdev->zbus->bus)
|
||||
pdev = pci_get_slot(zdev->zbus->bus, zdev->devfn);
|
||||
|
||||
@@ -147,7 +147,7 @@ config X86
|
||||
select ARCH_WANTS_DYNAMIC_TASK_STRUCT
|
||||
select ARCH_WANTS_NO_INSTR
|
||||
select ARCH_WANT_GENERAL_HUGETLB
|
||||
select ARCH_WANT_HUGE_PMD_SHARE
|
||||
select ARCH_WANT_HUGE_PMD_SHARE if X86_64
|
||||
select ARCH_WANT_LD_ORPHAN_WARN
|
||||
select ARCH_WANT_OPTIMIZE_DAX_VMEMMAP if X86_64
|
||||
select ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP if X86_64
|
||||
@@ -2695,6 +2695,15 @@ config MITIGATION_ITS
|
||||
disabled, mitigation cannot be enabled via cmdline.
|
||||
See <file:Documentation/admin-guide/hw-vuln/indirect-target-selection.rst>
|
||||
|
||||
config MITIGATION_TSA
|
||||
bool "Mitigate Transient Scheduler Attacks"
|
||||
depends on CPU_SUP_AMD
|
||||
default y
|
||||
help
|
||||
Enable mitigation for Transient Scheduler Attacks. TSA is a hardware
|
||||
security vulnerability on AMD CPUs which can lead to forwarding of
|
||||
invalid info to subsequent instructions and thus can affect their
|
||||
timing and thereby cause a leakage.
|
||||
endif
|
||||
|
||||
config ARCH_HAS_ADD_PAGES
|
||||
|
||||
@@ -88,7 +88,7 @@ static const char * const sev_status_feat_names[] = {
|
||||
*/
|
||||
static u64 snp_tsc_scale __ro_after_init;
|
||||
static u64 snp_tsc_offset __ro_after_init;
|
||||
static u64 snp_tsc_freq_khz __ro_after_init;
|
||||
static unsigned long snp_tsc_freq_khz __ro_after_init;
|
||||
|
||||
DEFINE_PER_CPU(struct sev_es_runtime_data*, runtime_data);
|
||||
DEFINE_PER_CPU(struct sev_es_save_area *, sev_vmsa);
|
||||
@@ -2167,15 +2167,31 @@ static unsigned long securetsc_get_tsc_khz(void)
|
||||
|
||||
void __init snp_secure_tsc_init(void)
|
||||
{
|
||||
unsigned long long tsc_freq_mhz;
|
||||
struct snp_secrets_page *secrets;
|
||||
unsigned long tsc_freq_mhz;
|
||||
void *mem;
|
||||
|
||||
if (!cc_platform_has(CC_ATTR_GUEST_SNP_SECURE_TSC))
|
||||
return;
|
||||
|
||||
mem = early_memremap_encrypted(sev_secrets_pa, PAGE_SIZE);
|
||||
if (!mem) {
|
||||
pr_err("Unable to get TSC_FACTOR: failed to map the SNP secrets page.\n");
|
||||
sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_SECURE_TSC);
|
||||
}
|
||||
|
||||
secrets = (__force struct snp_secrets_page *)mem;
|
||||
|
||||
setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
|
||||
rdmsrq(MSR_AMD64_GUEST_TSC_FREQ, tsc_freq_mhz);
|
||||
snp_tsc_freq_khz = (unsigned long)(tsc_freq_mhz * 1000);
|
||||
|
||||
/* Extract the GUEST TSC MHZ from BIT[17:0], rest is reserved space */
|
||||
tsc_freq_mhz &= GENMASK_ULL(17, 0);
|
||||
|
||||
snp_tsc_freq_khz = SNP_SCALE_TSC_FREQ(tsc_freq_mhz * 1000, secrets->tsc_factor);
|
||||
|
||||
x86_platform.calibrate_cpu = securetsc_get_tsc_khz;
|
||||
x86_platform.calibrate_tsc = securetsc_get_tsc_khz;
|
||||
|
||||
early_memunmap(mem, PAGE_SIZE);
|
||||
}
|
||||
|
||||
@@ -36,20 +36,20 @@ EXPORT_SYMBOL_GPL(write_ibpb);
|
||||
|
||||
/*
|
||||
* Define the VERW operand that is disguised as entry code so that
|
||||
* it can be referenced with KPTI enabled. This ensure VERW can be
|
||||
* it can be referenced with KPTI enabled. This ensures VERW can be
|
||||
* used late in exit-to-user path after page tables are switched.
|
||||
*/
|
||||
.pushsection .entry.text, "ax"
|
||||
|
||||
.align L1_CACHE_BYTES, 0xcc
|
||||
SYM_CODE_START_NOALIGN(mds_verw_sel)
|
||||
SYM_CODE_START_NOALIGN(x86_verw_sel)
|
||||
UNWIND_HINT_UNDEFINED
|
||||
ANNOTATE_NOENDBR
|
||||
.word __KERNEL_DS
|
||||
.align L1_CACHE_BYTES, 0xcc
|
||||
SYM_CODE_END(mds_verw_sel);
|
||||
SYM_CODE_END(x86_verw_sel);
|
||||
/* For KVM */
|
||||
EXPORT_SYMBOL_GPL(mds_verw_sel);
|
||||
EXPORT_SYMBOL_GPL(x86_verw_sel);
|
||||
|
||||
.popsection
|
||||
|
||||
|
||||
@@ -456,6 +456,7 @@
|
||||
#define X86_FEATURE_NO_NESTED_DATA_BP (20*32+ 0) /* No Nested Data Breakpoints */
|
||||
#define X86_FEATURE_WRMSR_XX_BASE_NS (20*32+ 1) /* WRMSR to {FS,GS,KERNEL_GS}_BASE is non-serializing */
|
||||
#define X86_FEATURE_LFENCE_RDTSC (20*32+ 2) /* LFENCE always serializing / synchronizes RDTSC */
|
||||
#define X86_FEATURE_VERW_CLEAR (20*32+ 5) /* The memory form of VERW mitigates TSA */
|
||||
#define X86_FEATURE_NULL_SEL_CLR_BASE (20*32+ 6) /* Null Selector Clears Base */
|
||||
#define X86_FEATURE_AUTOIBRS (20*32+ 8) /* Automatic IBRS */
|
||||
#define X86_FEATURE_NO_SMM_CTL_MSR (20*32+ 9) /* SMM_CTL MSR is not present */
|
||||
@@ -487,6 +488,9 @@
|
||||
#define X86_FEATURE_PREFER_YMM (21*32+ 8) /* Avoid ZMM registers due to downclocking */
|
||||
#define X86_FEATURE_APX (21*32+ 9) /* Advanced Performance Extensions */
|
||||
#define X86_FEATURE_INDIRECT_THUNK_ITS (21*32+10) /* Use thunk for indirect branches in lower half of cacheline */
|
||||
#define X86_FEATURE_TSA_SQ_NO (21*32+11) /* AMD CPU not vulnerable to TSA-SQ */
|
||||
#define X86_FEATURE_TSA_L1_NO (21*32+12) /* AMD CPU not vulnerable to TSA-L1 */
|
||||
#define X86_FEATURE_CLEAR_CPU_BUF_VM (21*32+13) /* Clear CPU buffers using VERW before VMRUN */
|
||||
|
||||
/*
|
||||
* BUG word(s)
|
||||
@@ -542,5 +546,5 @@
|
||||
#define X86_BUG_OLD_MICROCODE X86_BUG( 1*32+ 6) /* "old_microcode" CPU has old microcode, it is surely vulnerable to something */
|
||||
#define X86_BUG_ITS X86_BUG( 1*32+ 7) /* "its" CPU is affected by Indirect Target Selection */
|
||||
#define X86_BUG_ITS_NATIVE_ONLY X86_BUG( 1*32+ 8) /* "its_native_only" CPU is affected by ITS, VMX is not affected */
|
||||
|
||||
#define X86_BUG_TSA X86_BUG( 1*32+ 9) /* "tsa" CPU is affected by Transient Scheduler Attacks */
|
||||
#endif /* _ASM_X86_CPUFEATURES_H */
|
||||
|
||||
@@ -44,13 +44,13 @@ static __always_inline void native_irq_enable(void)
|
||||
|
||||
static __always_inline void native_safe_halt(void)
|
||||
{
|
||||
mds_idle_clear_cpu_buffers();
|
||||
x86_idle_clear_cpu_buffers();
|
||||
asm volatile("sti; hlt": : :"memory");
|
||||
}
|
||||
|
||||
static __always_inline void native_halt(void)
|
||||
{
|
||||
mds_idle_clear_cpu_buffers();
|
||||
x86_idle_clear_cpu_buffers();
|
||||
asm volatile("hlt": : :"memory");
|
||||
}
|
||||
|
||||
|
||||
@@ -700,8 +700,13 @@ struct kvm_vcpu_hv {
|
||||
|
||||
struct kvm_vcpu_hv_tlb_flush_fifo tlb_flush_fifo[HV_NR_TLB_FLUSH_FIFOS];
|
||||
|
||||
/* Preallocated buffer for handling hypercalls passing sparse vCPU set */
|
||||
/*
|
||||
* Preallocated buffers for handling hypercalls that pass sparse vCPU
|
||||
* sets (for high vCPU counts, they're too large to comfortably fit on
|
||||
* the stack).
|
||||
*/
|
||||
u64 sparse_banks[HV_MAX_SPARSE_VCPU_BANKS];
|
||||
DECLARE_BITMAP(vcpu_mask, KVM_MAX_VCPUS);
|
||||
|
||||
struct hv_vp_assist_page vp_assist_page;
|
||||
|
||||
@@ -764,6 +769,7 @@ enum kvm_only_cpuid_leafs {
|
||||
CPUID_8000_0022_EAX,
|
||||
CPUID_7_2_EDX,
|
||||
CPUID_24_0_EBX,
|
||||
CPUID_8000_0021_ECX,
|
||||
NR_KVM_CPU_CAPS,
|
||||
|
||||
NKVMCAPINTS = NR_KVM_CPU_CAPS - NCAPINTS,
|
||||
|
||||
@@ -628,6 +628,7 @@
|
||||
#define MSR_AMD64_OSVW_STATUS 0xc0010141
|
||||
#define MSR_AMD_PPIN_CTL 0xc00102f0
|
||||
#define MSR_AMD_PPIN 0xc00102f1
|
||||
#define MSR_AMD64_CPUID_FN_7 0xc0011002
|
||||
#define MSR_AMD64_CPUID_FN_1 0xc0011004
|
||||
#define MSR_AMD64_LS_CFG 0xc0011020
|
||||
#define MSR_AMD64_DC_CFG 0xc0011022
|
||||
|
||||
@@ -43,8 +43,6 @@ static __always_inline void __monitorx(const void *eax, u32 ecx, u32 edx)
|
||||
|
||||
static __always_inline void __mwait(u32 eax, u32 ecx)
|
||||
{
|
||||
mds_idle_clear_cpu_buffers();
|
||||
|
||||
/*
|
||||
* Use the instruction mnemonic with implicit operands, as the LLVM
|
||||
* assembler fails to assemble the mnemonic with explicit operands:
|
||||
@@ -80,7 +78,7 @@ static __always_inline void __mwait(u32 eax, u32 ecx)
|
||||
*/
|
||||
static __always_inline void __mwaitx(u32 eax, u32 ebx, u32 ecx)
|
||||
{
|
||||
/* No MDS buffer clear as this is AMD/HYGON only */
|
||||
/* No need for TSA buffer clearing on AMD */
|
||||
|
||||
/* "mwaitx %eax, %ebx, %ecx" */
|
||||
asm volatile(".byte 0x0f, 0x01, 0xfb"
|
||||
@@ -98,7 +96,6 @@ static __always_inline void __mwaitx(u32 eax, u32 ebx, u32 ecx)
|
||||
*/
|
||||
static __always_inline void __sti_mwait(u32 eax, u32 ecx)
|
||||
{
|
||||
mds_idle_clear_cpu_buffers();
|
||||
|
||||
asm volatile("sti; mwait" :: "a" (eax), "c" (ecx));
|
||||
}
|
||||
@@ -115,21 +112,29 @@ static __always_inline void __sti_mwait(u32 eax, u32 ecx)
|
||||
*/
|
||||
static __always_inline void mwait_idle_with_hints(u32 eax, u32 ecx)
|
||||
{
|
||||
if (need_resched())
|
||||
return;
|
||||
|
||||
x86_idle_clear_cpu_buffers();
|
||||
|
||||
if (static_cpu_has_bug(X86_BUG_MONITOR) || !current_set_polling_and_test()) {
|
||||
const void *addr = ¤t_thread_info()->flags;
|
||||
|
||||
alternative_input("", "clflush (%[addr])", X86_BUG_CLFLUSH_MONITOR, [addr] "a" (addr));
|
||||
__monitor(addr, 0, 0);
|
||||
|
||||
if (!need_resched()) {
|
||||
if (ecx & 1) {
|
||||
__mwait(eax, ecx);
|
||||
} else {
|
||||
__sti_mwait(eax, ecx);
|
||||
raw_local_irq_disable();
|
||||
}
|
||||
if (need_resched())
|
||||
goto out;
|
||||
|
||||
if (ecx & 1) {
|
||||
__mwait(eax, ecx);
|
||||
} else {
|
||||
__sti_mwait(eax, ecx);
|
||||
raw_local_irq_disable();
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
current_clr_polling();
|
||||
}
|
||||
|
||||
|
||||
@@ -302,25 +302,31 @@
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Macro to execute VERW instruction that mitigate transient data sampling
|
||||
* attacks such as MDS. On affected systems a microcode update overloaded VERW
|
||||
* instruction to also clear the CPU buffers. VERW clobbers CFLAGS.ZF.
|
||||
*
|
||||
* Macro to execute VERW insns that mitigate transient data sampling
|
||||
* attacks such as MDS or TSA. On affected systems a microcode update
|
||||
* overloaded VERW insns to also clear the CPU buffers. VERW clobbers
|
||||
* CFLAGS.ZF.
|
||||
* Note: Only the memory operand variant of VERW clears the CPU buffers.
|
||||
*/
|
||||
.macro CLEAR_CPU_BUFFERS
|
||||
.macro __CLEAR_CPU_BUFFERS feature
|
||||
#ifdef CONFIG_X86_64
|
||||
ALTERNATIVE "", "verw mds_verw_sel(%rip)", X86_FEATURE_CLEAR_CPU_BUF
|
||||
ALTERNATIVE "", "verw x86_verw_sel(%rip)", \feature
|
||||
#else
|
||||
/*
|
||||
* In 32bit mode, the memory operand must be a %cs reference. The data
|
||||
* segments may not be usable (vm86 mode), and the stack segment may not
|
||||
* be flat (ESPFIX32).
|
||||
*/
|
||||
ALTERNATIVE "", "verw %cs:mds_verw_sel", X86_FEATURE_CLEAR_CPU_BUF
|
||||
ALTERNATIVE "", "verw %cs:x86_verw_sel", \feature
|
||||
#endif
|
||||
.endm
|
||||
|
||||
#define CLEAR_CPU_BUFFERS \
|
||||
__CLEAR_CPU_BUFFERS X86_FEATURE_CLEAR_CPU_BUF
|
||||
|
||||
#define VM_CLEAR_CPU_BUFFERS \
|
||||
__CLEAR_CPU_BUFFERS X86_FEATURE_CLEAR_CPU_BUF_VM
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
.macro CLEAR_BRANCH_HISTORY
|
||||
ALTERNATIVE "", "call clear_bhb_loop", X86_FEATURE_CLEAR_BHB_LOOP
|
||||
@@ -567,24 +573,24 @@ DECLARE_STATIC_KEY_FALSE(switch_mm_always_ibpb);
|
||||
|
||||
DECLARE_STATIC_KEY_FALSE(switch_vcpu_ibpb);
|
||||
|
||||
DECLARE_STATIC_KEY_FALSE(mds_idle_clear);
|
||||
DECLARE_STATIC_KEY_FALSE(cpu_buf_idle_clear);
|
||||
|
||||
DECLARE_STATIC_KEY_FALSE(switch_mm_cond_l1d_flush);
|
||||
|
||||
DECLARE_STATIC_KEY_FALSE(cpu_buf_vm_clear);
|
||||
|
||||
extern u16 mds_verw_sel;
|
||||
extern u16 x86_verw_sel;
|
||||
|
||||
#include <asm/segment.h>
|
||||
|
||||
/**
|
||||
* mds_clear_cpu_buffers - Mitigation for MDS and TAA vulnerability
|
||||
* x86_clear_cpu_buffers - Buffer clearing support for different x86 CPU vulns
|
||||
*
|
||||
* This uses the otherwise unused and obsolete VERW instruction in
|
||||
* combination with microcode which triggers a CPU buffer flush when the
|
||||
* instruction is executed.
|
||||
*/
|
||||
static __always_inline void mds_clear_cpu_buffers(void)
|
||||
static __always_inline void x86_clear_cpu_buffers(void)
|
||||
{
|
||||
static const u16 ds = __KERNEL_DS;
|
||||
|
||||
@@ -601,14 +607,15 @@ static __always_inline void mds_clear_cpu_buffers(void)
|
||||
}
|
||||
|
||||
/**
|
||||
* mds_idle_clear_cpu_buffers - Mitigation for MDS vulnerability
|
||||
* x86_idle_clear_cpu_buffers - Buffer clearing support in idle for the MDS
|
||||
* and TSA vulnerabilities.
|
||||
*
|
||||
* Clear CPU buffers if the corresponding static key is enabled
|
||||
*/
|
||||
static __always_inline void mds_idle_clear_cpu_buffers(void)
|
||||
static __always_inline void x86_idle_clear_cpu_buffers(void)
|
||||
{
|
||||
if (static_branch_likely(&mds_idle_clear))
|
||||
mds_clear_cpu_buffers();
|
||||
if (static_branch_likely(&cpu_buf_idle_clear))
|
||||
x86_clear_cpu_buffers();
|
||||
}
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
@@ -223,6 +223,18 @@ struct snp_tsc_info_resp {
|
||||
u8 rsvd2[100];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Obtain the mean TSC frequency by decreasing the nominal TSC frequency with
|
||||
* TSC_FACTOR as documented in the SNP Firmware ABI specification:
|
||||
*
|
||||
* GUEST_TSC_FREQ * (1 - (TSC_FACTOR * 0.00001))
|
||||
*
|
||||
* which is equivalent to:
|
||||
*
|
||||
* GUEST_TSC_FREQ -= (GUEST_TSC_FREQ * TSC_FACTOR) / 100000;
|
||||
*/
|
||||
#define SNP_SCALE_TSC_FREQ(freq, factor) ((freq) - (freq) * (factor) / 100000)
|
||||
|
||||
struct snp_guest_req {
|
||||
void *req_buf;
|
||||
size_t req_sz;
|
||||
@@ -282,8 +294,11 @@ struct snp_secrets_page {
|
||||
u8 svsm_guest_vmpl;
|
||||
u8 rsvd3[3];
|
||||
|
||||
/* The percentage decrease from nominal to mean TSC frequency. */
|
||||
u32 tsc_factor;
|
||||
|
||||
/* Remainder of page */
|
||||
u8 rsvd4[3744];
|
||||
u8 rsvd4[3740];
|
||||
} __packed;
|
||||
|
||||
struct snp_msg_desc {
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
#define TDVMCALL_MAP_GPA 0x10001
|
||||
#define TDVMCALL_GET_QUOTE 0x10002
|
||||
#define TDVMCALL_REPORT_FATAL_ERROR 0x10003
|
||||
#define TDVMCALL_SETUP_EVENT_NOTIFY_INTERRUPT 0x10004ULL
|
||||
|
||||
/*
|
||||
* TDG.VP.VMCALL Status Codes (returned in R10)
|
||||
|
||||
@@ -965,7 +965,13 @@ struct kvm_tdx_cmd {
|
||||
struct kvm_tdx_capabilities {
|
||||
__u64 supported_attrs;
|
||||
__u64 supported_xfam;
|
||||
__u64 reserved[254];
|
||||
|
||||
__u64 kernel_tdvmcallinfo_1_r11;
|
||||
__u64 user_tdvmcallinfo_1_r11;
|
||||
__u64 kernel_tdvmcallinfo_1_r12;
|
||||
__u64 user_tdvmcallinfo_1_r12;
|
||||
|
||||
__u64 reserved[250];
|
||||
|
||||
/* Configurable CPUID bits for userspace */
|
||||
struct kvm_cpuid2 cpuid;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <linux/sched/clock.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/topology.h>
|
||||
#include <asm/amd/fch.h>
|
||||
#include <linux/platform_data/x86/amd-fch.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/apic.h>
|
||||
#include <asm/cacheinfo.h>
|
||||
@@ -377,6 +377,47 @@ static void bsp_determine_snp(struct cpuinfo_x86 *c)
|
||||
#endif
|
||||
}
|
||||
|
||||
#define ZEN_MODEL_STEP_UCODE(fam, model, step, ucode) \
|
||||
X86_MATCH_VFM_STEPS(VFM_MAKE(X86_VENDOR_AMD, fam, model), \
|
||||
step, step, ucode)
|
||||
|
||||
static const struct x86_cpu_id amd_tsa_microcode[] = {
|
||||
ZEN_MODEL_STEP_UCODE(0x19, 0x01, 0x1, 0x0a0011d7),
|
||||
ZEN_MODEL_STEP_UCODE(0x19, 0x01, 0x2, 0x0a00123b),
|
||||
ZEN_MODEL_STEP_UCODE(0x19, 0x08, 0x2, 0x0a00820d),
|
||||
ZEN_MODEL_STEP_UCODE(0x19, 0x11, 0x1, 0x0a10114c),
|
||||
ZEN_MODEL_STEP_UCODE(0x19, 0x11, 0x2, 0x0a10124c),
|
||||
ZEN_MODEL_STEP_UCODE(0x19, 0x18, 0x1, 0x0a108109),
|
||||
ZEN_MODEL_STEP_UCODE(0x19, 0x21, 0x0, 0x0a20102e),
|
||||
ZEN_MODEL_STEP_UCODE(0x19, 0x21, 0x2, 0x0a201211),
|
||||
ZEN_MODEL_STEP_UCODE(0x19, 0x44, 0x1, 0x0a404108),
|
||||
ZEN_MODEL_STEP_UCODE(0x19, 0x50, 0x0, 0x0a500012),
|
||||
ZEN_MODEL_STEP_UCODE(0x19, 0x61, 0x2, 0x0a60120a),
|
||||
ZEN_MODEL_STEP_UCODE(0x19, 0x74, 0x1, 0x0a704108),
|
||||
ZEN_MODEL_STEP_UCODE(0x19, 0x75, 0x2, 0x0a705208),
|
||||
ZEN_MODEL_STEP_UCODE(0x19, 0x78, 0x0, 0x0a708008),
|
||||
ZEN_MODEL_STEP_UCODE(0x19, 0x7c, 0x0, 0x0a70c008),
|
||||
ZEN_MODEL_STEP_UCODE(0x19, 0xa0, 0x2, 0x0aa00216),
|
||||
{},
|
||||
};
|
||||
|
||||
static void tsa_init(struct cpuinfo_x86 *c)
|
||||
{
|
||||
if (cpu_has(c, X86_FEATURE_HYPERVISOR))
|
||||
return;
|
||||
|
||||
if (cpu_has(c, X86_FEATURE_ZEN3) ||
|
||||
cpu_has(c, X86_FEATURE_ZEN4)) {
|
||||
if (x86_match_min_microcode_rev(amd_tsa_microcode))
|
||||
setup_force_cpu_cap(X86_FEATURE_VERW_CLEAR);
|
||||
else
|
||||
pr_debug("%s: current revision: 0x%x\n", __func__, c->microcode);
|
||||
} else {
|
||||
setup_force_cpu_cap(X86_FEATURE_TSA_SQ_NO);
|
||||
setup_force_cpu_cap(X86_FEATURE_TSA_L1_NO);
|
||||
}
|
||||
}
|
||||
|
||||
static void bsp_init_amd(struct cpuinfo_x86 *c)
|
||||
{
|
||||
if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) {
|
||||
@@ -489,6 +530,9 @@ static void bsp_init_amd(struct cpuinfo_x86 *c)
|
||||
}
|
||||
|
||||
bsp_determine_snp(c);
|
||||
|
||||
tsa_init(c);
|
||||
|
||||
return;
|
||||
|
||||
warn:
|
||||
@@ -930,6 +974,16 @@ static void init_amd_zen2(struct cpuinfo_x86 *c)
|
||||
init_spectral_chicken(c);
|
||||
fix_erratum_1386(c);
|
||||
zen2_zenbleed_check(c);
|
||||
|
||||
/* Disable RDSEED on AMD Cyan Skillfish because of an error. */
|
||||
if (c->x86_model == 0x47 && c->x86_stepping == 0x0) {
|
||||
clear_cpu_cap(c, X86_FEATURE_RDSEED);
|
||||
msr_clear_bit(MSR_AMD64_CPUID_FN_7, 18);
|
||||
pr_emerg("RDSEED is not reliable on this platform; disabling.\n");
|
||||
}
|
||||
|
||||
/* Correct misconfigured CPUID on some clients. */
|
||||
clear_cpu_cap(c, X86_FEATURE_INVLPGB);
|
||||
}
|
||||
|
||||
static void init_amd_zen3(struct cpuinfo_x86 *c)
|
||||
|
||||
@@ -94,6 +94,8 @@ static void __init bhi_apply_mitigation(void);
|
||||
static void __init its_select_mitigation(void);
|
||||
static void __init its_update_mitigation(void);
|
||||
static void __init its_apply_mitigation(void);
|
||||
static void __init tsa_select_mitigation(void);
|
||||
static void __init tsa_apply_mitigation(void);
|
||||
|
||||
/* The base value of the SPEC_CTRL MSR without task-specific bits set */
|
||||
u64 x86_spec_ctrl_base;
|
||||
@@ -169,9 +171,9 @@ DEFINE_STATIC_KEY_FALSE(switch_mm_always_ibpb);
|
||||
DEFINE_STATIC_KEY_FALSE(switch_vcpu_ibpb);
|
||||
EXPORT_SYMBOL_GPL(switch_vcpu_ibpb);
|
||||
|
||||
/* Control MDS CPU buffer clear before idling (halt, mwait) */
|
||||
DEFINE_STATIC_KEY_FALSE(mds_idle_clear);
|
||||
EXPORT_SYMBOL_GPL(mds_idle_clear);
|
||||
/* Control CPU buffer clear before idling (halt, mwait) */
|
||||
DEFINE_STATIC_KEY_FALSE(cpu_buf_idle_clear);
|
||||
EXPORT_SYMBOL_GPL(cpu_buf_idle_clear);
|
||||
|
||||
/*
|
||||
* Controls whether l1d flush based mitigations are enabled,
|
||||
@@ -225,6 +227,7 @@ void __init cpu_select_mitigations(void)
|
||||
gds_select_mitigation();
|
||||
its_select_mitigation();
|
||||
bhi_select_mitigation();
|
||||
tsa_select_mitigation();
|
||||
|
||||
/*
|
||||
* After mitigations are selected, some may need to update their
|
||||
@@ -272,6 +275,7 @@ void __init cpu_select_mitigations(void)
|
||||
gds_apply_mitigation();
|
||||
its_apply_mitigation();
|
||||
bhi_apply_mitigation();
|
||||
tsa_apply_mitigation();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -637,7 +641,7 @@ static void __init mmio_apply_mitigation(void)
|
||||
* is required irrespective of SMT state.
|
||||
*/
|
||||
if (!(x86_arch_cap_msr & ARCH_CAP_FBSDP_NO))
|
||||
static_branch_enable(&mds_idle_clear);
|
||||
static_branch_enable(&cpu_buf_idle_clear);
|
||||
|
||||
if (mmio_nosmt || cpu_mitigations_auto_nosmt())
|
||||
cpu_smt_disable(false);
|
||||
@@ -1487,6 +1491,94 @@ static void __init its_apply_mitigation(void)
|
||||
set_return_thunk(its_return_thunk);
|
||||
}
|
||||
|
||||
#undef pr_fmt
|
||||
#define pr_fmt(fmt) "Transient Scheduler Attacks: " fmt
|
||||
|
||||
enum tsa_mitigations {
|
||||
TSA_MITIGATION_NONE,
|
||||
TSA_MITIGATION_AUTO,
|
||||
TSA_MITIGATION_UCODE_NEEDED,
|
||||
TSA_MITIGATION_USER_KERNEL,
|
||||
TSA_MITIGATION_VM,
|
||||
TSA_MITIGATION_FULL,
|
||||
};
|
||||
|
||||
static const char * const tsa_strings[] = {
|
||||
[TSA_MITIGATION_NONE] = "Vulnerable",
|
||||
[TSA_MITIGATION_UCODE_NEEDED] = "Vulnerable: No microcode",
|
||||
[TSA_MITIGATION_USER_KERNEL] = "Mitigation: Clear CPU buffers: user/kernel boundary",
|
||||
[TSA_MITIGATION_VM] = "Mitigation: Clear CPU buffers: VM",
|
||||
[TSA_MITIGATION_FULL] = "Mitigation: Clear CPU buffers",
|
||||
};
|
||||
|
||||
static enum tsa_mitigations tsa_mitigation __ro_after_init =
|
||||
IS_ENABLED(CONFIG_MITIGATION_TSA) ? TSA_MITIGATION_AUTO : TSA_MITIGATION_NONE;
|
||||
|
||||
static int __init tsa_parse_cmdline(char *str)
|
||||
{
|
||||
if (!str)
|
||||
return -EINVAL;
|
||||
|
||||
if (!strcmp(str, "off"))
|
||||
tsa_mitigation = TSA_MITIGATION_NONE;
|
||||
else if (!strcmp(str, "on"))
|
||||
tsa_mitigation = TSA_MITIGATION_FULL;
|
||||
else if (!strcmp(str, "user"))
|
||||
tsa_mitigation = TSA_MITIGATION_USER_KERNEL;
|
||||
else if (!strcmp(str, "vm"))
|
||||
tsa_mitigation = TSA_MITIGATION_VM;
|
||||
else
|
||||
pr_err("Ignoring unknown tsa=%s option.\n", str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
early_param("tsa", tsa_parse_cmdline);
|
||||
|
||||
static void __init tsa_select_mitigation(void)
|
||||
{
|
||||
if (cpu_mitigations_off() || !boot_cpu_has_bug(X86_BUG_TSA)) {
|
||||
tsa_mitigation = TSA_MITIGATION_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (tsa_mitigation == TSA_MITIGATION_NONE)
|
||||
return;
|
||||
|
||||
if (!boot_cpu_has(X86_FEATURE_VERW_CLEAR)) {
|
||||
tsa_mitigation = TSA_MITIGATION_UCODE_NEEDED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (tsa_mitigation == TSA_MITIGATION_AUTO)
|
||||
tsa_mitigation = TSA_MITIGATION_FULL;
|
||||
|
||||
/*
|
||||
* No need to set verw_clear_cpu_buf_mitigation_selected - it
|
||||
* doesn't fit all cases here and it is not needed because this
|
||||
* is the only VERW-based mitigation on AMD.
|
||||
*/
|
||||
out:
|
||||
pr_info("%s\n", tsa_strings[tsa_mitigation]);
|
||||
}
|
||||
|
||||
static void __init tsa_apply_mitigation(void)
|
||||
{
|
||||
switch (tsa_mitigation) {
|
||||
case TSA_MITIGATION_USER_KERNEL:
|
||||
setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF);
|
||||
break;
|
||||
case TSA_MITIGATION_VM:
|
||||
setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF_VM);
|
||||
break;
|
||||
case TSA_MITIGATION_FULL:
|
||||
setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF);
|
||||
setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF_VM);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#undef pr_fmt
|
||||
#define pr_fmt(fmt) "Spectre V2 : " fmt
|
||||
|
||||
@@ -2249,10 +2341,10 @@ static void update_mds_branch_idle(void)
|
||||
return;
|
||||
|
||||
if (sched_smt_active()) {
|
||||
static_branch_enable(&mds_idle_clear);
|
||||
static_branch_enable(&cpu_buf_idle_clear);
|
||||
} else if (mmio_mitigation == MMIO_MITIGATION_OFF ||
|
||||
(x86_arch_cap_msr & ARCH_CAP_FBSDP_NO)) {
|
||||
static_branch_disable(&mds_idle_clear);
|
||||
static_branch_disable(&cpu_buf_idle_clear);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2316,6 +2408,25 @@ void cpu_bugs_smt_update(void)
|
||||
break;
|
||||
}
|
||||
|
||||
switch (tsa_mitigation) {
|
||||
case TSA_MITIGATION_USER_KERNEL:
|
||||
case TSA_MITIGATION_VM:
|
||||
case TSA_MITIGATION_AUTO:
|
||||
case TSA_MITIGATION_FULL:
|
||||
/*
|
||||
* TSA-SQ can potentially lead to info leakage between
|
||||
* SMT threads.
|
||||
*/
|
||||
if (sched_smt_active())
|
||||
static_branch_enable(&cpu_buf_idle_clear);
|
||||
else
|
||||
static_branch_disable(&cpu_buf_idle_clear);
|
||||
break;
|
||||
case TSA_MITIGATION_NONE:
|
||||
case TSA_MITIGATION_UCODE_NEEDED:
|
||||
break;
|
||||
}
|
||||
|
||||
mutex_unlock(&spec_ctrl_mutex);
|
||||
}
|
||||
|
||||
@@ -3265,6 +3376,11 @@ static ssize_t gds_show_state(char *buf)
|
||||
return sysfs_emit(buf, "%s\n", gds_strings[gds_mitigation]);
|
||||
}
|
||||
|
||||
static ssize_t tsa_show_state(char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "%s\n", tsa_strings[tsa_mitigation]);
|
||||
}
|
||||
|
||||
static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr,
|
||||
char *buf, unsigned int bug)
|
||||
{
|
||||
@@ -3328,6 +3444,9 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
|
||||
case X86_BUG_ITS:
|
||||
return its_show_state(buf);
|
||||
|
||||
case X86_BUG_TSA:
|
||||
return tsa_show_state(buf);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -3414,6 +3533,11 @@ ssize_t cpu_show_indirect_target_selection(struct device *dev, struct device_att
|
||||
{
|
||||
return cpu_show_common(dev, attr, buf, X86_BUG_ITS);
|
||||
}
|
||||
|
||||
ssize_t cpu_show_tsa(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return cpu_show_common(dev, attr, buf, X86_BUG_TSA);
|
||||
}
|
||||
#endif
|
||||
|
||||
void __warn_thunk(void)
|
||||
|
||||
@@ -1233,6 +1233,8 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
|
||||
#define ITS BIT(8)
|
||||
/* CPU is affected by Indirect Target Selection, but guest-host isolation is not affected */
|
||||
#define ITS_NATIVE_ONLY BIT(9)
|
||||
/* CPU is affected by Transient Scheduler Attacks */
|
||||
#define TSA BIT(10)
|
||||
|
||||
static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
|
||||
VULNBL_INTEL_STEPS(INTEL_IVYBRIDGE, X86_STEP_MAX, SRBDS),
|
||||
@@ -1280,7 +1282,7 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
|
||||
VULNBL_AMD(0x16, RETBLEED),
|
||||
VULNBL_AMD(0x17, RETBLEED | SMT_RSB | SRSO),
|
||||
VULNBL_HYGON(0x18, RETBLEED | SMT_RSB | SRSO),
|
||||
VULNBL_AMD(0x19, SRSO),
|
||||
VULNBL_AMD(0x19, SRSO | TSA),
|
||||
VULNBL_AMD(0x1a, SRSO),
|
||||
{}
|
||||
};
|
||||
@@ -1530,6 +1532,16 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
|
||||
setup_force_cpu_bug(X86_BUG_ITS_NATIVE_ONLY);
|
||||
}
|
||||
|
||||
if (c->x86_vendor == X86_VENDOR_AMD) {
|
||||
if (!cpu_has(c, X86_FEATURE_TSA_SQ_NO) ||
|
||||
!cpu_has(c, X86_FEATURE_TSA_L1_NO)) {
|
||||
if (cpu_matches(cpu_vuln_blacklist, TSA) ||
|
||||
/* Enable bug on Zen guests to allow for live migration. */
|
||||
(cpu_has(c, X86_FEATURE_HYPERVISOR) && cpu_has(c, X86_FEATURE_ZEN)))
|
||||
setup_force_cpu_bug(X86_BUG_TSA);
|
||||
}
|
||||
}
|
||||
|
||||
if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN))
|
||||
return;
|
||||
|
||||
|
||||
@@ -350,7 +350,6 @@ static void smca_configure(unsigned int bank, unsigned int cpu)
|
||||
|
||||
struct thresh_restart {
|
||||
struct threshold_block *b;
|
||||
int reset;
|
||||
int set_lvt_off;
|
||||
int lvt_off;
|
||||
u16 old_limit;
|
||||
@@ -432,13 +431,13 @@ static void threshold_restart_bank(void *_tr)
|
||||
|
||||
rdmsr(tr->b->address, lo, hi);
|
||||
|
||||
if (tr->b->threshold_limit < (hi & THRESHOLD_MAX))
|
||||
tr->reset = 1; /* limit cannot be lower than err count */
|
||||
|
||||
if (tr->reset) { /* reset err count and overflow bit */
|
||||
hi =
|
||||
(hi & ~(MASK_ERR_COUNT_HI | MASK_OVERFLOW_HI)) |
|
||||
(THRESHOLD_MAX - tr->b->threshold_limit);
|
||||
/*
|
||||
* Reset error count and overflow bit.
|
||||
* This is done during init or after handling an interrupt.
|
||||
*/
|
||||
if (hi & MASK_OVERFLOW_HI || tr->set_lvt_off) {
|
||||
hi &= ~(MASK_ERR_COUNT_HI | MASK_OVERFLOW_HI);
|
||||
hi |= THRESHOLD_MAX - tr->b->threshold_limit;
|
||||
} else if (tr->old_limit) { /* change limit w/o reset */
|
||||
int new_count = (hi & THRESHOLD_MAX) +
|
||||
(tr->old_limit - tr->b->threshold_limit);
|
||||
@@ -1113,13 +1112,20 @@ static const char *get_name(unsigned int cpu, unsigned int bank, struct threshol
|
||||
}
|
||||
|
||||
bank_type = smca_get_bank_type(cpu, bank);
|
||||
if (bank_type >= N_SMCA_BANK_TYPES)
|
||||
return NULL;
|
||||
|
||||
if (b && (bank_type == SMCA_UMC || bank_type == SMCA_UMC_V2)) {
|
||||
if (b->block < ARRAY_SIZE(smca_umc_block_names))
|
||||
return smca_umc_block_names[b->block];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (b && b->block) {
|
||||
snprintf(buf_mcatype, MAX_MCATYPE_NAME_LEN, "th_block_%u", b->block);
|
||||
return buf_mcatype;
|
||||
}
|
||||
|
||||
if (bank_type >= N_SMCA_BANK_TYPES) {
|
||||
snprintf(buf_mcatype, MAX_MCATYPE_NAME_LEN, "th_bank_%u", bank);
|
||||
return buf_mcatype;
|
||||
}
|
||||
|
||||
if (per_cpu(smca_bank_counts, cpu)[bank_type] == 1)
|
||||
|
||||
@@ -1740,6 +1740,11 @@ static void mc_poll_banks_default(void)
|
||||
|
||||
void (*mc_poll_banks)(void) = mc_poll_banks_default;
|
||||
|
||||
static bool should_enable_timer(unsigned long iv)
|
||||
{
|
||||
return !mca_cfg.ignore_ce && iv;
|
||||
}
|
||||
|
||||
static void mce_timer_fn(struct timer_list *t)
|
||||
{
|
||||
struct timer_list *cpu_t = this_cpu_ptr(&mce_timer);
|
||||
@@ -1763,7 +1768,7 @@ static void mce_timer_fn(struct timer_list *t)
|
||||
|
||||
if (mce_get_storm_mode()) {
|
||||
__start_timer(t, HZ);
|
||||
} else {
|
||||
} else if (should_enable_timer(iv)) {
|
||||
__this_cpu_write(mce_next_interval, iv);
|
||||
__start_timer(t, iv);
|
||||
}
|
||||
@@ -2156,11 +2161,10 @@ static void mce_start_timer(struct timer_list *t)
|
||||
{
|
||||
unsigned long iv = check_interval * HZ;
|
||||
|
||||
if (mca_cfg.ignore_ce || !iv)
|
||||
return;
|
||||
|
||||
this_cpu_write(mce_next_interval, iv);
|
||||
__start_timer(t, iv);
|
||||
if (should_enable_timer(iv)) {
|
||||
this_cpu_write(mce_next_interval, iv);
|
||||
__start_timer(t, iv);
|
||||
}
|
||||
}
|
||||
|
||||
static void __mcheck_cpu_setup_timer(void)
|
||||
@@ -2801,15 +2805,9 @@ static int mce_cpu_dead(unsigned int cpu)
|
||||
static int mce_cpu_online(unsigned int cpu)
|
||||
{
|
||||
struct timer_list *t = this_cpu_ptr(&mce_timer);
|
||||
int ret;
|
||||
|
||||
mce_device_create(cpu);
|
||||
|
||||
ret = mce_threshold_create_device(cpu);
|
||||
if (ret) {
|
||||
mce_device_remove(cpu);
|
||||
return ret;
|
||||
}
|
||||
mce_threshold_create_device(cpu);
|
||||
mce_reenable_cpu();
|
||||
mce_start_timer(t);
|
||||
return 0;
|
||||
|
||||
@@ -478,6 +478,7 @@ void mce_intel_feature_init(struct cpuinfo_x86 *c)
|
||||
void mce_intel_feature_clear(struct cpuinfo_x86 *c)
|
||||
{
|
||||
intel_clear_lmce();
|
||||
cmci_clear();
|
||||
}
|
||||
|
||||
bool intel_filter_mce(struct mce *m)
|
||||
|
||||
@@ -231,6 +231,13 @@ static const struct patch_digest phashes[] = {
|
||||
0x0d,0x5b,0x65,0x34,0x69,0xb2,0x62,0x21,
|
||||
}
|
||||
},
|
||||
{ 0xa0011d7, {
|
||||
0x35,0x07,0xcd,0x40,0x94,0xbc,0x81,0x6b,
|
||||
0xfc,0x61,0x56,0x1a,0xe2,0xdb,0x96,0x12,
|
||||
0x1c,0x1c,0x31,0xb1,0x02,0x6f,0xe5,0xd2,
|
||||
0xfe,0x1b,0x04,0x03,0x2c,0x8f,0x4c,0x36,
|
||||
}
|
||||
},
|
||||
{ 0xa001223, {
|
||||
0xfb,0x32,0x5f,0xc6,0x83,0x4f,0x8c,0xb8,
|
||||
0xa4,0x05,0xf9,0x71,0x53,0x01,0x16,0xc4,
|
||||
@@ -294,6 +301,13 @@ static const struct patch_digest phashes[] = {
|
||||
0xc0,0xcd,0x33,0xf2,0x8d,0xf9,0xef,0x59,
|
||||
}
|
||||
},
|
||||
{ 0xa00123b, {
|
||||
0xef,0xa1,0x1e,0x71,0xf1,0xc3,0x2c,0xe2,
|
||||
0xc3,0xef,0x69,0x41,0x7a,0x54,0xca,0xc3,
|
||||
0x8f,0x62,0x84,0xee,0xc2,0x39,0xd9,0x28,
|
||||
0x95,0xa7,0x12,0x49,0x1e,0x30,0x71,0x72,
|
||||
}
|
||||
},
|
||||
{ 0xa00820c, {
|
||||
0xa8,0x0c,0x81,0xc0,0xa6,0x00,0xe7,0xf3,
|
||||
0x5f,0x65,0xd3,0xb9,0x6f,0xea,0x93,0x63,
|
||||
@@ -301,6 +315,13 @@ static const struct patch_digest phashes[] = {
|
||||
0xe1,0x3b,0x8d,0xb2,0xf8,0x22,0x03,0xe2,
|
||||
}
|
||||
},
|
||||
{ 0xa00820d, {
|
||||
0xf9,0x2a,0xc0,0xf4,0x9e,0xa4,0x87,0xa4,
|
||||
0x7d,0x87,0x00,0xfd,0xab,0xda,0x19,0xca,
|
||||
0x26,0x51,0x32,0xc1,0x57,0x91,0xdf,0xc1,
|
||||
0x05,0xeb,0x01,0x7c,0x5a,0x95,0x21,0xb7,
|
||||
}
|
||||
},
|
||||
{ 0xa10113e, {
|
||||
0x05,0x3c,0x66,0xd7,0xa9,0x5a,0x33,0x10,
|
||||
0x1b,0xf8,0x9c,0x8f,0xed,0xfc,0xa7,0xa0,
|
||||
@@ -322,6 +343,13 @@ static const struct patch_digest phashes[] = {
|
||||
0xf1,0x5e,0xb0,0xde,0xb4,0x98,0xae,0xc4,
|
||||
}
|
||||
},
|
||||
{ 0xa10114c, {
|
||||
0x9e,0xb6,0xa2,0xd9,0x87,0x38,0xc5,0x64,
|
||||
0xd8,0x88,0xfa,0x78,0x98,0xf9,0x6f,0x74,
|
||||
0x39,0x90,0x1b,0xa5,0xcf,0x5e,0xb4,0x2a,
|
||||
0x02,0xff,0xd4,0x8c,0x71,0x8b,0xe2,0xc0,
|
||||
}
|
||||
},
|
||||
{ 0xa10123e, {
|
||||
0x03,0xb9,0x2c,0x76,0x48,0x93,0xc9,0x18,
|
||||
0xfb,0x56,0xfd,0xf7,0xe2,0x1d,0xca,0x4d,
|
||||
@@ -343,6 +371,13 @@ static const struct patch_digest phashes[] = {
|
||||
0x1b,0x7d,0x64,0x9d,0x4b,0x53,0x13,0x75,
|
||||
}
|
||||
},
|
||||
{ 0xa10124c, {
|
||||
0x29,0xea,0xf1,0x2c,0xb2,0xe4,0xef,0x90,
|
||||
0xa4,0xcd,0x1d,0x86,0x97,0x17,0x61,0x46,
|
||||
0xfc,0x22,0xcb,0x57,0x75,0x19,0xc8,0xcc,
|
||||
0x0c,0xf5,0xbc,0xac,0x81,0x9d,0x9a,0xd2,
|
||||
}
|
||||
},
|
||||
{ 0xa108108, {
|
||||
0xed,0xc2,0xec,0xa1,0x15,0xc6,0x65,0xe9,
|
||||
0xd0,0xef,0x39,0xaa,0x7f,0x55,0x06,0xc6,
|
||||
@@ -350,6 +385,13 @@ static const struct patch_digest phashes[] = {
|
||||
0x28,0x1e,0x9c,0x59,0x69,0x99,0x4d,0x16,
|
||||
}
|
||||
},
|
||||
{ 0xa108109, {
|
||||
0x85,0xb4,0xbd,0x7c,0x49,0xa7,0xbd,0xfa,
|
||||
0x49,0x36,0x80,0x81,0xc5,0xb7,0x39,0x1b,
|
||||
0x9a,0xaa,0x50,0xde,0x9b,0xe9,0x32,0x35,
|
||||
0x42,0x7e,0x51,0x4f,0x52,0x2c,0x28,0x59,
|
||||
}
|
||||
},
|
||||
{ 0xa20102d, {
|
||||
0xf9,0x6e,0xf2,0x32,0xd3,0x0f,0x5f,0x11,
|
||||
0x59,0xa1,0xfe,0xcc,0xcd,0x9b,0x42,0x89,
|
||||
@@ -357,6 +399,13 @@ static const struct patch_digest phashes[] = {
|
||||
0x8c,0xe9,0x19,0x3e,0xcc,0x3f,0x7b,0xb4,
|
||||
}
|
||||
},
|
||||
{ 0xa20102e, {
|
||||
0xbe,0x1f,0x32,0x04,0x0d,0x3c,0x9c,0xdd,
|
||||
0xe1,0xa4,0xbf,0x76,0x3a,0xec,0xc2,0xf6,
|
||||
0x11,0x00,0xa7,0xaf,0x0f,0xe5,0x02,0xc5,
|
||||
0x54,0x3a,0x1f,0x8c,0x16,0xb5,0xff,0xbe,
|
||||
}
|
||||
},
|
||||
{ 0xa201210, {
|
||||
0xe8,0x6d,0x51,0x6a,0x8e,0x72,0xf3,0xfe,
|
||||
0x6e,0x16,0xbc,0x62,0x59,0x40,0x17,0xe9,
|
||||
@@ -364,6 +413,13 @@ static const struct patch_digest phashes[] = {
|
||||
0xf7,0x55,0xf0,0x13,0xbb,0x22,0xf6,0x41,
|
||||
}
|
||||
},
|
||||
{ 0xa201211, {
|
||||
0x69,0xa1,0x17,0xec,0xd0,0xf6,0x6c,0x95,
|
||||
0xe2,0x1e,0xc5,0x59,0x1a,0x52,0x0a,0x27,
|
||||
0xc4,0xed,0xd5,0x59,0x1f,0xbf,0x00,0xff,
|
||||
0x08,0x88,0xb5,0xe1,0x12,0xb6,0xcc,0x27,
|
||||
}
|
||||
},
|
||||
{ 0xa404107, {
|
||||
0xbb,0x04,0x4e,0x47,0xdd,0x5e,0x26,0x45,
|
||||
0x1a,0xc9,0x56,0x24,0xa4,0x4c,0x82,0xb0,
|
||||
@@ -371,6 +427,13 @@ static const struct patch_digest phashes[] = {
|
||||
0x13,0xbc,0xc5,0x25,0xe4,0xc5,0xc3,0x99,
|
||||
}
|
||||
},
|
||||
{ 0xa404108, {
|
||||
0x69,0x67,0x43,0x06,0xf8,0x0c,0x62,0xdc,
|
||||
0xa4,0x21,0x30,0x4f,0x0f,0x21,0x2c,0xcb,
|
||||
0xcc,0x37,0xf1,0x1c,0xc3,0xf8,0x2f,0x19,
|
||||
0xdf,0x53,0x53,0x46,0xb1,0x15,0xea,0x00,
|
||||
}
|
||||
},
|
||||
{ 0xa500011, {
|
||||
0x23,0x3d,0x70,0x7d,0x03,0xc3,0xc4,0xf4,
|
||||
0x2b,0x82,0xc6,0x05,0xda,0x80,0x0a,0xf1,
|
||||
@@ -378,6 +441,13 @@ static const struct patch_digest phashes[] = {
|
||||
0x11,0x5e,0x96,0x7e,0x71,0xe9,0xfc,0x74,
|
||||
}
|
||||
},
|
||||
{ 0xa500012, {
|
||||
0xeb,0x74,0x0d,0x47,0xa1,0x8e,0x09,0xe4,
|
||||
0x93,0x4c,0xad,0x03,0x32,0x4c,0x38,0x16,
|
||||
0x10,0x39,0xdd,0x06,0xaa,0xce,0xd6,0x0f,
|
||||
0x62,0x83,0x9d,0x8e,0x64,0x55,0xbe,0x63,
|
||||
}
|
||||
},
|
||||
{ 0xa601209, {
|
||||
0x66,0x48,0xd4,0x09,0x05,0xcb,0x29,0x32,
|
||||
0x66,0xb7,0x9a,0x76,0xcd,0x11,0xf3,0x30,
|
||||
@@ -385,6 +455,13 @@ static const struct patch_digest phashes[] = {
|
||||
0xe8,0x73,0xe2,0xd6,0xdb,0xd2,0x77,0x1d,
|
||||
}
|
||||
},
|
||||
{ 0xa60120a, {
|
||||
0x0c,0x8b,0x3d,0xfd,0x52,0x52,0x85,0x7d,
|
||||
0x20,0x3a,0xe1,0x7e,0xa4,0x21,0x3b,0x7b,
|
||||
0x17,0x86,0xae,0xac,0x13,0xb8,0x63,0x9d,
|
||||
0x06,0x01,0xd0,0xa0,0x51,0x9a,0x91,0x2c,
|
||||
}
|
||||
},
|
||||
{ 0xa704107, {
|
||||
0xf3,0xc6,0x58,0x26,0xee,0xac,0x3f,0xd6,
|
||||
0xce,0xa1,0x72,0x47,0x3b,0xba,0x2b,0x93,
|
||||
@@ -392,6 +469,13 @@ static const struct patch_digest phashes[] = {
|
||||
0x64,0x39,0x71,0x8c,0xce,0xe7,0x41,0x39,
|
||||
}
|
||||
},
|
||||
{ 0xa704108, {
|
||||
0xd7,0x55,0x15,0x2b,0xfe,0xc4,0xbc,0x93,
|
||||
0xec,0x91,0xa0,0xae,0x45,0xb7,0xc3,0x98,
|
||||
0x4e,0xff,0x61,0x77,0x88,0xc2,0x70,0x49,
|
||||
0xe0,0x3a,0x1d,0x84,0x38,0x52,0xbf,0x5a,
|
||||
}
|
||||
},
|
||||
{ 0xa705206, {
|
||||
0x8d,0xc0,0x76,0xbd,0x58,0x9f,0x8f,0xa4,
|
||||
0x12,0x9d,0x21,0xfb,0x48,0x21,0xbc,0xe7,
|
||||
@@ -399,6 +483,13 @@ static const struct patch_digest phashes[] = {
|
||||
0x03,0x35,0xe9,0xbe,0xfb,0x06,0xdf,0xfc,
|
||||
}
|
||||
},
|
||||
{ 0xa705208, {
|
||||
0x30,0x1d,0x55,0x24,0xbc,0x6b,0x5a,0x19,
|
||||
0x0c,0x7d,0x1d,0x74,0xaa,0xd1,0xeb,0xd2,
|
||||
0x16,0x62,0xf7,0x5b,0xe1,0x1f,0x18,0x11,
|
||||
0x5c,0xf0,0x94,0x90,0x26,0xec,0x69,0xff,
|
||||
}
|
||||
},
|
||||
{ 0xa708007, {
|
||||
0x6b,0x76,0xcc,0x78,0xc5,0x8a,0xa3,0xe3,
|
||||
0x32,0x2d,0x79,0xe4,0xc3,0x80,0xdb,0xb2,
|
||||
@@ -406,6 +497,13 @@ static const struct patch_digest phashes[] = {
|
||||
0xdf,0x92,0x73,0x84,0x87,0x3c,0x73,0x93,
|
||||
}
|
||||
},
|
||||
{ 0xa708008, {
|
||||
0x08,0x6e,0xf0,0x22,0x4b,0x8e,0xc4,0x46,
|
||||
0x58,0x34,0xe6,0x47,0xa2,0x28,0xfd,0xab,
|
||||
0x22,0x3d,0xdd,0xd8,0x52,0x9e,0x1d,0x16,
|
||||
0xfa,0x01,0x68,0x14,0x79,0x3e,0xe8,0x6b,
|
||||
}
|
||||
},
|
||||
{ 0xa70c005, {
|
||||
0x88,0x5d,0xfb,0x79,0x64,0xd8,0x46,0x3b,
|
||||
0x4a,0x83,0x8e,0x77,0x7e,0xcf,0xb3,0x0f,
|
||||
@@ -413,6 +511,13 @@ static const struct patch_digest phashes[] = {
|
||||
0xee,0x49,0xac,0xe1,0x8b,0x13,0xc5,0x13,
|
||||
}
|
||||
},
|
||||
{ 0xa70c008, {
|
||||
0x0f,0xdb,0x37,0xa1,0x10,0xaf,0xd4,0x21,
|
||||
0x94,0x0d,0xa4,0xa2,0xe9,0x86,0x6c,0x0e,
|
||||
0x85,0x7c,0x36,0x30,0xa3,0x3a,0x78,0x66,
|
||||
0x18,0x10,0x60,0x0d,0x78,0x3d,0x44,0xd0,
|
||||
}
|
||||
},
|
||||
{ 0xaa00116, {
|
||||
0xe8,0x4c,0x2c,0x88,0xa1,0xac,0x24,0x63,
|
||||
0x65,0xe5,0xaa,0x2d,0x16,0xa9,0xc3,0xf5,
|
||||
@@ -441,4 +546,11 @@ static const struct patch_digest phashes[] = {
|
||||
0x68,0x2f,0x46,0xee,0xfe,0xc6,0x6d,0xef,
|
||||
}
|
||||
},
|
||||
{ 0xaa00216, {
|
||||
0x79,0xfb,0x5b,0x9f,0xb6,0xe6,0xa8,0xf5,
|
||||
0x4e,0x7c,0x4f,0x8e,0x1d,0xad,0xd0,0x08,
|
||||
0xc2,0x43,0x7c,0x8b,0xe6,0xdb,0xd0,0xd2,
|
||||
0xe8,0x39,0x26,0xc1,0xe5,0x5a,0x48,0xf1,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -50,6 +50,8 @@ static const struct cpuid_bit cpuid_bits[] = {
|
||||
{ X86_FEATURE_MBA, CPUID_EBX, 6, 0x80000008, 0 },
|
||||
{ X86_FEATURE_SMBA, CPUID_EBX, 2, 0x80000020, 0 },
|
||||
{ X86_FEATURE_BMEC, CPUID_EBX, 3, 0x80000020, 0 },
|
||||
{ X86_FEATURE_TSA_SQ_NO, CPUID_ECX, 1, 0x80000021, 0 },
|
||||
{ X86_FEATURE_TSA_L1_NO, CPUID_ECX, 2, 0x80000021, 0 },
|
||||
{ X86_FEATURE_AMD_WORKLOAD_CLASS, CPUID_EAX, 22, 0x80000021, 0 },
|
||||
{ X86_FEATURE_PERFMON_V2, CPUID_EAX, 0, 0x80000022, 0 },
|
||||
{ X86_FEATURE_AMD_LBR_V2, CPUID_EAX, 1, 0x80000022, 0 },
|
||||
|
||||
@@ -907,16 +907,24 @@ static __init bool prefer_mwait_c1_over_halt(void)
|
||||
*/
|
||||
static __cpuidle void mwait_idle(void)
|
||||
{
|
||||
if (need_resched())
|
||||
return;
|
||||
|
||||
x86_idle_clear_cpu_buffers();
|
||||
|
||||
if (!current_set_polling_and_test()) {
|
||||
const void *addr = ¤t_thread_info()->flags;
|
||||
|
||||
alternative_input("", "clflush (%[addr])", X86_BUG_CLFLUSH_MONITOR, [addr] "a" (addr));
|
||||
__monitor(addr, 0, 0);
|
||||
if (!need_resched()) {
|
||||
__sti_mwait(0, 0);
|
||||
raw_local_irq_disable();
|
||||
}
|
||||
if (need_resched())
|
||||
goto out;
|
||||
|
||||
__sti_mwait(0, 0);
|
||||
raw_local_irq_disable();
|
||||
}
|
||||
|
||||
out:
|
||||
__current_clr_polling();
|
||||
}
|
||||
|
||||
|
||||
@@ -1165,6 +1165,8 @@ void kvm_set_cpu_caps(void)
|
||||
*/
|
||||
SYNTHESIZED_F(LFENCE_RDTSC),
|
||||
/* SmmPgCfgLock */
|
||||
/* 4: Resv */
|
||||
SYNTHESIZED_F(VERW_CLEAR),
|
||||
F(NULL_SEL_CLR_BASE),
|
||||
/* UpperAddressIgnore */
|
||||
F(AUTOIBRS),
|
||||
@@ -1179,6 +1181,11 @@ void kvm_set_cpu_caps(void)
|
||||
F(SRSO_USER_KERNEL_NO),
|
||||
);
|
||||
|
||||
kvm_cpu_cap_init(CPUID_8000_0021_ECX,
|
||||
SYNTHESIZED_F(TSA_SQ_NO),
|
||||
SYNTHESIZED_F(TSA_L1_NO),
|
||||
);
|
||||
|
||||
kvm_cpu_cap_init(CPUID_8000_0022_EAX,
|
||||
F(PERFMON_V2),
|
||||
);
|
||||
@@ -1748,8 +1755,9 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
|
||||
entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
|
||||
break;
|
||||
case 0x80000021:
|
||||
entry->ebx = entry->ecx = entry->edx = 0;
|
||||
entry->ebx = entry->edx = 0;
|
||||
cpuid_entry_override(entry, CPUID_8000_0021_EAX);
|
||||
cpuid_entry_override(entry, CPUID_8000_0021_ECX);
|
||||
break;
|
||||
/* AMD Extended Performance Monitoring and Debug */
|
||||
case 0x80000022: {
|
||||
|
||||
@@ -1979,6 +1979,9 @@ int kvm_hv_vcpu_flush_tlb(struct kvm_vcpu *vcpu)
|
||||
if (entries[i] == KVM_HV_TLB_FLUSHALL_ENTRY)
|
||||
goto out_flush_all;
|
||||
|
||||
if (is_noncanonical_invlpg_address(entries[i], vcpu))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Lower 12 bits of 'address' encode the number of additional
|
||||
* pages to flush.
|
||||
@@ -2001,11 +2004,11 @@ int kvm_hv_vcpu_flush_tlb(struct kvm_vcpu *vcpu)
|
||||
static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc)
|
||||
{
|
||||
struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
|
||||
unsigned long *vcpu_mask = hv_vcpu->vcpu_mask;
|
||||
u64 *sparse_banks = hv_vcpu->sparse_banks;
|
||||
struct kvm *kvm = vcpu->kvm;
|
||||
struct hv_tlb_flush_ex flush_ex;
|
||||
struct hv_tlb_flush flush;
|
||||
DECLARE_BITMAP(vcpu_mask, KVM_MAX_VCPUS);
|
||||
struct kvm_vcpu_hv_tlb_flush_fifo *tlb_flush_fifo;
|
||||
/*
|
||||
* Normally, there can be no more than 'KVM_HV_TLB_FLUSH_FIFO_SIZE'
|
||||
|
||||
@@ -52,6 +52,10 @@
|
||||
/* CPUID level 0x80000022 (EAX) */
|
||||
#define KVM_X86_FEATURE_PERFMON_V2 KVM_X86_FEATURE(CPUID_8000_0022_EAX, 0)
|
||||
|
||||
/* CPUID level 0x80000021 (ECX) */
|
||||
#define KVM_X86_FEATURE_TSA_SQ_NO KVM_X86_FEATURE(CPUID_8000_0021_ECX, 1)
|
||||
#define KVM_X86_FEATURE_TSA_L1_NO KVM_X86_FEATURE(CPUID_8000_0021_ECX, 2)
|
||||
|
||||
struct cpuid_reg {
|
||||
u32 function;
|
||||
u32 index;
|
||||
@@ -82,6 +86,7 @@ static const struct cpuid_reg reverse_cpuid[] = {
|
||||
[CPUID_8000_0022_EAX] = {0x80000022, 0, CPUID_EAX},
|
||||
[CPUID_7_2_EDX] = { 7, 2, CPUID_EDX},
|
||||
[CPUID_24_0_EBX] = { 0x24, 0, CPUID_EBX},
|
||||
[CPUID_8000_0021_ECX] = {0x80000021, 0, CPUID_ECX},
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -121,6 +126,8 @@ static __always_inline u32 __feature_translate(int x86_feature)
|
||||
KVM_X86_TRANSLATE_FEATURE(PERFMON_V2);
|
||||
KVM_X86_TRANSLATE_FEATURE(RRSBA_CTRL);
|
||||
KVM_X86_TRANSLATE_FEATURE(BHI_CTRL);
|
||||
KVM_X86_TRANSLATE_FEATURE(TSA_SQ_NO);
|
||||
KVM_X86_TRANSLATE_FEATURE(TSA_L1_NO);
|
||||
default:
|
||||
return x86_feature;
|
||||
}
|
||||
|
||||
@@ -1971,6 +1971,10 @@ static int sev_check_source_vcpus(struct kvm *dst, struct kvm *src)
|
||||
struct kvm_vcpu *src_vcpu;
|
||||
unsigned long i;
|
||||
|
||||
if (src->created_vcpus != atomic_read(&src->online_vcpus) ||
|
||||
dst->created_vcpus != atomic_read(&dst->online_vcpus))
|
||||
return -EBUSY;
|
||||
|
||||
if (!sev_es_guest(src))
|
||||
return 0;
|
||||
|
||||
@@ -4445,8 +4449,12 @@ static void sev_es_init_vmcb(struct vcpu_svm *svm)
|
||||
* the VMSA will be NULL if this vCPU is the destination for intrahost
|
||||
* migration, and will be copied later.
|
||||
*/
|
||||
if (svm->sev_es.vmsa && !svm->sev_es.snp_has_guest_vmsa)
|
||||
svm->vmcb->control.vmsa_pa = __pa(svm->sev_es.vmsa);
|
||||
if (!svm->sev_es.snp_has_guest_vmsa) {
|
||||
if (svm->sev_es.vmsa)
|
||||
svm->vmcb->control.vmsa_pa = __pa(svm->sev_es.vmsa);
|
||||
else
|
||||
svm->vmcb->control.vmsa_pa = INVALID_PAGE;
|
||||
}
|
||||
|
||||
if (cpu_feature_enabled(X86_FEATURE_ALLOWED_SEV_FEATURES))
|
||||
svm->vmcb->control.allowed_sev_features = sev->vmsa_features |
|
||||
|
||||
@@ -169,6 +169,9 @@ SYM_FUNC_START(__svm_vcpu_run)
|
||||
#endif
|
||||
mov VCPU_RDI(%_ASM_DI), %_ASM_DI
|
||||
|
||||
/* Clobbers EFLAGS.ZF */
|
||||
VM_CLEAR_CPU_BUFFERS
|
||||
|
||||
/* Enter guest mode */
|
||||
3: vmrun %_ASM_AX
|
||||
4:
|
||||
@@ -335,6 +338,9 @@ SYM_FUNC_START(__svm_sev_es_vcpu_run)
|
||||
mov SVM_current_vmcb(%rdi), %rax
|
||||
mov KVM_VMCB_pa(%rax), %rax
|
||||
|
||||
/* Clobbers EFLAGS.ZF */
|
||||
VM_CLEAR_CPU_BUFFERS
|
||||
|
||||
/* Enter guest mode */
|
||||
1: vmrun %rax
|
||||
2:
|
||||
|
||||
@@ -173,6 +173,9 @@ static void td_init_cpuid_entry2(struct kvm_cpuid_entry2 *entry, unsigned char i
|
||||
tdx_clear_unsupported_cpuid(entry);
|
||||
}
|
||||
|
||||
#define TDVMCALLINFO_GET_QUOTE BIT(0)
|
||||
#define TDVMCALLINFO_SETUP_EVENT_NOTIFY_INTERRUPT BIT(1)
|
||||
|
||||
static int init_kvm_tdx_caps(const struct tdx_sys_info_td_conf *td_conf,
|
||||
struct kvm_tdx_capabilities *caps)
|
||||
{
|
||||
@@ -188,6 +191,10 @@ static int init_kvm_tdx_caps(const struct tdx_sys_info_td_conf *td_conf,
|
||||
|
||||
caps->cpuid.nent = td_conf->num_cpuid_config;
|
||||
|
||||
caps->user_tdvmcallinfo_1_r11 =
|
||||
TDVMCALLINFO_GET_QUOTE |
|
||||
TDVMCALLINFO_SETUP_EVENT_NOTIFY_INTERRUPT;
|
||||
|
||||
for (i = 0; i < td_conf->num_cpuid_config; i++)
|
||||
td_init_cpuid_entry2(&caps->cpuid.entries[i], i);
|
||||
|
||||
@@ -1530,6 +1537,27 @@ static int tdx_get_quote(struct kvm_vcpu *vcpu)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tdx_setup_event_notify_interrupt(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct vcpu_tdx *tdx = to_tdx(vcpu);
|
||||
u64 vector = tdx->vp_enter_args.r12;
|
||||
|
||||
if (vector < 32 || vector > 255) {
|
||||
tdvmcall_set_return_code(vcpu, TDVMCALL_STATUS_INVALID_OPERAND);
|
||||
return 1;
|
||||
}
|
||||
|
||||
vcpu->run->exit_reason = KVM_EXIT_TDX;
|
||||
vcpu->run->tdx.flags = 0;
|
||||
vcpu->run->tdx.nr = TDVMCALL_SETUP_EVENT_NOTIFY_INTERRUPT;
|
||||
vcpu->run->tdx.setup_event_notify.ret = TDVMCALL_STATUS_SUBFUNC_UNSUPPORTED;
|
||||
vcpu->run->tdx.setup_event_notify.vector = vector;
|
||||
|
||||
vcpu->arch.complete_userspace_io = tdx_complete_simple;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int handle_tdvmcall(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
switch (tdvmcall_leaf(vcpu)) {
|
||||
@@ -1541,6 +1569,8 @@ static int handle_tdvmcall(struct kvm_vcpu *vcpu)
|
||||
return tdx_get_td_vm_call_info(vcpu);
|
||||
case TDVMCALL_GET_QUOTE:
|
||||
return tdx_get_quote(vcpu);
|
||||
case TDVMCALL_SETUP_EVENT_NOTIFY_INTERRUPT:
|
||||
return tdx_setup_event_notify_interrupt(vcpu);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -7291,7 +7291,7 @@ static noinstr void vmx_vcpu_enter_exit(struct kvm_vcpu *vcpu,
|
||||
vmx_l1d_flush(vcpu);
|
||||
else if (static_branch_unlikely(&cpu_buf_vm_clear) &&
|
||||
kvm_arch_has_assigned_device(vcpu->kvm))
|
||||
mds_clear_cpu_buffers();
|
||||
x86_clear_cpu_buffers();
|
||||
|
||||
vmx_disable_fb_clear(vmx);
|
||||
|
||||
|
||||
@@ -3258,9 +3258,11 @@ int kvm_guest_time_update(struct kvm_vcpu *v)
|
||||
|
||||
/* With all the info we got, fill in the values */
|
||||
|
||||
if (kvm_caps.has_tsc_control)
|
||||
if (kvm_caps.has_tsc_control) {
|
||||
tgt_tsc_khz = kvm_scale_tsc(tgt_tsc_khz,
|
||||
v->arch.l1_tsc_scaling_ratio);
|
||||
tgt_tsc_khz = tgt_tsc_khz ? : 1;
|
||||
}
|
||||
|
||||
if (unlikely(vcpu->hw_tsc_khz != tgt_tsc_khz)) {
|
||||
kvm_get_time_scale(NSEC_PER_SEC, tgt_tsc_khz * 1000LL,
|
||||
|
||||
@@ -1971,8 +1971,19 @@ int kvm_xen_setup_evtchn(struct kvm *kvm,
|
||||
{
|
||||
struct kvm_vcpu *vcpu;
|
||||
|
||||
if (ue->u.xen_evtchn.port >= max_evtchn_port(kvm))
|
||||
return -EINVAL;
|
||||
/*
|
||||
* Don't check for the port being within range of max_evtchn_port().
|
||||
* Userspace can configure what ever targets it likes; events just won't
|
||||
* be delivered if/while the target is invalid, just like userspace can
|
||||
* configure MSIs which target non-existent APICs.
|
||||
*
|
||||
* This allow on Live Migration and Live Update, the IRQ routing table
|
||||
* can be restored *independently* of other things like creating vCPUs,
|
||||
* without imposing an ordering dependency on userspace. In this
|
||||
* particular case, the problematic ordering would be with setting the
|
||||
* Xen 'long mode' flag, which changes max_evtchn_port() to allow 4096
|
||||
* instead of 1024 event channels.
|
||||
*/
|
||||
|
||||
/* We only support 2 level event channels for now */
|
||||
if (ue->u.xen_evtchn.priority != KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL)
|
||||
|
||||
@@ -243,23 +243,10 @@ static int acpi_battery_get_property(struct power_supply *psy,
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CURRENT_NOW:
|
||||
case POWER_SUPPLY_PROP_POWER_NOW:
|
||||
if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN) {
|
||||
if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
|
||||
ret = -ENODEV;
|
||||
break;
|
||||
}
|
||||
|
||||
val->intval = battery->rate_now * 1000;
|
||||
/*
|
||||
* When discharging, the current should be reported as a
|
||||
* negative number as per the power supply class interface
|
||||
* definition.
|
||||
*/
|
||||
if (psp == POWER_SUPPLY_PROP_CURRENT_NOW &&
|
||||
(battery->state & ACPI_BATTERY_STATE_DISCHARGING) &&
|
||||
acpi_battery_handle_discharging(battery)
|
||||
== POWER_SUPPLY_STATUS_DISCHARGING)
|
||||
val->intval = -val->intval;
|
||||
|
||||
else
|
||||
val->intval = battery->rate_now * 1000;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
|
||||
case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
|
||||
|
||||
@@ -602,6 +602,7 @@ CPU_SHOW_VULN_FALLBACK(reg_file_data_sampling);
|
||||
CPU_SHOW_VULN_FALLBACK(ghostwrite);
|
||||
CPU_SHOW_VULN_FALLBACK(old_microcode);
|
||||
CPU_SHOW_VULN_FALLBACK(indirect_target_selection);
|
||||
CPU_SHOW_VULN_FALLBACK(tsa);
|
||||
|
||||
static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL);
|
||||
static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL);
|
||||
@@ -620,6 +621,7 @@ static DEVICE_ATTR(reg_file_data_sampling, 0444, cpu_show_reg_file_data_sampling
|
||||
static DEVICE_ATTR(ghostwrite, 0444, cpu_show_ghostwrite, NULL);
|
||||
static DEVICE_ATTR(old_microcode, 0444, cpu_show_old_microcode, NULL);
|
||||
static DEVICE_ATTR(indirect_target_selection, 0444, cpu_show_indirect_target_selection, NULL);
|
||||
static DEVICE_ATTR(tsa, 0444, cpu_show_tsa, NULL);
|
||||
|
||||
static struct attribute *cpu_root_vulnerabilities_attrs[] = {
|
||||
&dev_attr_meltdown.attr,
|
||||
@@ -639,6 +641,7 @@ static struct attribute *cpu_root_vulnerabilities_attrs[] = {
|
||||
&dev_attr_ghostwrite.attr,
|
||||
&dev_attr_old_microcode.attr,
|
||||
&dev_attr_indirect_target_selection.attr,
|
||||
&dev_attr_tsa.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
@@ -1237,6 +1237,7 @@ void dpm_complete(pm_message_t state)
|
||||
void dpm_resume_end(pm_message_t state)
|
||||
{
|
||||
dpm_resume(state);
|
||||
pm_restore_gfp_mask();
|
||||
dpm_complete(state);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dpm_resume_end);
|
||||
@@ -2176,8 +2177,10 @@ int dpm_suspend_start(pm_message_t state)
|
||||
error = dpm_prepare(state);
|
||||
if (error)
|
||||
dpm_save_failed_step(SUSPEND_PREPARE);
|
||||
else
|
||||
else {
|
||||
pm_restrict_gfp_mask();
|
||||
error = dpm_suspend(state);
|
||||
}
|
||||
|
||||
dpm_show_time(starttime, state, error, "start");
|
||||
return error;
|
||||
|
||||
@@ -64,13 +64,15 @@ static struct page *brd_insert_page(struct brd_device *brd, sector_t sector,
|
||||
|
||||
rcu_read_unlock();
|
||||
page = alloc_page(gfp | __GFP_ZERO | __GFP_HIGHMEM);
|
||||
rcu_read_lock();
|
||||
if (!page)
|
||||
if (!page) {
|
||||
rcu_read_lock();
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
xa_lock(&brd->brd_pages);
|
||||
ret = __xa_cmpxchg(&brd->brd_pages, sector >> PAGE_SECTORS_SHIFT, NULL,
|
||||
page, gfp);
|
||||
rcu_read_lock();
|
||||
if (ret) {
|
||||
xa_unlock(&brd->brd_pages);
|
||||
__free_page(page);
|
||||
|
||||
@@ -2198,9 +2198,7 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
ret = nbd_start_device(nbd);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (info->attrs[NBD_ATTR_BACKEND_IDENTIFIER]) {
|
||||
nbd->backend = nla_strdup(info->attrs[NBD_ATTR_BACKEND_IDENTIFIER],
|
||||
GFP_KERNEL);
|
||||
@@ -2216,6 +2214,8 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)
|
||||
goto out;
|
||||
}
|
||||
set_bit(NBD_RT_HAS_BACKEND_FILE, &config->runtime_flags);
|
||||
|
||||
ret = nbd_start_device(nbd);
|
||||
out:
|
||||
mutex_unlock(&nbd->config_lock);
|
||||
if (!ret) {
|
||||
|
||||
@@ -1442,15 +1442,16 @@ static void ublk_queue_rqs(struct rq_list *rqlist)
|
||||
struct ublk_queue *this_q = req->mq_hctx->driver_data;
|
||||
struct ublk_io *this_io = &this_q->ios[req->tag];
|
||||
|
||||
if (ublk_prep_req(this_q, req, true) != BLK_STS_OK) {
|
||||
rq_list_add_tail(&requeue_list, req);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (io && !ublk_belong_to_same_batch(io, this_io) &&
|
||||
!rq_list_empty(&submit_list))
|
||||
ublk_queue_cmd_list(io, &submit_list);
|
||||
io = this_io;
|
||||
|
||||
if (ublk_prep_req(this_q, req, true) == BLK_STS_OK)
|
||||
rq_list_add_tail(&submit_list, req);
|
||||
else
|
||||
rq_list_add_tail(&requeue_list, req);
|
||||
rq_list_add_tail(&submit_list, req);
|
||||
}
|
||||
|
||||
if (!rq_list_empty(&submit_list))
|
||||
|
||||
@@ -720,11 +720,6 @@ static const struct pci_device_id agp_amd64_pci_table[] = {
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, agp_amd64_pci_table);
|
||||
|
||||
static const struct pci_device_id agp_amd64_pci_promisc_table[] = {
|
||||
{ PCI_DEVICE_CLASS(0, 0) },
|
||||
{ }
|
||||
};
|
||||
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(agp_amd64_pm_ops, NULL, agp_amd64_resume);
|
||||
|
||||
static struct pci_driver agp_amd64_pci_driver = {
|
||||
@@ -739,6 +734,7 @@ static struct pci_driver agp_amd64_pci_driver = {
|
||||
/* Not static due to IOMMU code calling it early. */
|
||||
int __init agp_amd64_init(void)
|
||||
{
|
||||
struct pci_dev *pdev = NULL;
|
||||
int err = 0;
|
||||
|
||||
if (agp_off)
|
||||
@@ -767,9 +763,13 @@ int __init agp_amd64_init(void)
|
||||
}
|
||||
|
||||
/* Look for any AGP bridge */
|
||||
agp_amd64_pci_driver.id_table = agp_amd64_pci_promisc_table;
|
||||
err = driver_attach(&agp_amd64_pci_driver.driver);
|
||||
if (err == 0 && agp_bridges_found == 0) {
|
||||
for_each_pci_dev(pdev)
|
||||
if (pci_find_capability(pdev, PCI_CAP_ID_AGP))
|
||||
pci_add_dynid(&agp_amd64_pci_driver,
|
||||
pdev->vendor, pdev->device,
|
||||
pdev->subsystem_vendor,
|
||||
pdev->subsystem_device, 0, 0, 0);
|
||||
if (agp_bridges_found == 0) {
|
||||
pci_unregister_driver(&agp_amd64_pci_driver);
|
||||
err = -ENODEV;
|
||||
}
|
||||
|
||||
@@ -404,6 +404,7 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
|
||||
const struct scmi_handle *handle = sdev->handle;
|
||||
struct scmi_protocol_handle *ph;
|
||||
const struct clk_ops *scmi_clk_ops_db[SCMI_MAX_CLK_OPS] = {};
|
||||
struct scmi_clk *sclks;
|
||||
|
||||
if (!handle)
|
||||
return -ENODEV;
|
||||
@@ -430,18 +431,21 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
|
||||
transport_is_atomic = handle->is_transport_atomic(handle,
|
||||
&atomic_threshold_us);
|
||||
|
||||
for (idx = 0; idx < count; idx++) {
|
||||
struct scmi_clk *sclk;
|
||||
const struct clk_ops *scmi_ops;
|
||||
sclks = devm_kcalloc(dev, count, sizeof(*sclks), GFP_KERNEL);
|
||||
if (!sclks)
|
||||
return -ENOMEM;
|
||||
|
||||
sclk = devm_kzalloc(dev, sizeof(*sclk), GFP_KERNEL);
|
||||
if (!sclk)
|
||||
return -ENOMEM;
|
||||
for (idx = 0; idx < count; idx++)
|
||||
hws[idx] = &sclks[idx].hw;
|
||||
|
||||
for (idx = 0; idx < count; idx++) {
|
||||
struct scmi_clk *sclk = &sclks[idx];
|
||||
const struct clk_ops *scmi_ops;
|
||||
|
||||
sclk->info = scmi_proto_clk_ops->info_get(ph, idx);
|
||||
if (!sclk->info) {
|
||||
dev_dbg(dev, "invalid clock info for idx %d\n", idx);
|
||||
devm_kfree(dev, sclk);
|
||||
hws[idx] = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -479,13 +483,11 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
|
||||
if (err) {
|
||||
dev_err(dev, "failed to register clock %d\n", idx);
|
||||
devm_kfree(dev, sclk->parent_data);
|
||||
devm_kfree(dev, sclk);
|
||||
hws[idx] = NULL;
|
||||
} else {
|
||||
dev_dbg(dev, "Registered clock:%s%s\n",
|
||||
sclk->info->name,
|
||||
scmi_ops->enable ? " (atomic ops)" : "");
|
||||
hws[idx] = &sclk->hw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -219,11 +219,15 @@ static const struct imx95_blk_ctl_dev_data lvds_csr_dev_data = {
|
||||
.clk_reg_offset = 0,
|
||||
};
|
||||
|
||||
static const char * const disp_engine_parents[] = {
|
||||
"videopll1", "dsi_pll", "ldb_pll_div7"
|
||||
};
|
||||
|
||||
static const struct imx95_blk_ctl_clk_dev_data dispmix_csr_clk_dev_data[] = {
|
||||
[IMX95_CLK_DISPMIX_ENG0_SEL] = {
|
||||
.name = "disp_engine0_sel",
|
||||
.parent_names = (const char *[]){"videopll1", "dsi_pll", "ldb_pll_div7", },
|
||||
.num_parents = 4,
|
||||
.parent_names = disp_engine_parents,
|
||||
.num_parents = ARRAY_SIZE(disp_engine_parents),
|
||||
.reg = 0,
|
||||
.bit_idx = 0,
|
||||
.bit_width = 2,
|
||||
@@ -232,8 +236,8 @@ static const struct imx95_blk_ctl_clk_dev_data dispmix_csr_clk_dev_data[] = {
|
||||
},
|
||||
[IMX95_CLK_DISPMIX_ENG1_SEL] = {
|
||||
.name = "disp_engine1_sel",
|
||||
.parent_names = (const char *[]){"videopll1", "dsi_pll", "ldb_pll_div7", },
|
||||
.num_parents = 4,
|
||||
.parent_names = disp_engine_parents,
|
||||
.num_parents = ARRAY_SIZE(disp_engine_parents),
|
||||
.reg = 0,
|
||||
.bit_idx = 2,
|
||||
.bit_width = 2,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user