mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 11:06:41 -05:00
ASoC: codec: Convert to GPIO descriptors for
Merge series from Peng Fan <peng.fan@nxp.com>: This patchset is a pick up of patch 1,2 from [1]. And I also collect Linus's R-b for patch 2. After this patchset, there is only one user of of_gpio.h left in sound driver(pxa2xx-ac97). of_gpio.h is deprecated, update the driver to use GPIO descriptors. Patch 1 is to drop legacy platform data which in-tree no users are using it Patch 2 is to convert to GPIO descriptors Checking the DTS that use the device, all are using GPIOD_ACTIVE_LOW polarity for reset-gpios, so all should work as expected with this patch. [1] https://lore.kernel.org/all/20250408-asoc-gpio-v1-0-c0db9d3fd6e9@nxp.com/
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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
38
MAINTAINERS
38
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
|
||||
@@ -16822,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
|
||||
@@ -17222,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)
|
||||
@@ -19601,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
|
||||
@@ -20155,21 +20156,15 @@ S: Supported
|
||||
F: Documentation/devicetree/bindings/soc/qcom/qcom,apr*
|
||||
F: Documentation/devicetree/bindings/sound/qcom,*
|
||||
F: drivers/soc/qcom/apr.c
|
||||
F: include/dt-bindings/sound/qcom,wcd9335.h
|
||||
F: include/dt-bindings/sound/qcom,wcd934x.h
|
||||
F: sound/soc/codecs/lpass-rx-macro.*
|
||||
F: sound/soc/codecs/lpass-tx-macro.*
|
||||
F: sound/soc/codecs/lpass-va-macro.c
|
||||
F: sound/soc/codecs/lpass-wsa-macro.*
|
||||
F: drivers/soundwire/qcom.c
|
||||
F: include/dt-bindings/sound/qcom,wcd93*
|
||||
F: sound/soc/codecs/lpass-*.*
|
||||
F: sound/soc/codecs/msm8916-wcd-analog.c
|
||||
F: sound/soc/codecs/msm8916-wcd-digital.c
|
||||
F: sound/soc/codecs/wcd-clsh-v2.*
|
||||
F: sound/soc/codecs/wcd-mbhc-v2.*
|
||||
F: sound/soc/codecs/wcd9335.*
|
||||
F: sound/soc/codecs/wcd934x.c
|
||||
F: sound/soc/codecs/wsa881x.c
|
||||
F: sound/soc/codecs/wsa883x.c
|
||||
F: sound/soc/codecs/wsa884x.c
|
||||
F: sound/soc/codecs/wcd93*.*
|
||||
F: sound/soc/codecs/wsa88*.*
|
||||
F: sound/soc/qcom/
|
||||
|
||||
QCOM EMBEDDED USB DEBUGGER (EUD)
|
||||
@@ -26955,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
|
||||
@@ -27324,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 = -rc5
|
||||
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
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -1236,8 +1236,8 @@ void dpm_complete(pm_message_t state)
|
||||
*/
|
||||
void dpm_resume_end(pm_message_t state)
|
||||
{
|
||||
pm_restore_gfp_mask();
|
||||
dpm_resume(state);
|
||||
pm_restore_gfp_mask();
|
||||
dpm_complete(state);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dpm_resume_end);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -29,14 +29,12 @@ SECTIONS
|
||||
. = _etext;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EFI_SBAT
|
||||
.sbat : ALIGN(4096) {
|
||||
_sbat = .;
|
||||
*(.sbat)
|
||||
_esbat = ALIGN(4096);
|
||||
. = _esbat;
|
||||
}
|
||||
#endif
|
||||
|
||||
.data : ALIGN(4096) {
|
||||
_data = .;
|
||||
@@ -60,6 +58,6 @@ SECTIONS
|
||||
PROVIDE(__efistub__gzdata_size =
|
||||
ABSOLUTE(__efistub__gzdata_end - __efistub__gzdata_start));
|
||||
|
||||
PROVIDE(__data_rawsize = ABSOLUTE(_edata - _etext));
|
||||
PROVIDE(__data_size = ABSOLUTE(_end - _etext));
|
||||
PROVIDE(__data_rawsize = ABSOLUTE(_edata - _data));
|
||||
PROVIDE(__data_size = ABSOLUTE(_end - _data));
|
||||
PROVIDE(__sbat_size = ABSOLUTE(_esbat - _sbat));
|
||||
|
||||
@@ -708,7 +708,7 @@ struct gpio_desc *of_find_gpio(struct device_node *np, const char *con_id,
|
||||
unsigned int idx, unsigned long *flags)
|
||||
{
|
||||
char propname[32]; /* 32 is max size of property name */
|
||||
enum of_gpio_flags of_flags;
|
||||
enum of_gpio_flags of_flags = 0;
|
||||
const of_find_gpio_quirk *q;
|
||||
struct gpio_desc *desc;
|
||||
|
||||
|
||||
@@ -3297,14 +3297,15 @@ static int gpiod_get_raw_value_commit(const struct gpio_desc *desc)
|
||||
static int gpio_chip_get_multiple(struct gpio_chip *gc,
|
||||
unsigned long *mask, unsigned long *bits)
|
||||
{
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&gc->gpiodev->srcu);
|
||||
|
||||
if (gc->get_multiple) {
|
||||
int ret;
|
||||
|
||||
ret = gc->get_multiple(gc, mask, bits);
|
||||
if (ret > 0)
|
||||
return -EBADE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (gc->get) {
|
||||
|
||||
@@ -862,11 +862,23 @@ EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_framebuffer_free);
|
||||
int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
|
||||
const struct drm_framebuffer_funcs *funcs)
|
||||
{
|
||||
unsigned int i;
|
||||
int ret;
|
||||
bool exists;
|
||||
|
||||
if (WARN_ON_ONCE(fb->dev != dev || !fb->format))
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < fb->format->num_planes; i++) {
|
||||
if (drm_WARN_ON_ONCE(dev, fb->internal_flags & DRM_FRAMEBUFFER_HAS_HANDLE_REF(i)))
|
||||
fb->internal_flags &= ~DRM_FRAMEBUFFER_HAS_HANDLE_REF(i);
|
||||
if (fb->obj[i]) {
|
||||
exists = drm_gem_object_handle_get_if_exists_unlocked(fb->obj[i]);
|
||||
if (exists)
|
||||
fb->internal_flags |= DRM_FRAMEBUFFER_HAS_HANDLE_REF(i);
|
||||
}
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&fb->filp_head);
|
||||
|
||||
fb->funcs = funcs;
|
||||
@@ -875,7 +887,7 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
|
||||
ret = __drm_mode_object_add(dev, &fb->base, DRM_MODE_OBJECT_FB,
|
||||
false, drm_framebuffer_free);
|
||||
if (ret)
|
||||
goto out;
|
||||
goto err;
|
||||
|
||||
mutex_lock(&dev->mode_config.fb_lock);
|
||||
dev->mode_config.num_fb++;
|
||||
@@ -883,7 +895,16 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
|
||||
mutex_unlock(&dev->mode_config.fb_lock);
|
||||
|
||||
drm_mode_object_register(dev, &fb->base);
|
||||
out:
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
for (i = 0; i < fb->format->num_planes; i++) {
|
||||
if (fb->internal_flags & DRM_FRAMEBUFFER_HAS_HANDLE_REF(i)) {
|
||||
drm_gem_object_handle_put_unlocked(fb->obj[i]);
|
||||
fb->internal_flags &= ~DRM_FRAMEBUFFER_HAS_HANDLE_REF(i);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_framebuffer_init);
|
||||
@@ -960,6 +981,12 @@ EXPORT_SYMBOL(drm_framebuffer_unregister_private);
|
||||
void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
|
||||
{
|
||||
struct drm_device *dev = fb->dev;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < fb->format->num_planes; i++) {
|
||||
if (fb->internal_flags & DRM_FRAMEBUFFER_HAS_HANDLE_REF(i))
|
||||
drm_gem_object_handle_put_unlocked(fb->obj[i]);
|
||||
}
|
||||
|
||||
mutex_lock(&dev->mode_config.fb_lock);
|
||||
list_del(&fb->head);
|
||||
|
||||
@@ -223,23 +223,34 @@ static void drm_gem_object_handle_get(struct drm_gem_object *obj)
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_gem_object_handle_get_unlocked - acquire reference on user-space handles
|
||||
* drm_gem_object_handle_get_if_exists_unlocked - acquire reference on user-space handle, if any
|
||||
* @obj: GEM object
|
||||
*
|
||||
* Acquires a reference on the GEM buffer object's handle. Required
|
||||
* to keep the GEM object alive. Call drm_gem_object_handle_put_unlocked()
|
||||
* to release the reference.
|
||||
* Acquires a reference on the GEM buffer object's handle. Required to keep
|
||||
* the GEM object alive. Call drm_gem_object_handle_put_if_exists_unlocked()
|
||||
* to release the reference. Does nothing if the buffer object has no handle.
|
||||
*
|
||||
* Returns:
|
||||
* True if a handle exists, or false otherwise
|
||||
*/
|
||||
void drm_gem_object_handle_get_unlocked(struct drm_gem_object *obj)
|
||||
bool drm_gem_object_handle_get_if_exists_unlocked(struct drm_gem_object *obj)
|
||||
{
|
||||
struct drm_device *dev = obj->dev;
|
||||
|
||||
guard(mutex)(&dev->object_name_lock);
|
||||
|
||||
drm_WARN_ON(dev, !obj->handle_count); /* first ref taken in create-tail helper */
|
||||
/*
|
||||
* First ref taken during GEM object creation, if any. Some
|
||||
* drivers set up internal framebuffers with GEM objects that
|
||||
* do not have a GEM handle. Hence, this counter can be zero.
|
||||
*/
|
||||
if (!obj->handle_count)
|
||||
return false;
|
||||
|
||||
drm_gem_object_handle_get(obj);
|
||||
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_gem_object_handle_get_unlocked);
|
||||
|
||||
/**
|
||||
* drm_gem_object_handle_free - release resources bound to userspace handles
|
||||
@@ -272,7 +283,7 @@ static void drm_gem_object_exported_dma_buf_free(struct drm_gem_object *obj)
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_gem_object_handle_put_unlocked - releases reference on user-space handles
|
||||
* drm_gem_object_handle_put_unlocked - releases reference on user-space handle
|
||||
* @obj: GEM object
|
||||
*
|
||||
* Releases a reference on the GEM buffer object's handle. Possibly releases
|
||||
@@ -283,14 +294,14 @@ void drm_gem_object_handle_put_unlocked(struct drm_gem_object *obj)
|
||||
struct drm_device *dev = obj->dev;
|
||||
bool final = false;
|
||||
|
||||
if (WARN_ON(READ_ONCE(obj->handle_count) == 0))
|
||||
if (drm_WARN_ON(dev, READ_ONCE(obj->handle_count) == 0))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Must bump handle count first as this may be the last
|
||||
* ref, in which case the object would disappear before we
|
||||
* checked for a name
|
||||
*/
|
||||
* Must bump handle count first as this may be the last
|
||||
* ref, in which case the object would disappear before
|
||||
* we checked for a name.
|
||||
*/
|
||||
|
||||
mutex_lock(&dev->object_name_lock);
|
||||
if (--obj->handle_count == 0) {
|
||||
@@ -303,7 +314,6 @@ void drm_gem_object_handle_put_unlocked(struct drm_gem_object *obj)
|
||||
if (final)
|
||||
drm_gem_object_put(obj);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_gem_object_handle_put_unlocked);
|
||||
|
||||
/*
|
||||
* Called at device or object close to release the file's
|
||||
@@ -315,6 +325,9 @@ drm_gem_object_release_handle(int id, void *ptr, void *data)
|
||||
struct drm_file *file_priv = data;
|
||||
struct drm_gem_object *obj = ptr;
|
||||
|
||||
if (drm_WARN_ON(obj->dev, !data))
|
||||
return 0;
|
||||
|
||||
if (obj->funcs->close)
|
||||
obj->funcs->close(obj, file_priv);
|
||||
|
||||
@@ -435,7 +448,7 @@ drm_gem_handle_create_tail(struct drm_file *file_priv,
|
||||
idr_preload(GFP_KERNEL);
|
||||
spin_lock(&file_priv->table_lock);
|
||||
|
||||
ret = idr_alloc(&file_priv->object_idr, obj, 1, 0, GFP_NOWAIT);
|
||||
ret = idr_alloc(&file_priv->object_idr, NULL, 1, 0, GFP_NOWAIT);
|
||||
|
||||
spin_unlock(&file_priv->table_lock);
|
||||
idr_preload_end();
|
||||
@@ -456,6 +469,11 @@ drm_gem_handle_create_tail(struct drm_file *file_priv,
|
||||
goto err_revoke;
|
||||
}
|
||||
|
||||
/* mirrors drm_gem_handle_delete to avoid races */
|
||||
spin_lock(&file_priv->table_lock);
|
||||
obj = idr_replace(&file_priv->object_idr, obj, handle);
|
||||
WARN_ON(obj != NULL);
|
||||
spin_unlock(&file_priv->table_lock);
|
||||
*handlep = handle;
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ void drm_gem_fb_destroy(struct drm_framebuffer *fb)
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < fb->format->num_planes; i++)
|
||||
drm_gem_object_handle_put_unlocked(fb->obj[i]);
|
||||
drm_gem_object_put(fb->obj[i]);
|
||||
|
||||
drm_framebuffer_cleanup(fb);
|
||||
kfree(fb);
|
||||
@@ -182,10 +182,8 @@ int drm_gem_fb_init_with_funcs(struct drm_device *dev,
|
||||
if (!objs[i]) {
|
||||
drm_dbg_kms(dev, "Failed to lookup GEM object\n");
|
||||
ret = -ENOENT;
|
||||
goto err_gem_object_handle_put_unlocked;
|
||||
goto err_gem_object_put;
|
||||
}
|
||||
drm_gem_object_handle_get_unlocked(objs[i]);
|
||||
drm_gem_object_put(objs[i]);
|
||||
|
||||
min_size = (height - 1) * mode_cmd->pitches[i]
|
||||
+ drm_format_info_min_pitch(info, i, width)
|
||||
@@ -195,22 +193,22 @@ int drm_gem_fb_init_with_funcs(struct drm_device *dev,
|
||||
drm_dbg_kms(dev,
|
||||
"GEM object size (%zu) smaller than minimum size (%u) for plane %d\n",
|
||||
objs[i]->size, min_size, i);
|
||||
drm_gem_object_handle_put_unlocked(objs[i]);
|
||||
drm_gem_object_put(objs[i]);
|
||||
ret = -EINVAL;
|
||||
goto err_gem_object_handle_put_unlocked;
|
||||
goto err_gem_object_put;
|
||||
}
|
||||
}
|
||||
|
||||
ret = drm_gem_fb_init(dev, fb, mode_cmd, objs, i, funcs);
|
||||
if (ret)
|
||||
goto err_gem_object_handle_put_unlocked;
|
||||
goto err_gem_object_put;
|
||||
|
||||
return 0;
|
||||
|
||||
err_gem_object_handle_put_unlocked:
|
||||
err_gem_object_put:
|
||||
while (i > 0) {
|
||||
--i;
|
||||
drm_gem_object_handle_put_unlocked(objs[i]);
|
||||
drm_gem_object_put(objs[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ void drm_sysfs_lease_event(struct drm_device *dev);
|
||||
|
||||
/* drm_gem.c */
|
||||
int drm_gem_init(struct drm_device *dev);
|
||||
void drm_gem_object_handle_get_unlocked(struct drm_gem_object *obj);
|
||||
bool drm_gem_object_handle_get_if_exists_unlocked(struct drm_gem_object *obj);
|
||||
void drm_gem_object_handle_put_unlocked(struct drm_gem_object *obj);
|
||||
int drm_gem_handle_create_tail(struct drm_file *file_priv,
|
||||
struct drm_gem_object *obj,
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
//! * <https://github.com/erwanvivien/fast_qr>
|
||||
//! * <https://github.com/bjguillot/qr>
|
||||
|
||||
use kernel::{prelude::*, str::CStr};
|
||||
use kernel::prelude::*;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
|
||||
struct Version(usize);
|
||||
|
||||
@@ -1938,7 +1938,7 @@ static int get_init_otp_deassert_fragment_len(struct intel_display *display,
|
||||
int index, len;
|
||||
|
||||
if (drm_WARN_ON(display->drm,
|
||||
!data || panel->vbt.dsi.seq_version != 1))
|
||||
!data || panel->vbt.dsi.seq_version >= 3))
|
||||
return 0;
|
||||
|
||||
/* index = 1 to skip sequence byte */
|
||||
@@ -1961,7 +1961,7 @@ static int get_init_otp_deassert_fragment_len(struct intel_display *display,
|
||||
}
|
||||
|
||||
/*
|
||||
* Some v1 VBT MIPI sequences do the deassert in the init OTP sequence.
|
||||
* Some v1/v2 VBT MIPI sequences do the deassert in the init OTP sequence.
|
||||
* The deassert must be done before calling intel_dsi_device_ready, so for
|
||||
* these devices we split the init OTP sequence into a deassert sequence and
|
||||
* the actual init OTP part.
|
||||
@@ -1972,9 +1972,9 @@ static void vlv_fixup_mipi_sequences(struct intel_display *display,
|
||||
u8 *init_otp;
|
||||
int len;
|
||||
|
||||
/* Limit this to v1 vid-mode sequences */
|
||||
/* Limit this to v1/v2 vid-mode sequences */
|
||||
if (panel->vbt.dsi.config->is_cmd_mode ||
|
||||
panel->vbt.dsi.seq_version != 1)
|
||||
panel->vbt.dsi.seq_version >= 3)
|
||||
return;
|
||||
|
||||
/* Only do this if there are otp and assert seqs and no deassert seq */
|
||||
|
||||
@@ -386,13 +386,13 @@ pvr_power_reset(struct pvr_device *pvr_dev, bool hard_reset)
|
||||
if (!err) {
|
||||
if (hard_reset) {
|
||||
pvr_dev->fw_dev.booted = false;
|
||||
WARN_ON(pm_runtime_force_suspend(from_pvr_device(pvr_dev)->dev));
|
||||
WARN_ON(pvr_power_device_suspend(from_pvr_device(pvr_dev)->dev));
|
||||
|
||||
err = pvr_fw_hard_reset(pvr_dev);
|
||||
if (err)
|
||||
goto err_device_lost;
|
||||
|
||||
err = pm_runtime_force_resume(from_pvr_device(pvr_dev)->dev);
|
||||
err = pvr_power_device_resume(from_pvr_device(pvr_dev)->dev);
|
||||
pvr_dev->fw_dev.booted = true;
|
||||
if (err)
|
||||
goto err_device_lost;
|
||||
|
||||
@@ -314,14 +314,10 @@ nouveau_debugfs_fini(struct nouveau_drm *drm)
|
||||
drm->debugfs = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
nouveau_module_debugfs_init(void)
|
||||
{
|
||||
nouveau_debugfs_root = debugfs_create_dir("nouveau", NULL);
|
||||
if (IS_ERR(nouveau_debugfs_root))
|
||||
return PTR_ERR(nouveau_debugfs_root);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -24,7 +24,7 @@ extern void nouveau_debugfs_fini(struct nouveau_drm *);
|
||||
|
||||
extern struct dentry *nouveau_debugfs_root;
|
||||
|
||||
int nouveau_module_debugfs_init(void);
|
||||
void nouveau_module_debugfs_init(void);
|
||||
void nouveau_module_debugfs_fini(void);
|
||||
#else
|
||||
static inline void
|
||||
@@ -42,10 +42,9 @@ nouveau_debugfs_fini(struct nouveau_drm *drm)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int
|
||||
static inline void
|
||||
nouveau_module_debugfs_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
||||
@@ -1461,9 +1461,7 @@ nouveau_drm_init(void)
|
||||
if (!nouveau_modeset)
|
||||
return 0;
|
||||
|
||||
ret = nouveau_module_debugfs_init();
|
||||
if (ret)
|
||||
return ret;
|
||||
nouveau_module_debugfs_init();
|
||||
|
||||
#ifdef CONFIG_NOUVEAU_PLATFORM_DRIVER
|
||||
platform_driver_register(&nouveau_platform_driver);
|
||||
|
||||
@@ -719,7 +719,6 @@ r535_gsp_acpi_caps(acpi_handle handle, CAPS_METHOD_DATA *caps)
|
||||
union acpi_object argv4 = {
|
||||
.buffer.type = ACPI_TYPE_BUFFER,
|
||||
.buffer.length = 4,
|
||||
.buffer.pointer = kmalloc(argv4.buffer.length, GFP_KERNEL),
|
||||
}, *obj;
|
||||
|
||||
caps->status = 0xffff;
|
||||
@@ -727,17 +726,22 @@ r535_gsp_acpi_caps(acpi_handle handle, CAPS_METHOD_DATA *caps)
|
||||
if (!acpi_check_dsm(handle, &NVOP_DSM_GUID, NVOP_DSM_REV, BIT_ULL(0x1a)))
|
||||
return;
|
||||
|
||||
argv4.buffer.pointer = kmalloc(argv4.buffer.length, GFP_KERNEL);
|
||||
if (!argv4.buffer.pointer)
|
||||
return;
|
||||
|
||||
obj = acpi_evaluate_dsm(handle, &NVOP_DSM_GUID, NVOP_DSM_REV, 0x1a, &argv4);
|
||||
if (!obj)
|
||||
return;
|
||||
goto done;
|
||||
|
||||
if (WARN_ON(obj->type != ACPI_TYPE_BUFFER) ||
|
||||
WARN_ON(obj->buffer.length != 4))
|
||||
return;
|
||||
goto done;
|
||||
|
||||
caps->status = 0;
|
||||
caps->optimusCaps = *(u32 *)obj->buffer.pointer;
|
||||
|
||||
done:
|
||||
ACPI_FREE(obj);
|
||||
|
||||
kfree(argv4.buffer.pointer);
|
||||
@@ -754,24 +758,28 @@ r535_gsp_acpi_jt(acpi_handle handle, JT_METHOD_DATA *jt)
|
||||
union acpi_object argv4 = {
|
||||
.buffer.type = ACPI_TYPE_BUFFER,
|
||||
.buffer.length = sizeof(caps),
|
||||
.buffer.pointer = kmalloc(argv4.buffer.length, GFP_KERNEL),
|
||||
}, *obj;
|
||||
|
||||
jt->status = 0xffff;
|
||||
|
||||
argv4.buffer.pointer = kmalloc(argv4.buffer.length, GFP_KERNEL);
|
||||
if (!argv4.buffer.pointer)
|
||||
return;
|
||||
|
||||
obj = acpi_evaluate_dsm(handle, &JT_DSM_GUID, JT_DSM_REV, 0x1, &argv4);
|
||||
if (!obj)
|
||||
return;
|
||||
goto done;
|
||||
|
||||
if (WARN_ON(obj->type != ACPI_TYPE_BUFFER) ||
|
||||
WARN_ON(obj->buffer.length != 4))
|
||||
return;
|
||||
goto done;
|
||||
|
||||
jt->status = 0;
|
||||
jt->jtCaps = *(u32 *)obj->buffer.pointer;
|
||||
jt->jtRevId = (jt->jtCaps & 0xfff00000) >> 20;
|
||||
jt->bSBIOSCaps = 0;
|
||||
|
||||
done:
|
||||
ACPI_FREE(obj);
|
||||
|
||||
kfree(argv4.buffer.pointer);
|
||||
@@ -1744,6 +1752,13 @@ r535_gsp_fini(struct nvkm_gsp *gsp, bool suspend)
|
||||
nvkm_gsp_sg_free(gsp->subdev.device, &gsp->sr.sgt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Debug the GSP firmware / RPC handling to find out why
|
||||
* without this Turing (but none of the other architectures)
|
||||
* ends up resetting all channels after resume.
|
||||
*/
|
||||
msleep(50);
|
||||
}
|
||||
|
||||
ret = r535_gsp_rpc_unloading_guest_driver(gsp, suspend);
|
||||
|
||||
@@ -261,10 +261,8 @@ static int nvdec_load_falcon_firmware(struct nvdec *nvdec)
|
||||
|
||||
if (!client->group) {
|
||||
virt = dma_alloc_coherent(nvdec->dev, size, &iova, GFP_KERNEL);
|
||||
|
||||
err = dma_mapping_error(nvdec->dev, iova);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (!virt)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
virt = tegra_drm_alloc(tegra, size, &iova);
|
||||
if (IS_ERR(virt))
|
||||
|
||||
@@ -171,14 +171,32 @@ static void xe_devcoredump_snapshot_free(struct xe_devcoredump_snapshot *ss)
|
||||
|
||||
#define XE_DEVCOREDUMP_CHUNK_MAX (SZ_512M + SZ_1G)
|
||||
|
||||
/**
|
||||
* xe_devcoredump_read() - Read data from the Xe device coredump snapshot
|
||||
* @buffer: Destination buffer to copy the coredump data into
|
||||
* @offset: Offset in the coredump data to start reading from
|
||||
* @count: Number of bytes to read
|
||||
* @data: Pointer to the xe_devcoredump structure
|
||||
* @datalen: Length of the data (unused)
|
||||
*
|
||||
* Reads a chunk of the coredump snapshot data into the provided buffer.
|
||||
* If the devcoredump is smaller than 1.5 GB (XE_DEVCOREDUMP_CHUNK_MAX),
|
||||
* it is read directly from a pre-written buffer. For larger devcoredumps,
|
||||
* the pre-written buffer must be periodically repopulated from the snapshot
|
||||
* state due to kmalloc size limitations.
|
||||
*
|
||||
* Return: Number of bytes copied on success, or a negative error code on failure.
|
||||
*/
|
||||
static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
|
||||
size_t count, void *data, size_t datalen)
|
||||
{
|
||||
struct xe_devcoredump *coredump = data;
|
||||
struct xe_devcoredump_snapshot *ss;
|
||||
ssize_t byte_copied;
|
||||
ssize_t byte_copied = 0;
|
||||
u32 chunk_offset;
|
||||
ssize_t new_chunk_position;
|
||||
bool pm_needed = false;
|
||||
int ret = 0;
|
||||
|
||||
if (!coredump)
|
||||
return -ENODEV;
|
||||
@@ -188,20 +206,19 @@ static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
|
||||
/* Ensure delayed work is captured before continuing */
|
||||
flush_work(&ss->work);
|
||||
|
||||
if (ss->read.size > XE_DEVCOREDUMP_CHUNK_MAX)
|
||||
pm_needed = ss->read.size > XE_DEVCOREDUMP_CHUNK_MAX;
|
||||
if (pm_needed)
|
||||
xe_pm_runtime_get(gt_to_xe(ss->gt));
|
||||
|
||||
mutex_lock(&coredump->lock);
|
||||
|
||||
if (!ss->read.buffer) {
|
||||
mutex_unlock(&coredump->lock);
|
||||
return -ENODEV;
|
||||
ret = -ENODEV;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (offset >= ss->read.size) {
|
||||
mutex_unlock(&coredump->lock);
|
||||
return 0;
|
||||
}
|
||||
if (offset >= ss->read.size)
|
||||
goto unlock;
|
||||
|
||||
new_chunk_position = div_u64_rem(offset,
|
||||
XE_DEVCOREDUMP_CHUNK_MAX,
|
||||
@@ -221,12 +238,13 @@ static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
|
||||
ss->read.size - offset;
|
||||
memcpy(buffer, ss->read.buffer + chunk_offset, byte_copied);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&coredump->lock);
|
||||
|
||||
if (ss->read.size > XE_DEVCOREDUMP_CHUNK_MAX)
|
||||
if (pm_needed)
|
||||
xe_pm_runtime_put(gt_to_xe(ss->gt));
|
||||
|
||||
return byte_copied;
|
||||
return byte_copied ? byte_copied : ret;
|
||||
}
|
||||
|
||||
static void xe_devcoredump_free(void *data)
|
||||
|
||||
@@ -444,6 +444,7 @@ static int xe_alloc_pf_queue(struct xe_gt *gt, struct pf_queue *pf_queue)
|
||||
#define PF_MULTIPLIER 8
|
||||
pf_queue->num_dw =
|
||||
(num_eus + XE_NUM_HW_ENGINES) * PF_MSG_LEN_DW * PF_MULTIPLIER;
|
||||
pf_queue->num_dw = roundup_pow_of_two(pf_queue->num_dw);
|
||||
#undef PF_MULTIPLIER
|
||||
|
||||
pf_queue->gt = gt;
|
||||
|
||||
@@ -78,6 +78,9 @@ static struct xe_lmtt_pt *lmtt_pt_alloc(struct xe_lmtt *lmtt, unsigned int level
|
||||
}
|
||||
|
||||
lmtt_assert(lmtt, xe_bo_is_vram(bo));
|
||||
lmtt_debug(lmtt, "level=%u addr=%#llx\n", level, (u64)xe_bo_main_addr(bo, XE_PAGE_SIZE));
|
||||
|
||||
xe_map_memset(lmtt_to_xe(lmtt), &bo->vmap, 0, 0, bo->size);
|
||||
|
||||
pt->level = level;
|
||||
pt->bo = bo;
|
||||
@@ -91,6 +94,9 @@ static struct xe_lmtt_pt *lmtt_pt_alloc(struct xe_lmtt *lmtt, unsigned int level
|
||||
|
||||
static void lmtt_pt_free(struct xe_lmtt_pt *pt)
|
||||
{
|
||||
lmtt_debug(&pt->bo->tile->sriov.pf.lmtt, "level=%u addr=%llx\n",
|
||||
pt->level, (u64)xe_bo_main_addr(pt->bo, XE_PAGE_SIZE));
|
||||
|
||||
xe_bo_unpin_map_no_vm(pt->bo);
|
||||
kfree(pt);
|
||||
}
|
||||
@@ -226,9 +232,14 @@ static void lmtt_write_pte(struct xe_lmtt *lmtt, struct xe_lmtt_pt *pt,
|
||||
|
||||
switch (lmtt->ops->lmtt_pte_size(level)) {
|
||||
case sizeof(u32):
|
||||
lmtt_assert(lmtt, !overflows_type(pte, u32));
|
||||
lmtt_assert(lmtt, !pte || !iosys_map_rd(&pt->bo->vmap, idx * sizeof(u32), u32));
|
||||
|
||||
xe_map_wr(lmtt_to_xe(lmtt), &pt->bo->vmap, idx * sizeof(u32), u32, pte);
|
||||
break;
|
||||
case sizeof(u64):
|
||||
lmtt_assert(lmtt, !pte || !iosys_map_rd(&pt->bo->vmap, idx * sizeof(u64), u64));
|
||||
|
||||
xe_map_wr(lmtt_to_xe(lmtt), &pt->bo->vmap, idx * sizeof(u64), u64, pte);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -863,7 +863,7 @@ struct dma_fence *xe_migrate_copy(struct xe_migrate *m,
|
||||
if (src_is_vram && xe_migrate_allow_identity(src_L0, &src_it))
|
||||
xe_res_next(&src_it, src_L0);
|
||||
else
|
||||
emit_pte(m, bb, src_L0_pt, src_is_vram, copy_system_ccs,
|
||||
emit_pte(m, bb, src_L0_pt, src_is_vram, copy_system_ccs || use_comp_pat,
|
||||
&src_it, src_L0, src);
|
||||
|
||||
if (dst_is_vram && xe_migrate_allow_identity(src_L0, &dst_it))
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
struct xe_modparam xe_modparam = {
|
||||
.probe_display = true,
|
||||
.guc_log_level = 3,
|
||||
.guc_log_level = IS_ENABLED(CONFIG_DRM_XE_DEBUG) ? 3 : 1,
|
||||
.force_probe = CONFIG_DRM_XE_FORCE_PROBE,
|
||||
.wedged_mode = 1,
|
||||
.svm_notifier_size = 512,
|
||||
|
||||
@@ -140,7 +140,6 @@ static const struct xe_graphics_desc graphics_xelpg = {
|
||||
.has_asid = 1, \
|
||||
.has_atomic_enable_pte_bit = 1, \
|
||||
.has_flat_ccs = 1, \
|
||||
.has_indirect_ring_state = 1, \
|
||||
.has_range_tlb_invalidation = 1, \
|
||||
.has_usm = 1, \
|
||||
.has_64bit_timestamp = 1, \
|
||||
|
||||
@@ -134,7 +134,7 @@ int xe_pm_suspend(struct xe_device *xe)
|
||||
/* FIXME: Super racey... */
|
||||
err = xe_bo_evict_all(xe);
|
||||
if (err)
|
||||
goto err_pxp;
|
||||
goto err_display;
|
||||
|
||||
for_each_gt(gt, xe, id) {
|
||||
err = xe_gt_suspend(gt);
|
||||
@@ -151,7 +151,6 @@ int xe_pm_suspend(struct xe_device *xe)
|
||||
|
||||
err_display:
|
||||
xe_display_pm_resume(xe);
|
||||
err_pxp:
|
||||
xe_pxp_pm_resume(xe->pxp);
|
||||
err:
|
||||
drm_dbg(&xe->drm, "Device suspend failed %d\n", err);
|
||||
@@ -753,11 +752,13 @@ void xe_pm_assert_unbounded_bridge(struct xe_device *xe)
|
||||
}
|
||||
|
||||
/**
|
||||
* xe_pm_set_vram_threshold - Set a vram threshold for allowing/blocking D3Cold
|
||||
* xe_pm_set_vram_threshold - Set a VRAM threshold for allowing/blocking D3Cold
|
||||
* @xe: xe device instance
|
||||
* @threshold: VRAM size in bites for the D3cold threshold
|
||||
* @threshold: VRAM size in MiB for the D3cold threshold
|
||||
*
|
||||
* Returns 0 for success, negative error code otherwise.
|
||||
* Return:
|
||||
* * 0 - success
|
||||
* * -EINVAL - invalid argument
|
||||
*/
|
||||
int xe_pm_set_vram_threshold(struct xe_device *xe, u32 threshold)
|
||||
{
|
||||
|
||||
@@ -114,10 +114,10 @@ struct fw_blobs_by_type {
|
||||
#define XE_GT_TYPE_ANY XE_GT_TYPE_UNINITIALIZED
|
||||
|
||||
#define XE_GUC_FIRMWARE_DEFS(fw_def, mmp_ver, major_ver) \
|
||||
fw_def(BATTLEMAGE, GT_TYPE_ANY, major_ver(xe, guc, bmg, 70, 44, 1)) \
|
||||
fw_def(LUNARLAKE, GT_TYPE_ANY, major_ver(xe, guc, lnl, 70, 44, 1)) \
|
||||
fw_def(BATTLEMAGE, GT_TYPE_ANY, major_ver(xe, guc, bmg, 70, 45, 2)) \
|
||||
fw_def(LUNARLAKE, GT_TYPE_ANY, major_ver(xe, guc, lnl, 70, 45, 2)) \
|
||||
fw_def(METEORLAKE, GT_TYPE_ANY, major_ver(i915, guc, mtl, 70, 44, 1)) \
|
||||
fw_def(DG2, GT_TYPE_ANY, major_ver(i915, guc, dg2, 70, 44, 1)) \
|
||||
fw_def(DG2, GT_TYPE_ANY, major_ver(i915, guc, dg2, 70, 45, 2)) \
|
||||
fw_def(DG1, GT_TYPE_ANY, major_ver(i915, guc, dg1, 70, 44, 1)) \
|
||||
fw_def(ALDERLAKE_N, GT_TYPE_ANY, major_ver(i915, guc, tgl, 70, 44, 1)) \
|
||||
fw_def(ALDERLAKE_P, GT_TYPE_ANY, major_ver(i915, guc, adlp, 70, 44, 1)) \
|
||||
|
||||
@@ -38,10 +38,10 @@
|
||||
GRAPHICS_VERSION(2004)
|
||||
GRAPHICS_VERSION_RANGE(3000, 3001)
|
||||
22019338487 MEDIA_VERSION(2000)
|
||||
GRAPHICS_VERSION(2001)
|
||||
GRAPHICS_VERSION(2001), FUNC(xe_rtp_match_not_sriov_vf)
|
||||
MEDIA_VERSION(3000), MEDIA_STEP(A0, B0), FUNC(xe_rtp_match_not_sriov_vf)
|
||||
22019338487_display PLATFORM(LUNARLAKE)
|
||||
16023588340 GRAPHICS_VERSION(2001)
|
||||
16023588340 GRAPHICS_VERSION(2001), FUNC(xe_rtp_match_not_sriov_vf)
|
||||
14019789679 GRAPHICS_VERSION(1255)
|
||||
GRAPHICS_VERSION_RANGE(1270, 2004)
|
||||
no_media_l3 MEDIA_VERSION(3000)
|
||||
|
||||
@@ -2366,8 +2366,7 @@ static int bitmap_get_stats(void *data, struct md_bitmap_stats *stats)
|
||||
|
||||
if (!bitmap)
|
||||
return -ENOENT;
|
||||
if (!bitmap->mddev->bitmap_info.external &&
|
||||
!bitmap->storage.sb_page)
|
||||
if (!bitmap->storage.sb_page)
|
||||
return -EINVAL;
|
||||
sb = kmap_local_page(bitmap->storage.sb_page);
|
||||
stats->sync_size = le64_to_cpu(sb->sync_size);
|
||||
|
||||
@@ -1399,7 +1399,7 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
|
||||
}
|
||||
read_bio = bio_alloc_clone(mirror->rdev->bdev, bio, gfp,
|
||||
&mddev->bio_set);
|
||||
|
||||
read_bio->bi_opf &= ~REQ_NOWAIT;
|
||||
r1_bio->bios[rdisk] = read_bio;
|
||||
|
||||
read_bio->bi_iter.bi_sector = r1_bio->sector +
|
||||
@@ -1649,6 +1649,7 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
|
||||
wait_for_serialization(rdev, r1_bio);
|
||||
}
|
||||
|
||||
mbio->bi_opf &= ~REQ_NOWAIT;
|
||||
r1_bio->bios[i] = mbio;
|
||||
|
||||
mbio->bi_iter.bi_sector = (r1_bio->sector + rdev->data_offset);
|
||||
@@ -3428,6 +3429,7 @@ static int raid1_reshape(struct mddev *mddev)
|
||||
/* ok, everything is stopped */
|
||||
oldpool = conf->r1bio_pool;
|
||||
conf->r1bio_pool = newpool;
|
||||
init_waitqueue_head(&conf->r1bio_pool.wait);
|
||||
|
||||
for (d = d2 = 0; d < conf->raid_disks; d++) {
|
||||
struct md_rdev *rdev = conf->mirrors[d].rdev;
|
||||
|
||||
@@ -1182,8 +1182,11 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
|
||||
}
|
||||
}
|
||||
|
||||
if (!regular_request_wait(mddev, conf, bio, r10_bio->sectors))
|
||||
if (!regular_request_wait(mddev, conf, bio, r10_bio->sectors)) {
|
||||
raid_end_bio_io(r10_bio);
|
||||
return;
|
||||
}
|
||||
|
||||
rdev = read_balance(conf, r10_bio, &max_sectors);
|
||||
if (!rdev) {
|
||||
if (err_rdev) {
|
||||
@@ -1221,6 +1224,7 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
|
||||
r10_bio->master_bio = bio;
|
||||
}
|
||||
read_bio = bio_alloc_clone(rdev->bdev, bio, gfp, &mddev->bio_set);
|
||||
read_bio->bi_opf &= ~REQ_NOWAIT;
|
||||
|
||||
r10_bio->devs[slot].bio = read_bio;
|
||||
r10_bio->devs[slot].rdev = rdev;
|
||||
@@ -1256,6 +1260,7 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
|
||||
conf->mirrors[devnum].rdev;
|
||||
|
||||
mbio = bio_alloc_clone(rdev->bdev, bio, GFP_NOIO, &mddev->bio_set);
|
||||
mbio->bi_opf &= ~REQ_NOWAIT;
|
||||
if (replacement)
|
||||
r10_bio->devs[n_copy].repl_bio = mbio;
|
||||
else
|
||||
@@ -1370,8 +1375,11 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio,
|
||||
}
|
||||
|
||||
sectors = r10_bio->sectors;
|
||||
if (!regular_request_wait(mddev, conf, bio, sectors))
|
||||
if (!regular_request_wait(mddev, conf, bio, sectors)) {
|
||||
raid_end_bio_io(r10_bio);
|
||||
return;
|
||||
}
|
||||
|
||||
if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
|
||||
(mddev->reshape_backwards
|
||||
? (bio->bi_iter.bi_sector < conf->reshape_safe &&
|
||||
|
||||
@@ -665,7 +665,7 @@ static int m_can_handle_lost_msg(struct net_device *dev)
|
||||
struct can_frame *frame;
|
||||
u32 timestamp = 0;
|
||||
|
||||
netdev_err(dev, "msg lost in rxf0\n");
|
||||
netdev_dbg(dev, "msg lost in rxf0\n");
|
||||
|
||||
stats->rx_errors++;
|
||||
stats->rx_over_errors++;
|
||||
|
||||
@@ -2984,6 +2984,7 @@ static int airoha_probe(struct platform_device *pdev)
|
||||
error_napi_stop:
|
||||
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
|
||||
airoha_qdma_stop_napi(ð->qdma[i]);
|
||||
airoha_ppe_deinit(eth);
|
||||
error_hw_cleanup:
|
||||
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
|
||||
airoha_hw_cleanup(ð->qdma[i]);
|
||||
|
||||
@@ -11607,11 +11607,9 @@ static void bnxt_free_irq(struct bnxt *bp)
|
||||
|
||||
static int bnxt_request_irq(struct bnxt *bp)
|
||||
{
|
||||
struct cpu_rmap *rmap = NULL;
|
||||
int i, j, rc = 0;
|
||||
unsigned long flags = 0;
|
||||
#ifdef CONFIG_RFS_ACCEL
|
||||
struct cpu_rmap *rmap;
|
||||
#endif
|
||||
|
||||
rc = bnxt_setup_int_mode(bp);
|
||||
if (rc) {
|
||||
@@ -11632,15 +11630,15 @@ static int bnxt_request_irq(struct bnxt *bp)
|
||||
int map_idx = bnxt_cp_num_to_irq_num(bp, i);
|
||||
struct bnxt_irq *irq = &bp->irq_tbl[map_idx];
|
||||
|
||||
#ifdef CONFIG_RFS_ACCEL
|
||||
if (rmap && bp->bnapi[i]->rx_ring) {
|
||||
if (IS_ENABLED(CONFIG_RFS_ACCEL) &&
|
||||
rmap && bp->bnapi[i]->rx_ring) {
|
||||
rc = irq_cpu_rmap_add(rmap, irq->vector);
|
||||
if (rc)
|
||||
netdev_warn(bp->dev, "failed adding irq rmap for ring %d\n",
|
||||
j);
|
||||
j++;
|
||||
}
|
||||
#endif
|
||||
|
||||
rc = request_irq(irq->vector, irq->handler, flags, irq->name,
|
||||
bp->bnapi[i]);
|
||||
if (rc)
|
||||
|
||||
@@ -368,23 +368,27 @@ static u32 bnxt_get_ctx_coredump(struct bnxt *bp, void *buf, u32 offset,
|
||||
if (!ctxm->mem_valid || !seg_id)
|
||||
continue;
|
||||
|
||||
if (trace)
|
||||
if (trace) {
|
||||
extra_hlen = BNXT_SEG_RCD_LEN;
|
||||
if (buf) {
|
||||
u16 trace_type = bnxt_bstore_to_trace[type];
|
||||
|
||||
bnxt_fill_drv_seg_record(bp, &record, ctxm,
|
||||
trace_type);
|
||||
}
|
||||
}
|
||||
|
||||
if (buf)
|
||||
data = buf + BNXT_SEG_HDR_LEN + extra_hlen;
|
||||
|
||||
seg_len = bnxt_copy_ctx_mem(bp, ctxm, data, 0) + extra_hlen;
|
||||
if (buf) {
|
||||
bnxt_fill_coredump_seg_hdr(bp, &seg_hdr, NULL, seg_len,
|
||||
0, 0, 0, comp_id, seg_id);
|
||||
memcpy(buf, &seg_hdr, BNXT_SEG_HDR_LEN);
|
||||
buf += BNXT_SEG_HDR_LEN;
|
||||
if (trace) {
|
||||
u16 trace_type = bnxt_bstore_to_trace[type];
|
||||
|
||||
bnxt_fill_drv_seg_record(bp, &record, ctxm,
|
||||
trace_type);
|
||||
if (trace)
|
||||
memcpy(buf, &record, BNXT_SEG_RCD_LEN);
|
||||
}
|
||||
buf += seg_len;
|
||||
}
|
||||
len += BNXT_SEG_HDR_LEN + seg_len;
|
||||
|
||||
@@ -487,7 +487,9 @@ static int bnxt_ets_validate(struct bnxt *bp, struct ieee_ets *ets, u8 *tc)
|
||||
|
||||
if ((ets->tc_tx_bw[i] || ets->tc_tsa[i]) && i > bp->max_tc)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < max_tc; i++) {
|
||||
switch (ets->tc_tsa[i]) {
|
||||
case IEEE_8021QAZ_TSA_STRICT:
|
||||
break;
|
||||
|
||||
@@ -115,7 +115,7 @@ static void __bnxt_xmit_xdp_redirect(struct bnxt *bp,
|
||||
tx_buf->action = XDP_REDIRECT;
|
||||
tx_buf->xdpf = xdpf;
|
||||
dma_unmap_addr_set(tx_buf, mapping, mapping);
|
||||
dma_unmap_len_set(tx_buf, len, 0);
|
||||
dma_unmap_len_set(tx_buf, len, len);
|
||||
}
|
||||
|
||||
void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int budget)
|
||||
|
||||
@@ -4092,6 +4092,12 @@ static int bcmgenet_probe(struct platform_device *pdev)
|
||||
for (i = 0; i <= priv->hw_params->rx_queues; i++)
|
||||
priv->rx_rings[i].rx_max_coalesced_frames = 1;
|
||||
|
||||
/* Initialize u64 stats seq counter for 32bit machines */
|
||||
for (i = 0; i <= priv->hw_params->rx_queues; i++)
|
||||
u64_stats_init(&priv->rx_rings[i].stats64.syncp);
|
||||
for (i = 0; i <= priv->hw_params->tx_queues; i++)
|
||||
u64_stats_init(&priv->tx_rings[i].stats64.syncp);
|
||||
|
||||
/* libphy will determine the link state */
|
||||
netif_carrier_off(dev);
|
||||
|
||||
|
||||
@@ -1578,7 +1578,6 @@ int nicvf_open(struct net_device *netdev)
|
||||
static int nicvf_change_mtu(struct net_device *netdev, int new_mtu)
|
||||
{
|
||||
struct nicvf *nic = netdev_priv(netdev);
|
||||
int orig_mtu = netdev->mtu;
|
||||
|
||||
/* For now just support only the usual MTU sized frames,
|
||||
* plus some headroom for VLAN, QinQ.
|
||||
@@ -1589,15 +1588,10 @@ static int nicvf_change_mtu(struct net_device *netdev, int new_mtu)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
WRITE_ONCE(netdev->mtu, new_mtu);
|
||||
|
||||
if (!netif_running(netdev))
|
||||
return 0;
|
||||
|
||||
if (nicvf_update_hw_max_frs(nic, new_mtu)) {
|
||||
netdev->mtu = orig_mtu;
|
||||
if (netif_running(netdev) && nicvf_update_hw_max_frs(nic, new_mtu))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
WRITE_ONCE(netdev->mtu, new_mtu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -211,7 +211,6 @@ struct ibmvnic_statistics {
|
||||
u8 reserved[72];
|
||||
} __packed __aligned(8);
|
||||
|
||||
#define NUM_TX_STATS 3
|
||||
struct ibmvnic_tx_queue_stats {
|
||||
u64 batched_packets;
|
||||
u64 direct_packets;
|
||||
@@ -219,13 +218,18 @@ struct ibmvnic_tx_queue_stats {
|
||||
u64 dropped_packets;
|
||||
};
|
||||
|
||||
#define NUM_RX_STATS 3
|
||||
#define NUM_TX_STATS \
|
||||
(sizeof(struct ibmvnic_tx_queue_stats) / sizeof(u64))
|
||||
|
||||
struct ibmvnic_rx_queue_stats {
|
||||
u64 packets;
|
||||
u64 bytes;
|
||||
u64 interrupts;
|
||||
};
|
||||
|
||||
#define NUM_RX_STATS \
|
||||
(sizeof(struct ibmvnic_rx_queue_stats) / sizeof(u64))
|
||||
|
||||
struct ibmvnic_acl_buffer {
|
||||
__be32 len;
|
||||
__be32 version;
|
||||
|
||||
@@ -18,7 +18,8 @@ enum {
|
||||
|
||||
enum {
|
||||
MLX5E_TC_PRIO = 0,
|
||||
MLX5E_NIC_PRIO
|
||||
MLX5E_PROMISC_PRIO,
|
||||
MLX5E_NIC_PRIO,
|
||||
};
|
||||
|
||||
struct mlx5e_flow_table {
|
||||
@@ -68,9 +69,13 @@ struct mlx5e_l2_table {
|
||||
MLX5_HASH_FIELD_SEL_DST_IP |\
|
||||
MLX5_HASH_FIELD_SEL_IPSEC_SPI)
|
||||
|
||||
/* NIC prio FTS */
|
||||
/* NIC promisc FT level */
|
||||
enum {
|
||||
MLX5E_PROMISC_FT_LEVEL,
|
||||
};
|
||||
|
||||
/* NIC prio FTS */
|
||||
enum {
|
||||
MLX5E_VLAN_FT_LEVEL,
|
||||
MLX5E_L2_FT_LEVEL,
|
||||
MLX5E_TTC_FT_LEVEL,
|
||||
|
||||
@@ -113,7 +113,7 @@ int mlx5e_dim_rx_change(struct mlx5e_rq *rq, bool enable)
|
||||
__set_bit(MLX5E_RQ_STATE_DIM, &rq->state);
|
||||
} else {
|
||||
__clear_bit(MLX5E_RQ_STATE_DIM, &rq->state);
|
||||
|
||||
synchronize_net();
|
||||
mlx5e_dim_disable(rq->dim);
|
||||
rq->dim = NULL;
|
||||
}
|
||||
@@ -140,7 +140,7 @@ int mlx5e_dim_tx_change(struct mlx5e_txqsq *sq, bool enable)
|
||||
__set_bit(MLX5E_SQ_STATE_DIM, &sq->state);
|
||||
} else {
|
||||
__clear_bit(MLX5E_SQ_STATE_DIM, &sq->state);
|
||||
|
||||
synchronize_net();
|
||||
mlx5e_dim_disable(sq->dim);
|
||||
sq->dim = NULL;
|
||||
}
|
||||
|
||||
@@ -780,7 +780,7 @@ static int mlx5e_create_promisc_table(struct mlx5e_flow_steering *fs)
|
||||
ft_attr.max_fte = MLX5E_PROMISC_TABLE_SIZE;
|
||||
ft_attr.autogroup.max_num_groups = 1;
|
||||
ft_attr.level = MLX5E_PROMISC_FT_LEVEL;
|
||||
ft_attr.prio = MLX5E_NIC_PRIO;
|
||||
ft_attr.prio = MLX5E_PROMISC_PRIO;
|
||||
|
||||
ft->t = mlx5_create_auto_grouped_flow_table(fs->ns, &ft_attr);
|
||||
if (IS_ERR(ft->t)) {
|
||||
|
||||
@@ -1076,6 +1076,7 @@ static int esw_qos_vports_node_update_parent(struct mlx5_esw_sched_node *node,
|
||||
return err;
|
||||
}
|
||||
esw_qos_node_set_parent(node, parent);
|
||||
node->bw_share = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user