Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

Cross-merge networking fixes after downstream PR (net-7.3-rc5).

Conflicts:

drivers/net/mdio/mdio-realtek-rtl9300.c
  89a8a1eef2 ("net: mdio: realtek-rtl9300: fix RTL931x C22 extended page selection")
  cc3cb8db1e ("net: mdio: realtek-rtl9300: Add page tracking")
https://lore.kernel.org/arUZOqy73bE2pp0w@sirena.org.uk

net/8021q/vlan_dev.c
  cd5dd68267 ("vlan: ensure sufficient headroom in vlan_dev_hard_header()")
  ca6ff8dd70 ("vlan: annotate data-races in vlan_dev_priv fields")

Adjacent changes:

net/ipv6/ip6_gre.c
  dd47bcf279 ("ip6_gre: Call ip6erspan_tunnel_unlink_md() in ip6erspan_changelink().")
  cce829e2aa ("ip6_gre: Protect ip6gre_net.tunnels[][] with mutex.")

drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
  b5d9e9d4d0 ("eth: fbnic: use the Rx queue napi pointer to find the napi vector")
  c0aca269ec ("eth: fbnic: Make Rx completion coalescing configurable")

drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
  d68acbf935 ("net: stmmac: selftests: Support running selftests on DSA conduits")
  85ca3292d7 ("net: stmmac: Remove ARP offload code")

drivers/net/ethernet/wangxun/libwx/wx_hw.c
  3173cba117 ("net: libwx: fix races in Tx timestamp handling")
  7042c8c193 ("net: libwx: rename wx_pf_flags to wx_flags")

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2026-09-17 14:24:32 -07:00
commit 42a9fb3382
613 changed files with 10615 additions and 3214 deletions

View File

@ -357,6 +357,8 @@ Hans Verkuil <hverkuil@kernel.org> <hverkuil-cisco@xs4all.nl>
Hans Verkuil <hverkuil@kernel.org> <hansverk@cisco.com>
Hans Verkuil <hverkuil@kernel.org> <hans.verkuil@cisco.com>
Hao Ge <hao.ge@linux.dev> <gehao@kylinos.cn>
Haowen Bai <baihaowen88@gmail.com> <baihaowen@meizu.com>
Haowen Bai <baihaowen88@gmail.com> <calvin.bai@ugreen.com>
Harry Yoo <harry.yoo@oracle.com> <42.hyeyoo@gmail.com>
Harry Yoo <harry@kernel.org> <harry.yoo@oracle.com>
Heiko Carstens <hca@linux.ibm.com> <h.carstens@de.ibm.com>
@ -982,6 +984,7 @@ Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@virtuozzo.com>
Vlastimil Babka <vbabka@kernel.org> <vbabka@suse.cz>
WangYuli <wangyuli@aosc.io> <wangyl5933@chinaunicom.cn>
WangYuli <wangyuli@aosc.io> <wangyuli@deepin.org>
Wei Wang <weiwan@google.com> <weibunny@fb.com>
Weiwen Hu <huweiwen@linux.alibaba.com> <sehuww@mail.scut.edu.cn>
WeiXiong Liao <gmpy.liaowx@gmail.com> <liaoweixiong@allwinnertech.com>
Wen Gong <quic_wgong@quicinc.com> <wgong@codeaurora.org>
@ -989,6 +992,8 @@ Wesley Cheng <quic_wcheng@quicinc.com> <wcheng@codeaurora.org>
Will Deacon <will@kernel.org> <will.deacon@arm.com>
Wolfram Sang <wsa@kernel.org> <w.sang@pengutronix.de>
Wolfram Sang <wsa@kernel.org> <wsa@the-dreams.de>
Xu Xin <xu.xin@linux.dev> <xu.xin16@zte.com.cn>
Xu Xin <xu.xin@linux.dev> xu xin <cgel.zte@gmail.com>
Yakir Yang <kuankuan.y@gmail.com> <ykk@rock-chips.com>
Yanteng Si <si.yanteng@linux.dev> <siyanteng@loongson.cn>
Ying Huang <huang.ying.caritas@gmail.com> <ying.huang@intel.com>

View File

@ -5,7 +5,7 @@ Contact: linux-input@vger.kernel.org
Description:
(RW) Trackpoint sensitivity.
What: /sys/devices/platform/i8042/.../intertia
What: /sys/devices/platform/i8042/.../inertia
Date: Aug, 2005
KernelVersion: 2.6.14
Contact: linux-input@vger.kernel.org

View File

@ -589,6 +589,9 @@ Kernel parameters
arm64.nosve [ARM64] Unconditionally disable Scalable Vector
Extension support
arm64.nowfxt [ARM64] Unconditionally disable Wait For Event with
Timeout and Wait For Interrupt with Timeout support
ataflop= [HW,M68k]
atarimouse= [HW,MOUSE] Atari Mouse

View File

@ -465,6 +465,7 @@ Before jumping into the kernel, the following conditions must be met:
- HDFGWTR2_EL2.nPMICNTR_EL0 (bit 2) must be initialised to 0b1.
- HDFGWTR2_EL2.nPMICFILTR_EL0 (bit 3) must be initialised to 0b1.
- HDFGWTR2_EL2.nPMUACR_EL1 (bit 4) must be initialised to 0b1.
- HDFGWTR2_EL2.nPMZR_EL0 (bit 21) must be initialised to 0b1.
For CPUs with SPE data source filtering (FEAT_SPE_FDS):

View File

@ -208,11 +208,10 @@ will use the corresponding aligned address.
tracer's space cannot be accessed or does not have valid tags.
- ``-EPERM`` - the specified process cannot be traced.
- ``-EIO`` - the tracee's address range cannot be accessed (e.g. invalid
address) and no tags copied. ``iov_len`` not updated.
address) or does not have valid tags (not mapped with the ``PROT_MTE``
flag) and no tags copied. ``iov_len`` not updated.
- ``-EFAULT`` - fault on accessing the tracer's memory (``struct iovec``
or ``iov_base`` buffer) and no tags copied. ``iov_len`` not updated.
- ``-EOPNOTSUPP`` - the tracee's address does not have valid tags (never
mapped with the ``PROT_MTE`` flag). ``iov_len`` not updated.
**Note**: There are no transient errors for the requests above, so user
programs should not retry in case of a non-zero system call return.

View File

@ -486,6 +486,16 @@ Example usage in BPF program:
/* note that the last argument is omitted */
bpf_task_work_schedule_signal(task, &work->tw, &arrmap, task_work_callback);
2.5.10 KF_PERFMON flag
----------------------
The KF_PERFMON flag is used for kfuncs that can expose kernel memory or kernel
addresses to the BPF program, for example by reading through a pointer that the
verifier does not check. Calling such a kfunc requires CAP_PERFMON, or
CAP_SYS_ADMIN, in the same way that the equivalent BPF helpers are gated in
bpf_base_func_proto(). A program loaded with CAP_BPF alone is rejected at load
time.
2.6 Registering the kfuncs
--------------------------

View File

@ -150,7 +150,7 @@ examples:
reg = <0>;
dpu_intf0_out: endpoint {
remote-endpoint = <&mdss_dp0_in>;
remote-endpoint = <&mdss_dp0_in>;
};
};
@ -352,9 +352,9 @@ examples:
};
port@1 {
reg = <1>;
reg = <1>;
mdss_dp_out: endpoint { };
mdss_dp_out: endpoint { };
};
};

View File

@ -248,9 +248,9 @@ examples:
remote-endpoint = <&usb_dp_qmpphy_dp_in>;
};
};
};
};
dp_opp_table: opp-table {
dp_opp_table: opp-table {
compatible = "operating-points-v2";
opp-162000000 {

View File

@ -81,7 +81,7 @@ examples:
port@1 {
reg = <1>;
dpu_intf1_out: endpoint {
remote-endpoint = <&mdss_dsi0_in>;
remote-endpoint = <&mdss_dsi0_in>;
};
};
};
@ -90,18 +90,18 @@ examples:
compatible = "operating-points-v2";
opp-19200000 {
opp-hz = /bits/ 64 <19200000>;
required-opps = <&rpmhpd_opp_low_svs>;
opp-hz = /bits/ 64 <19200000>;
required-opps = <&rpmhpd_opp_low_svs>;
};
opp-25600000 {
opp-hz = /bits/ 64 <25600000>;
required-opps = <&rpmhpd_opp_svs>;
opp-hz = /bits/ 64 <25600000>;
required-opps = <&rpmhpd_opp_svs>;
};
opp-307200000 {
opp-hz = /bits/ 64 <307200000>;
required-opps = <&rpmhpd_opp_nom>;
opp-hz = /bits/ 64 <307200000>;
required-opps = <&rpmhpd_opp_nom>;
};
};
};

View File

@ -223,7 +223,7 @@ examples:
phys = <&mdss_dsi0_phy>;
ports {
#address-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
port@0 {

View File

@ -208,47 +208,47 @@ examples:
#sound-dai-cells = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
port@0 {
reg = <0>;
mdss_dp0_in: endpoint {
remote-endpoint = <&mdss_intf0_out>;
};
};
mdss_dp0_in: endpoint {
remote-endpoint = <&mdss_intf0_out>;
};
};
port@1 {
reg = <1>;
port@1 {
reg = <1>;
mdss_dp0_out: endpoint {
};
};
mdss_dp0_out: endpoint {
};
};
};
mdss_dp0_opp_table: opp-table {
compatible = "operating-points-v2";
compatible = "operating-points-v2";
opp-160000000 {
opp-hz = /bits/ 64 <160000000>;
required-opps = <&rpmhpd_opp_low_svs>;
};
opp-160000000 {
opp-hz = /bits/ 64 <160000000>;
required-opps = <&rpmhpd_opp_low_svs>;
};
opp-270000000 {
opp-hz = /bits/ 64 <270000000>;
required-opps = <&rpmhpd_opp_svs>;
};
opp-270000000 {
opp-hz = /bits/ 64 <270000000>;
required-opps = <&rpmhpd_opp_svs>;
};
opp-540000000 {
opp-hz = /bits/ 64 <540000000>;
required-opps = <&rpmhpd_opp_svs_l1>;
};
opp-540000000 {
opp-hz = /bits/ 64 <540000000>;
required-opps = <&rpmhpd_opp_svs_l1>;
};
opp-810000000 {
opp-hz = /bits/ 64 <810000000>;
required-opps = <&rpmhpd_opp_nom>;
};
opp-810000000 {
opp-hz = /bits/ 64 <810000000>;
required-opps = <&rpmhpd_opp_nom>;
};
};
};
};

View File

@ -26,6 +26,7 @@ properties:
- const: mediatek,mt6779-keypad
- items:
- enum:
- mediatek,mt6572-keypad
- mediatek,mt6873-keypad
- mediatek,mt8183-keypad
- mediatek,mt8365-keypad

View File

@ -67,7 +67,7 @@ $defs:
Specify the alternative function to be configured for the specified
pins.
enum: [ aoss_cti, atest_char, atest_usb20, atest_usb21,
enum: [ gpio, aoss_cti, atest_char, atest_usb20, atest_usb21,
aud_intfc0_clk, aud_intfc0_data, aud_intfc0_ws,
aud_intfc10_clk, aud_intfc10_data, aud_intfc10_ws,
aud_intfc1_clk, aud_intfc1_data, aud_intfc1_ws,
@ -98,9 +98,10 @@ $defs:
pcie3_clk_req_n, phase_flag, pll_bist_sync, pll_clk_aux,
prng_rosc0, prng_rosc1, pwrbrk_i_n, qdss, qdss_cti, qspi,
qup0_se0, qup0_se1, qup0_se2, qup0_se3, qup0_se4, qup0_se5,
qup1_se0, qup1_se1, qup1_se3, qup1_se2, qup1_se4, qup1_se5,
qup1_se0, qup1_se1, qup1_se2_01, qup1_se2_23, qup1_se3_01,
qup1_se3_23, qup1_se4, qup1_se5,
qup1_se6, qup2_se0, qup2_se1, qup2_se2, qup2_se3, qup2_se4,
qup2_se5, qup2_se6,
qup2_se5, qup2_se6, qup3_se0_mira, qup3_se0_mirb,
sailss_ospi, sdc4_clk, sdc4_cmd, sdc4_data, smb_alert,
smb_alert_n, smb_clk, smb_dat, tb_trig_sdc4, tmess_prng0,
tmess_prng1, tsc_timer, tsense_pwm, usb0_hs,

View File

@ -28,34 +28,44 @@ system.
Name Description
============= ======================
temp1_input CPU temperature
temp2_input Box temperature
temp2_input Case temperature
temp3_input Ambient temperature
temp4_input Board temperature
temp5_input Carrier temperature
temp6_input Chipset temperature
temp7_input Video temperature
temp4_input CPU Board temperature
temp5_input Carrier Board temperature
temp6_input System Chipset temperature
temp7_input Video Controller/Board temperature
temp8_input Other temperature
temp9_input TOPDIM temperature
temp10_input BOTTOMDIM temperature
in0_input CPU voltage
temp9_input Top DIMM 0 temperature
temp10_input Bottom DIMM 0 temperature
temp11_input Alternate Board temperature
temp12_input Top DIMM 1 temperature
temp13_input Top DIMM 2 temperature
temp14_input Top DIMM 3 temperature
temp15_input Top DIMM 4 temperature
temp16_input Top DIMM 5 temperature
temp17_input Top DIMM 6 temperature
temp18_input Top DIMM 7 temperature
temp19_input Bottom DIMM 1 temperature
in0_input CPU Core voltage
in1_input DC Runtime voltage
in2_input DC Standby voltage
in3_input CMOS Battery voltage
in4_input Battery voltage
in4_input Battery Supply voltage
in5_input AC voltage
in6_input Other voltage
in7_input 5V voltage
in7_input 5V Runtime voltage
in8_input 5V Standby voltage
in9_input 3V3 voltage
in9_input 3V3 Runtime voltage
in10_input 3V3 Standby voltage
in11_input VCore A voltage
in12_input VCore B voltage
in13_input 12V voltage
curr1_input DC current
curr2_input 5V current
curr3_input 12V current
in13_input 12V Runtime voltage
in14_input 12V Standby voltage
curr1_input DC Runtime current
curr2_input 5V Runtime current
curr3_input 12V Runtime current
fan1_input CPU fan
fan2_input Box fan
fan2_input Case fan
fan3_input Ambient fan
fan4_input Chiptset fan
fan5_input Video fan

View File

@ -852,6 +852,8 @@ operations:
name: bind-tx
doc: Bind dmabuf to netdev for TX
attribute-set: dmabuf
# Intentionally unprivileged (no admin-perm / uns-admin-perm); see
# comment above netdev_nl_bind_tx_doit().
do:
request:
attributes:

View File

@ -6,7 +6,7 @@ Landlock Trace Events
=====================
:Author: Mickaël Salaün
:Date: August 2026
:Date: September 2026
Landlock emits trace events for sandbox lifecycle operations and access
denials. These events can be consumed by ftrace (for human-readable
@ -31,8 +31,8 @@ Landlock trace events are organized in four categories:
**Syscall events** are emitted during Landlock system calls:
- ``landlock_create_ruleset``: a new ruleset is created
- ``landlock_add_rule_fs``: a filesystem rule is added to a ruleset
- ``landlock_add_rule_net``: a network port rule is added to a ruleset
- ``landlock_add_rule_path_beneath``: a filesystem rule is added to a ruleset
- ``landlock_add_rule_net_port``: a network port rule is added to a ruleset
- ``landlock_create_domain``: a new domain is created from a ruleset
- ``landlock_enforce_domain``: a domain is enforced on a thread
@ -47,8 +47,8 @@ Landlock trace events are organized in four categories:
**Rule evaluation events** are emitted during rule matching:
- ``landlock_check_rule_fs``: a filesystem rule is evaluated
- ``landlock_check_rule_net``: a network port rule is evaluated
- ``landlock_check_rule_inode``: an inode-keyed rule is evaluated
- ``landlock_check_rule_net_port``: a network-port-keyed rule is evaluated
**Lifecycle events**:
@ -141,10 +141,10 @@ in some field formats:
treated as untrusted input and escaped in the trace text output so it
cannot inject field separators or control characters.
- **Other party's domain**: A scope or ptrace denial compares the
subject's denying domain (``domain=``, always the enforcing domain and
never the current task) with the other party's domain, so these
tracepoints also report the other party's domain as a scalar ID:
- **Other party's domain**: A scope or ptrace denial compares the subject's
denying domain (``domain=``), which is the enforcing domain and not
necessarily the current task's domain, with the other party's domain.
These tracepoints also report the other party's domain as a scalar ID:
``tracee_domain=`` (ptrace), ``target_domain=`` (signal), and
``peer_domain=`` (abstract unix socket). It is ``0`` when the other
party is unsandboxed, and otherwise a domain ID that a consumer resolves
@ -189,7 +189,7 @@ rather than the caller's, so correlate those to the syscall by domain ID.
Interpreting check_rule events
==============================
The ``check_rule_fs`` and ``check_rule_net`` events expose the per-layer
The ``check_rule_inode`` and ``check_rule_net_port`` events expose the per-layer
rule evaluation, which is useful for understanding *why* a specific
access is allowed or denied.
@ -231,9 +231,10 @@ contribution, not the final decision:
through another matching rule, or the right is denied and appears in the
``blockers=`` field of the corresponding ``deny_access`` event.
To reconstruct the decision for an object, aggregate the ``grants=``
groups of all ``check_rule`` events emitted for that object during the
check.
For an access check that a consumer can delimit, aggregate the ``grants=``
groups of all matching ``check_rule`` events. These events do not carry a
request ID; use their execution context and generic tracepoints to separate
concurrent or successive checks of the same object.
.. note::
@ -244,29 +245,31 @@ check.
For example, a program sandboxed with read and execute access to the
whole filesystem reads ``/etc/passwd``; both the ``execve()`` and the
read match the rule covering ``/`` (inode 2), so ``check_rule_fs`` fires
read match the rule covering ``/`` (inode 2), so ``check_rule_inode`` fires
with the requested rights intersected against what that rule grants.
The ``access_request=`` mask includes ``truncate`` because the file-open hook
evaluates that optional right alongside the required access, but the
rule does not grant it, so ``truncate`` never appears in ``grants=``::
cat-127 [...] landlock_check_rule_fs: domain=1e40cb56f access_request=execute|read_file|truncate dev=0:17 ino=2 grants={execute|read_file}
cat-127 [...] landlock_check_rule_fs: domain=1e40cb56f access_request=read_file|truncate dev=0:17 ino=2 grants={read_file}
cat-127 [...] landlock_check_rule_inode: domain=1e40cb56f access_request=execute|read_file|truncate dev=0:17 ino=2 grants={execute|read_file}
cat-127 [...] landlock_check_rule_inode: domain=1e40cb56f access_request=read_file|truncate dev=0:17 ino=2 grants={read_file}
The ``[...]`` replaces the ftrace CPU, flags, and timestamp columns. A
single ``grants=`` group means the enforcing domain has one layer. With
two nested sandboxes that each grant the same rights, the rule spans both
layers, so ``grants=`` has one group per layer::
cat-128 [...] landlock_check_rule_fs: domain=184788b52 access_request=execute|read_file|truncate dev=0:17 ino=2 grants={execute|read_file,execute|read_file}
cat-128 [...] landlock_check_rule_fs: domain=184788b52 access_request=read_file|truncate dev=0:17 ino=2 grants={read_file,read_file}
cat-128 [...] landlock_check_rule_inode: domain=184788b52 access_request=execute|read_file|truncate dev=0:17 ino=2 grants={execute|read_file,execute|read_file}
cat-128 [...] landlock_check_rule_inode: domain=184788b52 access_request=read_file|truncate dev=0:17 ino=2 grants={read_file,read_file}
eBPF access
===========
eBPF programs attached via ``BPF_RAW_TRACEPOINT`` can access the
tracepoint arguments directly through BTF. The arguments include both
standard kernel objects and Landlock-internal objects:
BTF-enabled raw tracepoint programs attached through libbpf
``SEC("tp_btf/...")`` sections receive typed callback arguments. The
event prototypes in `Event reference`_ document their argument layouts.
The arguments include both standard kernel objects and Landlock-internal
objects:
- Standard kernel objects (``struct task_struct``, ``struct sock``,
``struct path``, ``struct dentry``) can be used with existing BPF
@ -277,7 +280,7 @@ standard kernel objects and Landlock-internal objects:
Internal struct layouts may change between kernel versions; use CO-RE
for field relocation.
A stateful eBPF program observes the full event stream and maintains
A stateful eBPF program attached before sandbox construction can maintain
per-domain state in BPF maps:
1. On ``landlock_create_domain``: record the domain ID and parent (the
@ -293,7 +296,10 @@ per-domain state in BPF maps:
final statistics.
This approach requires no kernel modification and no Landlock-specific
BPF helpers. The Landlock IDs serve as correlation keys across events.
BPF helpers. Landlock IDs serve as correlation keys within one boot.
Records exported through tracing or BPF buffers can be lost, and records
from different CPUs are not globally ordered, so consumers must detect and
reconcile incomplete state.
Audit filtering equivalence
===========================

View File

@ -5454,6 +5454,7 @@ F: include/linux/brcmphy.h
BROADCOM GENET ETHERNET DRIVER
M: Doug Berger <opendmb@gmail.com>
M: Florian Fainelli <florian.fainelli@broadcom.com>
M: Nicolai Buchwitz <nb@tipi-net.de>
R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
L: netdev@vger.kernel.org
S: Maintained
@ -9325,6 +9326,7 @@ F: Documentation/devicetree/bindings/interrupt-controller/econet,en751221-intc.y
F: Documentation/devicetree/bindings/mips/econet.yaml
F: Documentation/devicetree/bindings/timer/econet,en751221-timer.yaml
F: arch/mips/boot/dts/econet/
F: arch/mips/configs/econet_en751221_defconfig
F: arch/mips/econet/
F: drivers/clocksource/timer-econet-en751221.c
F: drivers/irqchip/irq-econet-en751221.c
@ -17194,7 +17196,7 @@ F: tools/testing/selftests/mm/gup_test.c
MEMORY MANAGEMENT - KSM (Kernel Samepage Merging)
M: Andrew Morton <akpm@linux-foundation.org>
M: David Hildenbrand <david@kernel.org>
R: Xu Xin <xu.xin16@zte.com.cn>
R: Xu Xin <xu.xin@linux.dev>
R: Chengming Zhou <chengming.zhou@linux.dev>
L: linux-mm@kvack.org
S: Maintained
@ -17242,6 +17244,8 @@ R: Barry Song <baohua@kernel.org>
R: Axel Rasmussen <axelrasmussen@google.com>
R: Yuanchu Xie <yuanchu@google.com>
R: Wei Xu <weixugc@google.com>
R: Baoquan He <baoquan.he@linux.dev>
R: Baolin Wang <baolin.wang@linux.alibaba.com>
L: linux-mm@kvack.org
S: Maintained
W: http://www.linux-mm.org

View File

@ -2,7 +2,7 @@
VERSION = 7
PATCHLEVEL = 3
SUBLEVEL = 0
EXTRAVERSION = -rc3
EXTRAVERSION = -rc4
NAME = Baby Opossum Posse
# *DOCUMENTATION*

View File

@ -16,7 +16,7 @@ menuconfig ARCH_INTEL_SOCFPGA
select ARM_ERRATA_775420
select PL310_ERRATA_588369
select PL310_ERRATA_727915
select PL310_ERRATA_753970 if PL310
select PL310_ERRATA_753970
select PL310_ERRATA_769419
select RESET_CONTROLLER

View File

View File

View File

@ -33,7 +33,7 @@ xtal: xtal-clk {
};
&uart_a {
clocks = <&xtal>, <&xtal>, <&xtal>;
clocks = <&xtal>, <&clkc_periphs CLKID_SYS_UART_A>, <&xtal>;
clock-names = "xtal", "pclk", "baud";
status = "okay";
};

View File

@ -71,7 +71,6 @@ sd_3v3: regulator-sdcard-3v3 {
vin-supply = <&vddao_3v3>;
gpio = <&gpio GPIOD_11 GPIO_ACTIVE_LOW>;
regulator-boot-on;
regulator-always-on;
};
sdio_pwrseq: sdio-pwrseq {
@ -105,6 +104,66 @@ vcc5v0_usb: regulator-vcc-usb {
enable-active-high;
};
vdd_ddr: regulator-vddddr {
/*
* SY8003ADFC Regulator.
*/
compatible = "pwm-regulator";
regulator-name = "VDDDDR";
regulator-min-microvolt = <690000>;
regulator-max-microvolt = <890000>;
pwm-supply = <&dc_in>;
pwms = <&pwm_ao_gh 0 1500 0>;
pwm-dutycycle-range = <100 0>;
regulator-boot-on;
regulator-always-on;
};
vdd_ee: regulator-vddee {
/*
* MP8756GD Regulator.
*/
compatible = "pwm-regulator";
regulator-name = "VDDEE";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <922000>;
pwm-supply = <&dc_in>;
pwms = <&pwm_ao_ab 0 1500 0>;
pwm-dutycycle-range = <100 0>;
regulator-boot-on;
regulator-always-on;
};
vdd_gpu: regulator-vddgpu {
/*
* SY8003ADFC Regulator.
*/
compatible = "pwm-regulator";
regulator-name = "VDDGPU";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <922000>;
pwm-supply = <&dc_in>;
pwms = <&pwm_ao_ef 0 1500 0>;
pwm-dutycycle-range = <100 0>;
regulator-boot-on;
regulator-always-on;
};
vdd_npu: regulator-vddnpu {
/*
* SY8003ADFC Regulator.
*/
compatible = "pwm-regulator";
regulator-name = "VDDNPU";
regulator-min-microvolt = <733000>;
regulator-max-microvolt = <933000>;
pwm-supply = <&dc_in>;
pwms = <&pwm_ao_ef 1 1500 0>;
pwm-dutycycle-range = <100 0>;
regulator-boot-on;
regulator-always-on;
};
vddao_1v8: regulator-vddao-1v8 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_1V8";
@ -123,6 +182,36 @@ vddao_3v3: regulator-vddao-3v3 {
regulator-always-on;
};
vddcpu_a: regulator-vddcpu-a {
/*
* MP8756GD Regulator.
*/
compatible = "pwm-regulator";
regulator-name = "VDDCPU_A";
regulator-min-microvolt = <689000>;
regulator-max-microvolt = <1049000>;
pwm-supply = <&dc_in>;
pwms = <&pwm_ao_cd 1 1500 0>;
pwm-dutycycle-range = <100 0>;
regulator-boot-on;
regulator-always-on;
};
vddcpu_b: regulator-vddcpu-b {
/*
* MP8756GD Regulator.
*/
compatible = "pwm-regulator";
regulator-name = "VDDCPU_B";
regulator-min-microvolt = <689000>;
regulator-max-microvolt = <1049000>;
pwm-supply = <&dc_in>;
pwms = <&pwm_ao_ab 1 1500 0>;
pwm-dutycycle-range = <100 0>;
regulator-boot-on;
regulator-always-on;
};
vddio_1v8: regulator-vddio-1v8 {
compatible = "regulator-fixed";
regulator-name = "VDDIO_1V8";
@ -173,9 +262,27 @@ &pwm_ab {
pinctrl-names = "default";
};
&pwm_ao_ab {
status = "okay";
pinctrl-0 = <&pwm_ao_a_pins>, <&pwm_ao_b_pins>;
pinctrl-names = "default";
};
&pwm_ao_cd {
status = "okay";
pinctrl-0 = <&pwm_ao_c_d_pins>;
pinctrl-0 = <&pwm_ao_c_d_pins>, <&pwm_ao_d_pins>;
pinctrl-names = "default";
};
&pwm_ao_ef {
status = "okay";
pinctrl-0 = <&pwm_ao_e_pins>, <&pwm_ao_f_pins>;
pinctrl-names = "default";
};
&pwm_ao_gh {
status = "okay";
pinctrl-0 = <&pwm_ao_g_e_pins>;
pinctrl-names = "default";
};
@ -266,6 +373,6 @@ &sd_emmc_c {
&uart_a {
status = "okay";
clocks = <&xtal>, <&xtal>, <&xtal>;
clocks = <&xtal>, <&clkc_periphs CLKID_SYS_UART_A>, <&xtal>;
clock-names = "xtal", "pclk", "baud";
};

View File

@ -458,9 +458,25 @@ mux {
};
};
pwm_ao_g_pins: pwm-ao-g {
pwm_ao_g_d11_pins: pwm-ao-g-d11 {
mux {
groups = "pwm_ao_g";
groups = "pwm_ao_g_d11";
function = "pwm_ao_g";
bias-disable;
};
};
pwm_ao_g_d7_pins: pwm-ao-g-d7 {
mux {
groups = "pwm_ao_g_d7";
function = "pwm_ao_g";
bias-disable;
};
};
pwm_ao_g_e_pins: pwm-ao-g-e {
mux {
groups = "pwm_ao_g_e";
function = "pwm_ao_g";
bias-disable;
};
@ -474,9 +490,17 @@ mux {
};
};
pwm_ao_h_pins: pwm-ao-h {
pwm_ao_h_d5_pins: pwm-ao-h-d5 {
mux {
groups = "pwm_ao_h";
groups = "pwm_ao_h_d5";
function = "pwm_ao_h";
bias-disable;
};
};
pwm_ao_h_d10_pins: pwm-ao-h-d10 {
mux {
groups = "pwm_ao_h_d10";
function = "pwm_ao_h";
bias-disable;
};
@ -522,9 +546,17 @@ mux {
};
};
pwm_vs_pins: pwm-vs {
pwm_vs_y_pins: pwm-vs-y {
mux {
groups = "pwm_vs";
groups = "pwm_vs_y";
function = "pwm_vs";
bias-disable;
};
};
pwm_vs_h_pins: pwm-vs-h {
mux {
groups = "pwm_vs_h";
function = "pwm_vs";
bias-disable;
};

View File

@ -901,6 +901,7 @@ ufs: ufs@e6860000 {
clocks = <&cpg CPG_MOD 1514>, <&ufs30_clk>;
clock-names = "fck", "ref_clk";
freq-table-hz = <200000000 200000000>, <38400000 38400000>;
lanes-per-direction = <1>;
power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>;
resets = <&cpg 1514>;
status = "disabled";

View File

@ -1913,23 +1913,28 @@ queue3 {
mtl_tx_setup0: tx-queues-config {
snps,tx-queues-to-use = <4>;
snps,tx-sched-wrr;
queue0 {
snps,weight = <0x10>;
snps,dcb-algorithm;
snps,priority = <0x1>;
};
queue1 {
snps,weight = <0x12>;
snps,dcb-algorithm;
snps,priority = <0x2>;
};
queue2 {
snps,weight = <0x14>;
snps,dcb-algorithm;
snps,priority = <0x4>;
};
queue3 {
snps,weight = <0x18>;
snps,dcb-algorithm;
snps,priority = <0x8>;
};
@ -2013,23 +2018,28 @@ queue3 {
mtl_tx_setup1: tx-queues-config {
snps,tx-queues-to-use = <4>;
snps,tx-sched-wrr;
queue0 {
snps,weight = <0x10>;
snps,dcb-algorithm;
snps,priority = <0x1>;
};
queue1 {
snps,weight = <0x12>;
snps,dcb-algorithm;
snps,priority = <0x2>;
};
queue2 {
snps,weight = <0x14>;
snps,dcb-algorithm;
snps,priority = <0x4>;
};
queue3 {
snps,weight = <0x18>;
snps,dcb-algorithm;
snps,priority = <0x8>;
};

View File

@ -1585,23 +1585,28 @@ queue3 {
mtl_tx_setup0: tx-queues-config {
snps,tx-queues-to-use = <4>;
snps,tx-sched-wrr;
queue0 {
snps,weight = <0x10>;
snps,dcb-algorithm;
snps,priority = <0x1>;
};
queue1 {
snps,weight = <0x12>;
snps,dcb-algorithm;
snps,priority = <0x2>;
};
queue2 {
snps,weight = <0x14>;
snps,dcb-algorithm;
snps,priority = <0x4>;
};
queue3 {
snps,weight = <0x18>;
snps,dcb-algorithm;
snps,priority = <0x8>;
};
@ -1686,23 +1691,28 @@ queue3 {
mtl_tx_setup1: tx-queues-config {
snps,tx-queues-to-use = <4>;
snps,tx-sched-wrr;
queue0 {
snps,weight = <0x10>;
snps,dcb-algorithm;
snps,priority = <0x1>;
};
queue1 {
snps,weight = <0x12>;
snps,dcb-algorithm;
snps,priority = <0x2>;
};
queue2 {
snps,weight = <0x14>;
snps,dcb-algorithm;
snps,priority = <0x4>;
};
queue3 {
snps,weight = <0x18>;
snps,dcb-algorithm;
snps,priority = <0x8>;
};

View File

@ -1715,23 +1715,28 @@ queue3 {
mtl_tx_setup0: tx-queues-config {
snps,tx-queues-to-use = <4>;
snps,tx-sched-wrr;
queue0 {
snps,weight = <0x10>;
snps,dcb-algorithm;
snps,priority = <0x1>;
};
queue1 {
snps,weight = <0x12>;
snps,dcb-algorithm;
snps,priority = <0x2>;
};
queue2 {
snps,weight = <0x14>;
snps,dcb-algorithm;
snps,priority = <0x4>;
};
queue3 {
snps,weight = <0x18>;
snps,dcb-algorithm;
snps,priority = <0x8>;
};
@ -1816,23 +1821,28 @@ queue3 {
mtl_tx_setup1: tx-queues-config {
snps,tx-queues-to-use = <4>;
snps,tx-sched-wrr;
queue0 {
snps,weight = <0x10>;
snps,dcb-algorithm;
snps,priority = <0x1>;
};
queue1 {
snps,weight = <0x12>;
snps,dcb-algorithm;
snps,priority = <0x2>;
};
queue2 {
snps,weight = <0x14>;
snps,dcb-algorithm;
snps,priority = <0x4>;
};
queue3 {
snps,weight = <0x18>;
snps,dcb-algorithm;
snps,priority = <0x8>;
};

View File

@ -642,36 +642,45 @@ queue7 {
mtl_tx_setup0: tx-queues-config {
snps,tx-queues-to-use = <8>;
snps,tx-sched-wrr;
queue0 {
snps,weight = <0x10>;
snps,dcb-algorithm;
};
queue1 {
snps,weight = <0x11>;
snps,dcb-algorithm;
};
queue2 {
snps,weight = <0x12>;
snps,dcb-algorithm;
};
queue3 {
snps,weight = <0x13>;
snps,dcb-algorithm;
};
queue4 {
snps,weight = <0x14>;
snps,dcb-algorithm;
};
queue5 {
snps,weight = <0x15>;
snps,dcb-algorithm;
};
queue6 {
snps,weight = <0x16>;
snps,dcb-algorithm;
};
queue7 {
snps,weight = <0x17>;
snps,dcb-algorithm;
};
};
@ -788,36 +797,45 @@ queue7 {
mtl_tx_setup1: tx-queues-config {
snps,tx-queues-to-use = <8>;
snps,tx-sched-wrr;
queue0 {
snps,weight = <0x10>;
snps,dcb-algorithm;
};
queue1 {
snps,weight = <0x11>;
snps,dcb-algorithm;
};
queue2 {
snps,weight = <0x12>;
snps,dcb-algorithm;
};
queue3 {
snps,weight = <0x13>;
snps,dcb-algorithm;
};
queue4 {
snps,weight = <0x14>;
snps,dcb-algorithm;
};
queue5 {
snps,weight = <0x15>;
snps,dcb-algorithm;
};
queue6 {
snps,weight = <0x16>;
snps,dcb-algorithm;
};
queue7 {
snps,weight = <0x17>;
snps,dcb-algorithm;
};
};
@ -934,36 +952,45 @@ queue7 {
mtl_tx_setup2: tx-queues-config {
snps,tx-queues-to-use = <8>;
snps,tx-sched-wrr;
queue0 {
snps,weight = <0x10>;
snps,dcb-algorithm;
};
queue1 {
snps,weight = <0x11>;
snps,dcb-algorithm;
};
queue2 {
snps,weight = <0x12>;
snps,dcb-algorithm;
};
queue3 {
snps,weight = <0x13>;
snps,dcb-algorithm;
};
queue4 {
snps,weight = <0x14>;
snps,dcb-algorithm;
};
queue5 {
snps,weight = <0x15>;
snps,dcb-algorithm;
};
queue6 {
snps,weight = <0x16>;
snps,dcb-algorithm;
};
queue7 {
snps,weight = <0x17>;
snps,dcb-algorithm;
};
};

View File

@ -643,36 +643,45 @@ queue7 {
mtl_tx_setup0: tx-queues-config {
snps,tx-queues-to-use = <8>;
snps,tx-sched-wrr;
queue0 {
snps,weight = <0x10>;
snps,dcb-algorithm;
};
queue1 {
snps,weight = <0x11>;
snps,dcb-algorithm;
};
queue2 {
snps,weight = <0x12>;
snps,dcb-algorithm;
};
queue3 {
snps,weight = <0x13>;
snps,dcb-algorithm;
};
queue4 {
snps,weight = <0x14>;
snps,dcb-algorithm;
};
queue5 {
snps,weight = <0x15>;
snps,dcb-algorithm;
};
queue6 {
snps,weight = <0x16>;
snps,dcb-algorithm;
};
queue7 {
snps,weight = <0x17>;
snps,dcb-algorithm;
};
};
@ -790,36 +799,45 @@ queue7 {
mtl_tx_setup1: tx-queues-config {
snps,tx-queues-to-use = <8>;
snps,tx-sched-wrr;
queue0 {
snps,weight = <0x10>;
snps,dcb-algorithm;
};
queue1 {
snps,weight = <0x11>;
snps,dcb-algorithm;
};
queue2 {
snps,weight = <0x12>;
snps,dcb-algorithm;
};
queue3 {
snps,weight = <0x13>;
snps,dcb-algorithm;
};
queue4 {
snps,weight = <0x14>;
snps,dcb-algorithm;
};
queue5 {
snps,weight = <0x15>;
snps,dcb-algorithm;
};
queue6 {
snps,weight = <0x16>;
snps,dcb-algorithm;
};
queue7 {
snps,weight = <0x17>;
snps,dcb-algorithm;
};
};
@ -937,36 +955,45 @@ queue7 {
mtl_tx_setup2: tx-queues-config {
snps,tx-queues-to-use = <8>;
snps,tx-sched-wrr;
queue0 {
snps,weight = <0x10>;
snps,dcb-algorithm;
};
queue1 {
snps,weight = <0x11>;
snps,dcb-algorithm;
};
queue2 {
snps,weight = <0x12>;
snps,dcb-algorithm;
};
queue3 {
snps,weight = <0x13>;
snps,dcb-algorithm;
};
queue4 {
snps,weight = <0x14>;
snps,dcb-algorithm;
};
queue5 {
snps,weight = <0x15>;
snps,dcb-algorithm;
};
queue6 {
snps,weight = <0x16>;
snps,dcb-algorithm;
};
queue7 {
snps,weight = <0x17>;
snps,dcb-algorithm;
};
};

View File

@ -418,6 +418,7 @@
b.lt .Lskip_fgt2_\@
mov x0, xzr
mov x2, xzr
mrs x1, id_aa64dfr0_el1
ubfx x1, x1, #ID_AA64DFR0_EL1_PMUVer_SHIFT, #4
cmp x1, #ID_AA64DFR0_EL1_PMUVer_V3P9
@ -426,6 +427,11 @@
orr x0, x0, #HDFGRTR2_EL2_nPMICNTR_EL0
orr x0, x0, #HDFGRTR2_EL2_nPMICFILTR_EL0
orr x0, x0, #HDFGRTR2_EL2_nPMUACR_EL1
orr x2, x2, #HDFGWTR2_EL2_nPMICNTR_EL0
orr x2, x2, #HDFGWTR2_EL2_nPMICFILTR_EL0
orr x2, x2, #HDFGWTR2_EL2_nPMUACR_EL1
/* PMZR_EL0 is write-only, so it has no read trap to disable */
orr x2, x2, #HDFGWTR2_EL2_nPMZR_EL0
.Lskip_pmuv3p9_\@:
/* If SPE is implemented, */
__spe_vers_imp .Lskip_spefds_\@, ID_AA64DFR0_EL1_PMSVer_IMP, x1
@ -436,10 +442,11 @@
cbz x1, .Lskip_spefds_\@
/* disable traps of PMSDSFR to EL2. */
orr x0, x0, #HDFGRTR2_EL2_nPMSDSFR_EL1
orr x2, x2, #HDFGWTR2_EL2_nPMSDSFR_EL1
.Lskip_spefds_\@:
msr_s SYS_HDFGRTR2_EL2, x0
msr_s SYS_HDFGWTR2_EL2, x0
msr_s SYS_HDFGWTR2_EL2, x2
msr_s SYS_HFGRTR2_EL2, xzr
msr_s SYS_HFGWTR2_EL2, xzr
msr_s SYS_HFGITR2_EL2, xzr

View File

@ -280,7 +280,8 @@ static inline void __iomem *ioremap_prot(phys_addr_t phys, size_t size,
pgprot_t prot;
ptval_t user_prot_val = pgprot_val(user_prot);
if (WARN_ON_ONCE(!(user_prot_val & PTE_USER)))
/* Reject PROT_NONE and exec-only */
if (!(user_prot_val & PTE_USER))
return NULL;
prot = __pgprot_modify(PAGE_KERNEL, PTE_ATTRINDX_MASK,

View File

@ -77,7 +77,7 @@ __percpu_##name##_case_##sz(void *ptr, unsigned long val) \
" stxr" #sfx "\t%w[loop], %" #w "[tmp], %[ptr]\n" \
" cbnz %w[loop], 1b", \
/* LSE atomics */ \
#op_lse "\t%" #w "[val], %" #w "[tmp], %[ptr]\n" \
#op_lse #sfx "\t%" #w "[val], %" #w "[tmp], %[ptr]\n" \
__nops(3)) \
: [loop] "=&r" (loop), [tmp] "=&r" (tmp), \
[ptr] "+Q"(*(u##sz *)ptr) \
@ -98,7 +98,7 @@ __percpu_##name##_return_case_##sz(void *ptr, unsigned long val) \
" stxr" #sfx "\t%w[loop], %" #w "[ret], %[ptr]\n" \
" cbnz %w[loop], 1b", \
/* LSE atomics */ \
#op_lse "\t%" #w "[val], %" #w "[ret], %[ptr]\n" \
#op_lse #sfx "\t%" #w "[val], %" #w "[ret], %[ptr]\n" \
#op_llsc "\t%" #w "[ret], %" #w "[ret], %" #w "[val]\n" \
__nops(2)) \
: [loop] "=&r" (loop), [ret] "=&r" (ret), \
@ -179,13 +179,13 @@ PERCPU_RET_OP(add, add, ldadd)
_pcp_protect_return(__percpu_read_64, pcp)
#define this_cpu_write_1(pcp, val) \
_pcp_protect(__percpu_write_8, pcp, (unsigned long)val)
_pcp_protect(__percpu_write_8, pcp, (unsigned long)(val))
#define this_cpu_write_2(pcp, val) \
_pcp_protect(__percpu_write_16, pcp, (unsigned long)val)
_pcp_protect(__percpu_write_16, pcp, (unsigned long)(val))
#define this_cpu_write_4(pcp, val) \
_pcp_protect(__percpu_write_32, pcp, (unsigned long)val)
_pcp_protect(__percpu_write_32, pcp, (unsigned long)(val))
#define this_cpu_write_8(pcp, val) \
_pcp_protect(__percpu_write_64, pcp, (unsigned long)val)
_pcp_protect(__percpu_write_64, pcp, (unsigned long)(val))
#define this_cpu_add_1(pcp, val) \
_pcp_protect(__percpu_add_case_8, pcp, val)
@ -206,13 +206,13 @@ PERCPU_RET_OP(add, add, ldadd)
_pcp_protect_return(__percpu_add_return_case_64, pcp, val)
#define this_cpu_and_1(pcp, val) \
_pcp_protect(__percpu_andnot_case_8, pcp, ~val)
_pcp_protect(__percpu_andnot_case_8, pcp, ~(u8)(val))
#define this_cpu_and_2(pcp, val) \
_pcp_protect(__percpu_andnot_case_16, pcp, ~val)
_pcp_protect(__percpu_andnot_case_16, pcp, ~(u16)(val))
#define this_cpu_and_4(pcp, val) \
_pcp_protect(__percpu_andnot_case_32, pcp, ~val)
_pcp_protect(__percpu_andnot_case_32, pcp, ~(u32)(val))
#define this_cpu_and_8(pcp, val) \
_pcp_protect(__percpu_andnot_case_64, pcp, ~val)
_pcp_protect(__percpu_andnot_case_64, pcp, ~(u64)(val))
#define this_cpu_or_1(pcp, val) \
_pcp_protect(__percpu_or_case_8, pcp, val)

View File

@ -28,18 +28,21 @@ bool cpu_errata_set_target_impl(u64 num, void *impl_cpus)
return true;
}
static inline bool __is_midr_in_range(u32 midr, struct midr_range const *range)
{
return midr_is_cpu_model_range(midr, range->model,
range->rv_min, range->rv_max);
}
static inline bool is_midr_in_range(struct midr_range const *range)
{
int i;
if (!target_impl_cpu_num)
return midr_is_cpu_model_range(read_cpuid_id(), range->model,
range->rv_min, range->rv_max);
return __is_midr_in_range(read_cpuid_id(), range);
for (i = 0; i < target_impl_cpu_num; i++) {
if (midr_is_cpu_model_range(target_impl_cpus[i].midr,
range->model,
range->rv_min, range->rv_max))
if (__is_midr_in_range(target_impl_cpus[i].midr, range))
return true;
}
return false;
@ -59,7 +62,7 @@ __is_affected_midr_range(const struct arm64_cpu_capabilities *entry,
u32 midr, u32 revidr)
{
const struct arm64_midr_revidr *fix;
if (!is_midr_in_range(&entry->midr_range))
if (!__is_midr_in_range(midr, &entry->midr_range))
return false;
midr &= MIDR_REVISION_MASK | MIDR_VARIANT_MASK;

View File

@ -89,6 +89,8 @@ alternative_insn "dc cvau, x4", "dc civac, x4", ARM64_WORKAROUND_CLEAN_CACHE
isb
cbz x24, 3f /* Do we need to re-initialise EL2? */
mov x1, x24
mov x0, #HVC_SET_VECTORS
hvc #0
3: ret
SYM_CODE_END(swsusp_arch_suspend_exit)

View File

@ -423,8 +423,8 @@ int __nocfi swsusp_arch_resume(void)
* Create a second copy of just the linear map, and use this when
* restoring.
*/
rc = trans_pgd_create_copy(&trans_info, &tmp_pg_dir, PAGE_OFFSET,
PAGE_END);
rc = trans_pgd_create_copy(&trans_info, &tmp_pg_dir,
_PAGE_OFFSET(vabits_actual), PAGE_END);
if (rc)
return rc;

View File

@ -476,7 +476,7 @@ static int __access_remote_tags(struct mm_struct *mm, unsigned long addr,
* was never mapped with PROT_MTE.
*/
if (!(vma->vm_flags & VM_MTE)) {
err = -EOPNOTSUPP;
err = -EIO;
put_page(page);
break;
}

View File

@ -186,6 +186,7 @@ static const struct ftr_set_desc isar2 __prel64_initconst = {
.name = "id_aa64isar2",
.override = &id_aa64isar2_override,
.fields = {
FIELD("wfxt", ID_AA64ISAR2_EL1_WFxT_SHIFT, NULL),
FIELD("gpa3", ID_AA64ISAR2_EL1_GPA3_SHIFT, NULL),
FIELD("apa3", ID_AA64ISAR2_EL1_APA3_SHIFT, NULL),
FIELD("mops", ID_AA64ISAR2_EL1_MOPS_SHIFT, NULL),
@ -254,6 +255,7 @@ static const struct {
"id_aa64isar1.api=0 id_aa64isar1.apa=0 "
"id_aa64isar2.gpa3=0 id_aa64isar2.apa3=0" },
{ "arm64.nomops", "id_aa64isar2.mops=0" },
{ "arm64.nowfxt", "id_aa64isar2.wfxt=0" },
{ "arm64.nomte", "id_aa64pfr1.mte=0" },
{ "nokaslr", "arm64_sw.nokaslr=1" },
{ "rodata=off", "arm64_sw.rodataoff=1" },

View File

@ -600,6 +600,8 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf)
* 12 registers are on the stack
*/
emit(A64_SUB_I(1, A64_SP, A64_FP, 96), ctx);
/* The callback may use its own BPF stack, set up fp for it. */
ctx->fp_used = true;
}
/* Stack must be multiples of 16B */

View File

@ -396,10 +396,7 @@ config ECONET
bool "EcoNet MIPS family"
select BOOT_RAW
select DEBUG_ZBOOT if DEBUG_KERNEL
select EARLY_PRINTK_8250
select ECONET_EN751221_TIMER
select SERIAL_8250
select SERIAL_OF_PLATFORM
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_HAS_CPU_MIPS32_R1
select SYS_HAS_CPU_MIPS32_R2
@ -661,6 +658,7 @@ config EYEQ
select USB_UHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
select USE_OF
select HOTPLUG_PARALLEL if HOTPLUG_CPU
select WEAK_REORDERING_BEYOND_LLSC
help
Select this to build a kernel supporting EyeQ SoC from Mobileye.

View File

@ -18,7 +18,7 @@
#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-helper-board.h>
#ifdef CONFIG_USB
#if IS_ENABLED(CONFIG_USB)
#include <linux/usb/ehci_def.h>
#include <linux/usb/ehci_pdriver.h>
#include <linux/usb/ohci_pdriver.h>
@ -1080,7 +1080,7 @@ int __init octeon_prune_device_tree(void)
;
}
#ifdef CONFIG_USB
#if IS_ENABLED(CONFIG_USB)
/* OHCI/UHCI USB */
alias_prop = fdt_getprop(initial_boot_params, aliases,
"uctl", NULL);

View File

@ -0,0 +1,264 @@
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_KERNEL_XZ=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
# CONFIG_CROSS_MEMORY_ATTACH is not set
CONFIG_HIGH_RES_TIMERS=y
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_JIT=y
CONFIG_PREEMPT=y
CONFIG_CGROUPS=y
CONFIG_MEMCG=y
CONFIG_BLK_CGROUP=y
CONFIG_CGROUP_SCHED=y
CONFIG_CFS_BANDWIDTH=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_RDMA=y
CONFIG_CPUSETS=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_BPF=y
CONFIG_NAMESPACES=y
# CONFIG_TIME_NS is not set
CONFIG_USER_NS=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_RD_GZIP is not set
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
# CONFIG_RD_XZ is not set
# CONFIG_RD_LZO is not set
# CONFIG_RD_LZ4 is not set
# CONFIG_RD_ZSTD is not set
# CONFIG_INITRAMFS_PRESERVE_MTIME is not set
CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=y
CONFIG_EXPERT=y
# CONFIG_SGETMASK_SYSCALL is not set
# CONFIG_IO_URING is not set
# CONFIG_RSEQ is not set
# CONFIG_CACHESTAT_SYSCALL is not set
CONFIG_ECONET=y
CONFIG_CPU_MIPS32_R2=y
CONFIG_ZBOOT_LOAD_ADDRESS=0x80020000
CONFIG_ARCH_FORCE_MAX_ORDER=11
# CONFIG_MIPS_FP_SUPPORT is not set
CONFIG_NR_CPUS=2
CONFIG_HZ_100=y
CONFIG_MIPS_RAW_APPENDED_DTB=y
# CONFIG_SCHED_SMT is not set
CONFIG_JUMP_LABEL=y
# CONFIG_STACKPROTECTOR_STRONG is not set
# CONFIG_GCC_PLUGINS is not set
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLOCK_LEGACY_AUTOLOAD is not set
CONFIG_BLK_DEV_THROTTLING=y
# CONFIG_BLK_DEBUG_FS is not set
CONFIG_PARTITION_ADVANCED=y
CONFIG_OF_PARTITION=y
# CONFIG_MQ_IOSCHED_DEADLINE is not set
# CONFIG_MQ_IOSCHED_KYBER is not set
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_SLAB_FREELIST_RANDOM=y
CONFIG_SLAB_FREELIST_HARDENED=y
# CONFIG_COMPAT_BRK is not set
CONFIG_LRU_GEN=y
CONFIG_LRU_GEN_ENABLED=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_MULTIPATH=y
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_MROUTE=y
CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
CONFIG_SYN_COOKIES=y
# CONFIG_INET_DIAG is not set
CONFIG_TCP_CONG_ADVANCED=y
# CONFIG_TCP_CONG_BIC is not set
# CONFIG_TCP_CONG_WESTWOOD is not set
# CONFIG_TCP_CONG_HTCP is not set
# CONFIG_IPV6_SIT is not set
CONFIG_IPV6_SUBTREES=y
CONFIG_IPV6_MROUTE=y
CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
CONFIG_IPV6_PIMSM_V2=y
CONFIG_IPV6_SEG6_LWTUNNEL=y
CONFIG_MPTCP=y
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_EGRESS is not set
CONFIG_NF_CONNTRACK=m
CONFIG_NF_CONNTRACK_MARK=y
CONFIG_NF_CONNTRACK_ZONES=y
CONFIG_NF_CONNTRACK_PROCFS=y
CONFIG_NF_CONNTRACK_TIMEOUT=y
# CONFIG_NF_CT_PROTO_SCTP is not set
CONFIG_NF_TABLES=m
CONFIG_NF_TABLES_INET=y
CONFIG_NF_TABLES_NETDEV=y
CONFIG_NFT_NUMGEN=m
CONFIG_NFT_CT=m
CONFIG_NFT_FLOW_OFFLOAD=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
CONFIG_NFT_MASQ=m
CONFIG_NFT_REDIR=m
CONFIG_NFT_NAT=m
CONFIG_NFT_QUOTA=m
CONFIG_NFT_REJECT=m
CONFIG_NFT_HASH=m
CONFIG_NFT_FIB_INET=m
CONFIG_NF_FLOW_TABLE_INET=m
CONFIG_NF_FLOW_TABLE=m
CONFIG_NFT_FIB_IPV4=m
CONFIG_NF_TABLES_ARP=y
CONFIG_NF_LOG_IPV4=m
CONFIG_NFT_FIB_IPV6=m
CONFIG_NF_LOG_IPV6=m
CONFIG_NF_TABLES_BRIDGE=m
CONFIG_BRIDGE=y
CONFIG_BRIDGE_VLAN_FILTERING=y
CONFIG_VLAN_8021Q=y
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_FQ_CODEL=y
CONFIG_NET_SCH_DEFAULT=y
CONFIG_DEFAULT_FQ_CODEL=y
CONFIG_NET_SWITCHDEV=y
CONFIG_NET_L3_MASTER_DEV=y
CONFIG_RFKILL=y
# CONFIG_LWTUNNEL_BPF is not set
CONFIG_PCI=y
CONFIG_PCIEPORTBUS=y
CONFIG_PCIEAER=y
# CONFIG_PCIEASPM is not set
CONFIG_PCI_MSI=y
# CONFIG_VGA_ARB is not set
CONFIG_PCIE_MEDIATEK=y
CONFIG_MTD=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_SPI_NAND=y
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_BEB_LIMIT=13
CONFIG_MTD_UBI_BLOCK=y
CONFIG_NETDEVICES=y
# CONFIG_NET_VENDOR_ASIX is not set
# CONFIG_NET_VENDOR_ENGLEDER is not set
# CONFIG_NET_VENDOR_FUNGIBLE is not set
# CONFIG_NET_VENDOR_LITEX is not set
# CONFIG_NET_VENDOR_MICROSOFT is not set
# CONFIG_NET_VENDOR_VERTEXCOM is not set
# CONFIG_NET_VENDOR_WANGXUN is not set
CONFIG_PPP=m
CONFIG_PPP_FILTER=y
CONFIG_PPP_MULTILINK=y
CONFIG_PPPOE=m
CONFIG_PPP_ASYNC=m
# CONFIG_WLAN_VENDOR_ADMTEK is not set
# CONFIG_WLAN_VENDOR_ATH is not set
# CONFIG_WLAN_VENDOR_ATMEL is not set
# CONFIG_WLAN_VENDOR_BROADCOM is not set
# CONFIG_WLAN_VENDOR_INTEL is not set
# CONFIG_WLAN_VENDOR_INTERSIL is not set
# CONFIG_WLAN_VENDOR_MARVELL is not set
# CONFIG_WLAN_VENDOR_MEDIATEK is not set
# CONFIG_WLAN_VENDOR_MICROCHIP is not set
# CONFIG_WLAN_VENDOR_PURELIFI is not set
# CONFIG_WLAN_VENDOR_RALINK is not set
# CONFIG_WLAN_VENDOR_REALTEK is not set
# CONFIG_WLAN_VENDOR_RSI is not set
# CONFIG_WLAN_VENDOR_SILABS is not set
# CONFIG_WLAN_VENDOR_ST is not set
# CONFIG_WLAN_VENDOR_TI is not set
# CONFIG_WLAN_VENDOR_ZYDAS is not set
# CONFIG_WLAN_VENDOR_QUANTENNA is not set
# CONFIG_INPUT is not set
# CONFIG_SERIO is not set
# CONFIG_VT is not set
# CONFIG_LEGACY_PTYS is not set
# CONFIG_LEGACY_TIOCSTI is not set
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_OF_PLATFORM=y
# CONFIG_HW_RANDOM is not set
# CONFIG_DEVMEM is not set
CONFIG_SPI=y
# CONFIG_PTP_1588_CLOCK is not set
CONFIG_GPIOLIB=y
# CONFIG_HWMON is not set
CONFIG_WATCHDOG=y
CONFIG_MFD_SYSCON=y
# CONFIG_USB_PCI is not set
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_CLASS_MULTICOLOR=y
CONFIG_LEDS_GPIO=m
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
CONFIG_LEDS_TRIGGER_NETDEV=y
CONFIG_STAGING=y
# CONFIG_MIPS_PLATFORM_DEVICES is not set
CONFIG_COMMON_CLK_EN7523=y
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_RESET_CONTROLLER=y
CONFIG_PHY_ECONET_PCIE=y
# CONFIG_DNOTIFY is not set
CONFIG_FANOTIFY=y
CONFIG_OVERLAY_FS=y
# CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW is not set
# CONFIG_PROC_PAGE_MONITOR is not set
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_SUMMARY=y
CONFIG_JFFS2_FS_XATTR=y
CONFIG_JFFS2_COMPRESSION_OPTIONS=y
CONFIG_UBIFS_FS=y
CONFIG_SQUASHFS=y
CONFIG_SQUASHFS_FILE_DIRECT=y
CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI_PERCPU=y
# CONFIG_SQUASHFS_ZLIB is not set
CONFIG_SQUASHFS_XZ=y
CONFIG_SQUASHFS_EMBEDDED=y
CONFIG_KEYS=y
CONFIG_INIT_STACK_NONE=y
CONFIG_FORTIFY_SOURCE=y
CONFIG_HARDENED_USERCOPY=y
CONFIG_LIST_HARDENED=y
CONFIG_CRYPTO_NULL=y
CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_CCM=y
CONFIG_CRYPTO_GCM=y
# CONFIG_CRYPTO_HW is not set
# CONFIG_XZ_DEC_X86 is not set
# CONFIG_XZ_DEC_POWERPC is not set
# CONFIG_XZ_DEC_ARM is not set
# CONFIG_XZ_DEC_ARMTHUMB is not set
# CONFIG_XZ_DEC_ARM64 is not set
# CONFIG_XZ_DEC_SPARC is not set
# CONFIG_XZ_DEC_RISCV is not set
CONFIG_PRINTK_TIME=y
# CONFIG_DEBUG_MISC is not set
CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
CONFIG_DEBUG_INFO_REDUCED=y
CONFIG_FRAME_WARN=1024
CONFIG_STRIP_ASM_SYMS=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_MAGIC_SYSRQ_SERIAL is not set
CONFIG_DEBUG_FS=y
# CONFIG_SLUB_DEBUG is not set
CONFIG_SCHED_STACK_END_CHECK=y
CONFIG_PANIC_ON_OOPS=y
CONFIG_PANIC_TIMEOUT=1
CONFIG_RCU_CPU_STALL_TIMEOUT=60
# CONFIG_RCU_TRACE is not set
# CONFIG_FTRACE is not set

View File

@ -1111,7 +1111,7 @@ static void emit_jmp_i64(struct jit_context *ctx,
emit(ctx, xor, tmp, lo(dst), tmp);
}
if (imm < 0) { /* Compare sign extension */
emit(ctx, addu, MIPS_R_T9, hi(dst), 1);
emit(ctx, addiu, MIPS_R_T9, hi(dst), 1);
emit(ctx, or, tmp, tmp, MIPS_R_T9);
} else { /* Compare zero extension */
emit(ctx, or, tmp, tmp, hi(dst));

View File

@ -305,8 +305,7 @@ static void emit_bswap_r64(struct jit_context *ctx, u8 dst, u32 width)
case 16:
emit_sext(ctx, dst, dst);
emit_bswap_r(ctx, dst, width);
if (cpu_has_mips64r2 || cpu_has_mips64r6)
emit_zext(ctx, dst);
emit_zext(ctx, dst);
break;
}
clobber_reg(ctx, dst);

View File

@ -1,18 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_PARISC_COMPAT_UCONTEXT_H
#define _ASM_PARISC_COMPAT_UCONTEXT_H
#include <linux/compat.h>
/* 32-bit ucontext as seen from an 64-bit kernel */
struct compat_ucontext {
compat_uint_t uc_flags;
compat_uptr_t uc_link;
compat_stack_t uc_stack; /* struct compat_sigaltstack (12 bytes)*/
/* FIXME: Pad out to get uc_mcontext to start at an 8-byte aligned boundary */
compat_uint_t pad[1];
struct compat_sigcontext uc_mcontext;
compat_sigset_t uc_sigmask; /* mask last for extensibility */
};
#endif /* !_ASM_PARISC_COMPAT_UCONTEXT_H */

View File

@ -24,7 +24,7 @@ struct thread_info {
/* thread information allocation */
#ifdef CONFIG_IRQSTACKS
#if defined(CONFIG_IRQSTACKS) && !defined(CONFIG_64BIT)
#define THREAD_SIZE_ORDER 2 /* PA-RISC requires at least 16k stack */
#else
#define THREAD_SIZE_ORDER 3 /* PA-RISC requires at least 32k stack */

View File

@ -132,6 +132,18 @@ void __init setup_arch(char **cmdline_p)
parisc_cache_init();
paging_init();
/*
* Parse early parameters before mm_core_init_early() runs.
* Several early_param() handlers only record data that is consumed
* from there - for example hugepages=, hugepagesz=,
* default_hugepagesz=, hugetlb_cma= and hugetlb_free_vmemmap= - so
* the generic parse_early_param() call in start_kernel() is too late
* for them. jump_label_init() must come first, since early param
* handlers may enable or disable static keys.
*/
jump_label_init();
parse_early_param();
#ifdef CONFIG_PA11
dma_ops_init();
#endif

View File

@ -14,6 +14,7 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/sort.h>
#include <linux/bsearch.h>
#include <linux/sched/task_stack.h>
#include <linux/uaccess.h>
@ -49,27 +50,23 @@ static DEFINE_SPINLOCK(unwind_lock);
static struct unwind_table kernel_unwind_table __ro_after_init;
static LIST_HEAD(unwind_tables);
static int cmp_unwind_entry(const void *key, const void *elt)
{
unsigned long addr = (unsigned long)key;
const struct unwind_table_entry *e = elt;
if (addr < e->region_start)
return -1;
if (addr > e->region_end)
return 1;
return 0;
}
static inline const struct unwind_table_entry *
find_unwind_entry_in_table(const struct unwind_table *table, unsigned long addr)
{
const struct unwind_table_entry *e = NULL;
unsigned long lo, hi, mid;
lo = 0;
hi = table->length - 1;
while (lo <= hi) {
mid = (hi - lo) / 2 + lo;
e = &table->table[mid];
if (addr < e->region_start)
hi = mid - 1;
else if (addr > e->region_end)
lo = mid + 1;
else
return e;
}
return NULL;
return bsearch((void *)addr, table->table, table->length,
sizeof(*table->table), cmp_unwind_entry);
}
static const struct unwind_table_entry *

View File

@ -150,7 +150,10 @@ static int hash_data(const u8 *in, unsigned int inlen,
#undef PARAM_INIT
cpacf_klmd(func, &param, in, inlen);
if (final)
cpacf_klmd(func, &param, in, inlen);
else
cpacf_kimd(func, &param, in, inlen);
memcpy(digest, &param, digestsize);

View File

@ -204,10 +204,21 @@ config CC_HAS_MARCH_NATIVE
# usage warnings that only appear wth '-march=native'.
depends on CC_IS_GCC || CLANG_VERSION >= 190100
config RUSTC_HAS_APXF
# The kernel isn't ready for in-kernel APX instructions. Without
# explicit frontend gating of APX, the backend may emit those
# instructions in native builds.
#
# Rust 1.88 added the `apxf` feature option, but versions before 1.93
# emit an `apxf` target attribute that only LLVM 23+ can interpret.
def_bool (RUSTC_VERSION >= 108800 && RUSTC_LLVM_MAJOR_VERSION >= 23) || \
RUSTC_VERSION >= 109300
config X86_NATIVE_CPU
bool "Build and optimize for local/native CPU"
depends on X86_64
depends on CC_HAS_MARCH_NATIVE
depends on !RUST || RUSTC_HAS_APXF
help
Optimize for the current CPU used to compile the kernel.
Use this option if you intend to build the kernel for your

View File

@ -161,6 +161,11 @@ else
ifdef CONFIG_X86_NATIVE_CPU
KBUILD_CFLAGS += -march=native
# Prevent the compiler from generating EGPR use. The kernel is
# not yet prepared for general in-kernel use.
KBUILD_CFLAGS += $(call cc-option,-mno-apx-features=egpr)
# generate_rust_target.rs handles Rust APX gating.
KBUILD_RUSTFLAGS += -Ctarget-cpu=native
else
KBUILD_CFLAGS += -march=x86-64 -mtune=generic

View File

@ -10,6 +10,7 @@
#include <asm/desc.h>
#include <asm/fred.h>
#include <asm/idtentry.h>
#include <asm/processor-flags.h>
#include <asm/syscall.h>
#include <asm/trapnr.h>
#include <asm/traps.h>
@ -71,7 +72,15 @@ static noinstr void fred_intx(struct pt_regs *regs)
#endif
default:
return exc_general_protection(regs, 0);
/*
* Reconstruct the #GP fault state that IDT delivery would produce.
* Clear the software event flag so ERETU with TF set does not trap
* before the resumed instruction. See prevent_single_step_upon_eretu().
*/
regs->ip -= regs->fred_ss.insnlen;
regs->flags |= X86_EFLAGS_RF;
regs->fred_ss.swevent = 0;
return exc_general_protection(regs, (regs->fred_ss.vector << 3) | 2);
}
}

View File

@ -164,9 +164,9 @@ unsigned long int3_emulate_pop(struct pt_regs *regs)
}
static __always_inline
void int3_emulate_call(struct pt_regs *regs, unsigned long func)
void int3_emulate_call(struct pt_regs *regs, unsigned long ip, unsigned long func)
{
int3_emulate_push(regs, regs->ip - INT3_INSN_SIZE + CALL_INSN_SIZE);
int3_emulate_push(regs, ip);
int3_emulate_jmp(regs, func);
}

View File

@ -2176,6 +2176,7 @@ int3_exception_notify(struct notifier_block *self, unsigned long val, void *data
unsigned long selftest = (unsigned long)&int3_selftest_asm;
struct die_args *args = data;
struct pt_regs *regs = args->regs;
unsigned long ip;
OPTIMIZER_HIDE_VAR(selftest);
@ -2188,7 +2189,8 @@ int3_exception_notify(struct notifier_block *self, unsigned long val, void *data
if (regs->ip - INT3_INSN_SIZE != selftest)
return NOTIFY_DONE;
int3_emulate_call(regs, (unsigned long)&int3_selftest_callee);
ip = regs->ip - INT3_INSN_SIZE + CALL_INSN_SIZE;
int3_emulate_call(regs, ip, (unsigned long)&int3_selftest_callee);
return NOTIFY_STOP;
}
@ -2758,7 +2760,7 @@ noinstr int smp_text_poke_int3_handler(struct pt_regs *regs)
break;
case CALL_INSN_OPCODE:
int3_emulate_call(regs, (long)ip + tpl->disp);
int3_emulate_call(regs, (long)ip, (long)ip + tpl->disp);
break;
case JMP32_INSN_OPCODE:

View File

@ -309,6 +309,26 @@ static void save_microcode_patch(struct microcode_intel *patch)
pr_err("Unable to allocate microcode memory size: %u\n", size);
}
static bool revision_is_safe(struct cpu_signature *sig, u32 rev)
{
u32 vfm = IFM(x86_family(sig->sig), x86_model(sig->sig));
/*
* Erratum GNR98 can cause #MCs if "jumping over" revision 0x1000405.
* Avoid the jumps.
*/
if (vfm == INTEL_GRANITERAPIDS_X &&
x86_stepping(sig->sig) == 1 &&
sig->pf & 0x95 &&
sig->rev < 0x1000405 &&
rev > 0x1000405) {
pr_err_once("Erratum GNR98: skipping revision 0x%x.\n", rev);
return false;
}
return true;
}
/* Scan blob for microcode matching the boot CPUs family, model, stepping */
static __init struct microcode_intel *scan_microcode(void *data, size_t size,
struct ucode_cpu_info *uci,
@ -330,6 +350,9 @@ static __init struct microcode_intel *scan_microcode(void *data, size_t size,
if (!intel_find_matching_signature(data, &uci->cpu_sig))
continue;
if (!revision_is_safe(&uci->cpu_sig, mc_header->rev))
continue;
/*
* For saving the early microcode, find the matching revision which
* was loaded on the BSP.
@ -878,6 +901,9 @@ static enum ucode_state parse_microcode_blobs(int cpu, struct iov_iter *iter)
if (!intel_find_matching_signature(mc, &uci->cpu_sig))
continue;
if (!revision_is_safe(&uci->cpu_sig, mc_header.rev))
continue;
is_safe = ucode_validate_minrev(&mc_header);
if (force_minrev && !is_safe)
continue;

View File

@ -510,10 +510,9 @@ NOKPROBE_SYMBOL(kprobe_emulate_ret);
static void kprobe_emulate_call(struct kprobe *p, struct pt_regs *regs)
{
unsigned long func = regs->ip - INT3_INSN_SIZE + p->ainsn.size;
unsigned long ip = regs->ip - INT3_INSN_SIZE + p->ainsn.size;
func += p->ainsn.rel32;
int3_emulate_call(regs, func);
int3_emulate_call(regs, ip, ip + p->ainsn.rel32);
}
NOKPROBE_SYMBOL(kprobe_emulate_call);

View File

@ -744,15 +744,28 @@ void ahci_start_fis_rx(struct ata_port *ap)
struct ahci_port_priv *pp = ap->private_data;
u32 tmp;
/* set FIS registers */
/*
* On HBAs that only support 32-bit addressing PxCLBU is read only '0'.
* When applying the AHCI_HFLAG_32BIT_ONLY quirk, PxCLBU is RW, and the
* reset value is Implementation Specific, so we need to clear it to 0.
*/
if (hpriv->cap & HOST_CAP_64)
writel((pp->cmd_slot_dma >> 16) >> 16,
port_mmio + PORT_LST_ADDR_HI);
else if (hpriv->flags & AHCI_HFLAG_32BIT_ONLY)
writel(0, port_mmio + PORT_LST_ADDR_HI);
writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR);
/*
* On HBAs that only support 32-bit addressing PxFBU is read only '0'.
* When applying the AHCI_HFLAG_32BIT_ONLY quirk, PxFBU is RW, and the
* reset value is Implementation Specific, so we need to clear it to 0.
*/
if (hpriv->cap & HOST_CAP_64)
writel((pp->rx_fis_dma >> 16) >> 16,
port_mmio + PORT_FIS_ADDR_HI);
else if (hpriv->flags & AHCI_HFLAG_32BIT_ONLY)
writel(0, port_mmio + PORT_FIS_ADDR_HI);
writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR);
/* enable FIS reception */

View File

@ -620,10 +620,10 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev,
of_platform_device_create(child, NULL, NULL);
port_dev = of_find_device_by_node(child);
if (port_dev) {
rc = ahci_platform_get_regulator(hpriv, port,
&port_dev->dev);
put_device(&port_dev->dev);
if (rc == -EPROBE_DEFER)
goto err_out;
}

View File

@ -2297,10 +2297,9 @@ static unsigned int ata_scsiop_inq_89(struct ata_device *dev,
* logical block, so it can hold at most sector_size / 512 pages.
*
* Return: the maximum number of 512-byte pages a single translated WRITE SAME
* command may send to @dev (never less than one), that is the smaller of:
* - MAX PAGES PER DSM COMMAND (IDENTIFY DEVICE word 105), when the device
* reports a non-zero limit; and
* - the logical sector size expressed in 512-byte pages (see above).
* command may send to @dev, that is the smaller of MAX PAGES PER DSM COMMAND
* (IDENTIFY DEVICE word 105, when the device reports a non-zero limit) and
* the logical sector size expressed in 512-byte pages; never less than one.
*/
static unsigned int ata_dsm_trim_pages(struct ata_device *dev)
{

View File

@ -1099,6 +1099,11 @@ static void btintel_pcie_msix_tx_handle(struct btintel_pcie_data *data)
txq = &data->txq;
if (cr_hia >= txq->count) {
bt_dev_err(data->hdev, "TXQ: invalid cr_hia %u", cr_hia);
return;
}
while (cr_tia != cr_hia) {
data->tx_wait_done = true;
wake_up(&data->tx_wait_q);
@ -1650,6 +1655,11 @@ static void btintel_pcie_msix_rx_handle(struct btintel_pcie_data *data)
rxq = &data->rxq;
if (cr_hia >= rxq->count) {
bt_dev_err(hdev, "RXQ: invalid cr_hia %u", cr_hia);
return;
}
/* The firmware sends multiple CD in a single MSI-X and it needs to
* process all received CDs in this interrupt.
*/
@ -1657,6 +1667,12 @@ static void btintel_pcie_msix_rx_handle(struct btintel_pcie_data *data)
urbd1 = &rxq->urbd1s[cr_tia];
ipc_print_urbd1(data->hdev, urbd1, cr_tia);
if (urbd1->frbd_tag >= rxq->count) {
bt_dev_err(hdev, "RXQ: invalid frbd_tag %u",
urbd1->frbd_tag);
return;
}
buf = &rxq->bufs[urbd1->frbd_tag];
if (!buf) {
bt_dev_err(hdev, "RXQ: failed to get the DMA buffer for %d",

View File

@ -1388,9 +1388,11 @@ static int nxp_process_fw_dump(struct hci_dev *hdev, struct sk_buff *skb)
msecs_to_jiffies(20000));
}
err = hci_devcd_append(hdev, skb_clone(skb, GFP_ATOMIC));
if (err < 0)
goto free_skb;
if (IS_ENABLED(CONFIG_DEV_COREDUMP)) {
err = hci_devcd_append(hdev, skb_clone(skb, GFP_ATOMIC));
if (err < 0)
goto free_skb;
}
if (buf_len == 0) {
bt_dev_warn(hdev, "==== FW dump complete ===");

View File

@ -73,7 +73,7 @@ static unsigned long scpi_dvfs_recalc_rate(struct clk_hw *hw,
int idx = clk->scpi_ops->dvfs_get_idx(clk->id);
const struct scpi_opp *opp;
if (idx < 0)
if (idx < 0 || idx >= clk->info->count)
return 0;
opp = clk->info->opps + idx;
@ -272,10 +272,15 @@ static int scpi_clocks_probe(struct platform_device *pdev)
if (match->data != &scpi_dvfs_ops)
continue;
/* Add the virtual cpufreq device if it's DVFS clock provider */
if (cpufreq_dev)
continue;
cpufreq_dev = platform_device_register_simple("scpi-cpufreq",
-1, NULL, 0);
if (IS_ERR(cpufreq_dev))
PLATFORM_DEVID_NONE,
NULL, 0);
if (IS_ERR(cpufreq_dev)) {
pr_warn("unable to register cpufreq device");
cpufreq_dev = NULL;
}
}
return 0;
}

View File

@ -583,12 +583,29 @@ static int caam_jr_probe(struct platform_device *pdev)
struct caam_drv_private_jr *jrpriv;
static int total_jobrs;
void __iomem *ctrl;
struct resource *r;
int error;
int irq;
ctrl = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(ctrl))
return PTR_ERR(ctrl);
/*
* The job rings live inside the register window of their parent
* fsl,sec-v4.0 node, which caam_probe() already reserves (and maps)
* via devm_of_iomap(). A requested region that overlaps that
* reservation, e.g. from devm_platform_ioremap_resource(), would
* therefore fail with -EBUSY, so map the registers without claiming
* the region here.
*/
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r) {
dev_err(&pdev->dev, "platform_get_resource() failed\n");
return -EINVAL;
}
ctrl = devm_ioremap(&pdev->dev, r->start, resource_size(r));
if (!ctrl) {
dev_err(&pdev->dev, "devm_ioremap() failed\n");
return -ENOMEM;
}
irq = platform_get_irq(pdev, 0);
if (irq < 0)

View File

@ -43,7 +43,7 @@ config UDMABUF
config DMABUF_DEBUG
bool "DMA-BUF debug checks"
depends on DMA_SHARED_BUFFER
default y if DEBUG
default y if DEBUG_KERNEL
help
This option enables additional checks for DMA-BUF importers and
exporters. Specifically it validates that importers do not peek at the

View File

@ -5,16 +5,18 @@
*/
#include <linux/dma-buf-mapping.h>
#include <linux/dma-resv.h>
#include <linux/overflow.h>
#include <linux/align.h>
#define MAX_SG_ENT_SZ ALIGN_DOWN(UINT_MAX, PAGE_SIZE)
static struct scatterlist *fill_sg_entry(struct scatterlist *sgl, size_t length,
dma_addr_t addr)
{
unsigned int len, nents;
int i;
size_t len;
nents = DIV_ROUND_UP(length, UINT_MAX);
for (i = 0; i < nents; i++) {
len = min_t(size_t, length, UINT_MAX);
while (length) {
len = min(length, MAX_SG_ENT_SZ);
length -= len;
/*
* DMABUF abuses scatterlist to create a scatterlist
@ -24,8 +26,10 @@ static struct scatterlist *fill_sg_entry(struct scatterlist *sgl, size_t length,
* does not require the CPU list for mapping or unmapping.
*/
sg_set_page(sgl, NULL, 0, 0);
sg_dma_address(sgl) = addr + (dma_addr_t)i * UINT_MAX;
sg_dma_address(sgl) = addr;
sg_dma_len(sgl) = len;
addr += len;
/* Unconditionally advance. On last segment, this becomes NULL */
sgl = sg_next(sgl);
}
@ -40,15 +44,19 @@ static unsigned int calc_sg_nents(struct dma_iova_state *state,
size_t i;
if (!state || !dma_use_iova(state)) {
for (i = 0; i < nr_ranges; i++)
nents += DIV_ROUND_UP(phys_vec[i].len, UINT_MAX);
for (i = 0; i < nr_ranges; i++) {
unsigned int added = DIV_ROUND_UP(phys_vec[i].len, MAX_SG_ENT_SZ);
if (check_add_overflow(nents, added, &nents))
return 0;
}
} else {
/*
* In IOVA case, there is only one SG entry which spans
* for whole IOVA address space, but we need to make sure
* that it fits sg->length, maybe we need more.
*/
nents = DIV_ROUND_UP(size, UINT_MAX);
nents = DIV_ROUND_UP(size, MAX_SG_ENT_SZ);
}
return nents;
@ -95,9 +103,10 @@ struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach,
size_t nr_ranges, size_t size,
enum dma_data_direction dir)
{
unsigned int nents, mapped_len = 0;
struct dma_buf_dma *dma;
struct scatterlist *sgl;
size_t mapped_len = 0;
unsigned int nents;
dma_addr_t addr;
size_t i;
int ret;
@ -133,6 +142,8 @@ struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach,
}
nents = calc_sg_nents(dma->state, phys_vec, nr_ranges, size);
/* sg_alloc_table will cleanly fail and return -EINVAL if nents == 0 */
ret = sg_alloc_table(&dma->sgt, nents, GFP_KERNEL | __GFP_ZERO);
if (ret)
goto err_free_state;

View File

@ -1170,7 +1170,12 @@ const char __rcu *dma_fence_driver_name(struct dma_fence *fence)
/* RCU protection is required for safe access to returned string */
ops = rcu_dereference(fence->ops);
if (ops)
/*
* Make load ordering irrelevant by checking both signaled state and ops
* pointer and ops pointer is only set to NULL on newer implementations.
*/
if (!dma_fence_test_signaled_flag(fence) && ops)
return (const char __rcu *)ops->get_driver_name(fence);
else
return (const char __rcu *)"detached-driver";
@ -1203,7 +1208,12 @@ const char __rcu *dma_fence_timeline_name(struct dma_fence *fence)
/* RCU protection is required for safe access to returned string */
ops = rcu_dereference(fence->ops);
if (ops)
/*
* Make load ordering irrelevant by checking both signaled state and ops
* pointer and ops pointer is only set to NULL on newer implementations.
*/
if (!dma_fence_test_signaled_flag(fence) && ops)
return (const char __rcu *)ops->get_timeline_name(fence);
else
return (const char __rcu *)"signaled-timeline";

View File

@ -428,11 +428,18 @@ static void dma_device_release(struct kref *ref)
list_del_rcu(&device->global_node);
dma_channel_rebalance();
synchronize_rcu();
if (device->device_release)
device->device_release(device);
}
static int __must_check dma_device_get(struct dma_device *device)
{
lockdep_assert_held(&dma_list_mutex);
return kref_get_unless_zero(&device->ref);
}
static void dma_device_put(struct dma_device *device)
{
lockdep_assert_held(&dma_list_mutex);
@ -460,8 +467,7 @@ static int dma_chan_get(struct dma_chan *chan)
if (!try_module_get(owner))
return -ENODEV;
ret = kref_get_unless_zero(&chan->device->ref);
if (!ret) {
if (!dma_device_get(chan->device)) {
ret = -ENODEV;
goto module_put_out;
}
@ -495,10 +501,13 @@ static int dma_chan_get(struct dma_chan *chan)
*/
static void dma_chan_put(struct dma_chan *chan)
{
struct module *owner;
/* This channel is not in use, bail out */
if (!chan->client_count)
return;
owner = dma_chan_to_owner(chan);
chan->client_count--;
/* This channel is not in use anymore, free it */
@ -515,8 +524,10 @@ static void dma_chan_put(struct dma_chan *chan)
chan->route_data = NULL;
}
dma_device_put(chan->device);
module_put(dma_chan_to_owner(chan));
/* This channel is not in use anymore, drop the device ref */
if (!chan->client_count)
dma_device_put(chan->device);
module_put(owner);
}
enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie)

View File

@ -52,7 +52,6 @@
#define DCSR_EORINTR BIT(9) /* The end of Receive */
#define DRCMR_BASE 0x0100
#define DRCMR_EXT_BASE_K3 0x1000
#define DRCMR_EXT_BASE_DEFAULT 0x1100
#define DRCMR_REQ_LIMIT 64
#define DRCMR_MAPVLD BIT(7) /* Map Valid (read / write) */
@ -713,7 +712,7 @@ mmp_pdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl,
for_each_sg(sgl, sg, sg_len, i) {
addr = sg_dma_address(sg);
avail = sg_dma_len(sgl);
avail = sg_dma_len(sg);
do {
len = min_t(size_t, avail, PDMA_MAX_DESC_BYTES);
@ -1219,7 +1218,7 @@ static const struct mmp_pdma_ops spacemit_k3_pdma_ops = {
.get_desc_dst_addr = get_desc_dst_addr_64,
.run_bits = (DCSR_RUN | DCSR_LPAEEN | DCSR_EORIRQEN | DCSR_EORSTOPEN),
.dma_width = 64,
.drcmr_ext_base = DRCMR_EXT_BASE_K3,
.drcmr_ext_base = DRCMR_EXT_BASE_DEFAULT,
};
static const struct of_device_id mmp_pdma_dt_ids[] = {

View File

@ -744,6 +744,7 @@ pxad_alloc_desc(struct pxad_chan *chan, unsigned int nb_hw_desc)
sw_desc = kzalloc_flex(*sw_desc, hw_desc, nb_hw_desc, GFP_NOWAIT);
if (!sw_desc)
return NULL;
sw_desc->nb_desc = nb_hw_desc;
sw_desc->desc_pool = chan->desc_pool;
for (i = 0; i < nb_hw_desc; i++) {
@ -752,10 +753,10 @@ pxad_alloc_desc(struct pxad_chan *chan, unsigned int nb_hw_desc)
dev_err(&chan->vc.chan.dev->device,
"%s(): Couldn't allocate the %dth hw_desc from dma_pool %p\n",
__func__, i, sw_desc->desc_pool);
sw_desc->nb_desc = i;
goto err;
}
sw_desc->nb_desc++;
sw_desc->hw_desc[i] = desc;
if (i == 0)

View File

@ -1212,7 +1212,7 @@ static int sprd_dma_probe(struct platform_device *pdev)
ret = pm_runtime_get_sync(&pdev->dev);
if (ret < 0)
goto err_rpm;
goto err_register;
ret = dma_async_device_register(&sdev->dma_dev);
if (ret < 0) {
@ -1234,7 +1234,6 @@ static int sprd_dma_probe(struct platform_device *pdev)
err_register:
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
err_rpm:
sprd_dma_disable(sdev);
return ret;
}

View File

@ -354,8 +354,10 @@ static size_t sun6i_get_chan_size(struct sun6i_pchan *pchan)
size_t bytes;
dma_addr_t pos;
pos = readl(pchan->base + DMA_CHAN_LLI_ADDR);
bytes = readl(pchan->base + DMA_CHAN_CUR_CNT);
do {
pos = readl(pchan->base + DMA_CHAN_LLI_ADDR);
bytes = readl(pchan->base + DMA_CHAN_CUR_CNT);
} while (pos != readl(pchan->base + DMA_CHAN_LLI_ADDR));
if (pos == LLI_LAST_ITEM)
return bytes;
@ -979,7 +981,6 @@ static enum dma_status sun6i_dma_tx_status(struct dma_chan *chan,
struct sun6i_pchan *pchan = vchan->phy;
struct sun6i_dma_lli *lli;
struct virt_dma_desc *vd;
struct sun6i_desc *txd;
enum dma_status ret;
unsigned long flags;
size_t bytes = 0;
@ -991,9 +992,9 @@ static enum dma_status sun6i_dma_tx_status(struct dma_chan *chan,
spin_lock_irqsave(&vchan->vc.lock, flags);
vd = vchan_find_desc(&vchan->vc, cookie);
txd = to_sun6i_desc(&vd->tx);
if (vd) {
struct sun6i_desc *txd = to_sun6i_desc(&vd->tx);
for (lli = txd->v_lli; lli != NULL; lli = lli->v_lli_next)
bytes += lli->len;
} else if (!pchan || !pchan->desc) {

View File

@ -1243,8 +1243,9 @@ void k3_udma_glue_release_rx_chn(struct k3_udma_glue_rx_channel *rx_chn)
rx_chn->psil_paired = false;
}
for (i = 0; i < rx_chn->flow_num; i++)
k3_udma_glue_release_rx_flow(rx_chn, i);
if (rx_chn->flows)
for (i = 0; i < rx_chn->flow_num; i++)
k3_udma_glue_release_rx_flow(rx_chn, i);
if (xudma_rflow_is_gp(rx_chn->common.udmax, rx_chn->flow_id_base))
xudma_free_gp_rflow_range(rx_chn->common.udmax,

View File

@ -756,15 +756,25 @@ xilinx_aximcdma_alloc_tx_segment(struct xilinx_dma_chan *chan)
return segment;
}
static void xilinx_dma_clean_hw_desc(struct xilinx_axidma_desc_hw *hw)
static void xilinx_dma_clean_hw_desc(struct xilinx_dma_chan *chan,
struct xilinx_axidma_tx_segment *segment)
{
u32 next_desc = hw->next_desc;
u32 next_desc_msb = hw->next_desc_msb;
dma_addr_t next;
u32 i;
memset(hw, 0, sizeof(struct xilinx_axidma_desc_hw));
/*
* Restore the buffer descriptor's next descriptor pointer to the value
* set up in xilinx_dma_alloc_chan_resources(). Otherwise using the DMA
* in cyclic mode leaves the next descriptor pointer altered and
* prevents subsequent non-cyclic transfers.
*/
i = segment - chan->seg_v;
next = chan->seg_p +
sizeof(*chan->seg_v) * ((i + 1) % XILINX_DMA_NUM_DESCS);
hw->next_desc = next_desc;
hw->next_desc_msb = next_desc_msb;
memset(&segment->hw, 0, sizeof(segment->hw));
segment->hw.next_desc = lower_32_bits(next);
segment->hw.next_desc_msb = upper_32_bits(next);
}
static void xilinx_mcdma_clean_hw_desc(struct xilinx_aximcdma_desc_hw *hw)
@ -786,7 +796,7 @@ static void xilinx_mcdma_clean_hw_desc(struct xilinx_aximcdma_desc_hw *hw)
static void xilinx_dma_free_tx_segment(struct xilinx_dma_chan *chan,
struct xilinx_axidma_tx_segment *segment)
{
xilinx_dma_clean_hw_desc(&segment->hw);
xilinx_dma_clean_hw_desc(chan, segment);
list_add_tail(&segment->node, &chan->free_seg_list);
}
@ -920,9 +930,9 @@ static void xilinx_dma_free_descriptors(struct xilinx_dma_chan *chan)
spin_lock_irqsave(&chan->lock, flags);
xilinx_dma_free_desc_list(chan, &chan->pending_list);
xilinx_dma_free_desc_list(chan, &chan->done_list);
xilinx_dma_free_desc_list(chan, &chan->active_list);
xilinx_dma_free_desc_list(chan, &chan->pending_list);
spin_unlock_irqrestore(&chan->lock, flags);
}

View File

@ -1210,8 +1210,7 @@ dpll_pin_ref_sync_state_set(struct dpll_pin *pin,
struct dpll_device *dpll;
int ret;
ref_sync_pin = xa_find(&pin->ref_sync_pins, &ref_sync_pin_idx,
ULONG_MAX, XA_PRESENT);
ref_sync_pin = xa_load(&pin->ref_sync_pins, ref_sync_pin_idx);
if (!ref_sync_pin) {
NL_SET_ERR_MSG(extack, "reference sync pin not found");
return -EINVAL;

View File

@ -2225,6 +2225,7 @@ static void ffa_remove(struct platform_device *pdev)
static struct platform_driver ffa_driver = {
.probe = ffa_probe,
.remove = ffa_remove,
.shutdown = ffa_remove,
.driver = {
.name = FFA_PLATFORM_NAME,
},

View File

@ -477,7 +477,7 @@ void *scmi_notification_instance_data_get(const struct scmi_handle *handle)
* - exactly 'next_token' may be NOT available so pick xfer_id >= next_token
* using find_next_zero_bit() starting from candidate next_token bit
*
* - all tokens ahead upto (MSG_TOKEN_ID_MASK - 1) are used in-flight but we
* - all tokens ahead up to (MSG_TOKEN_ID_MASK - 1) are used in-flight but we
* are plenty of free tokens at start, so try a second pass using
* find_next_zero_bit() and starting from 0.
*

View File

@ -631,8 +631,8 @@ static struct scpi_dvfs_info *scpi_dvfs_get_info(u8 domain)
if (ret)
return ERR_PTR(ret);
if (!buf.opp_count)
return ERR_PTR(-ENOENT);
if (!buf.opp_count || buf.opp_count > MAX_DVFS_OPPS)
return ERR_PTR(-EINVAL);
info = kmalloc_obj(*info);
if (!info)
@ -661,12 +661,15 @@ static struct scpi_dvfs_info *scpi_dvfs_get_info(u8 domain)
static int scpi_dev_domain_id(struct device *dev)
{
struct of_phandle_args clkspec;
int domain;
if (of_parse_phandle_with_args(dev->of_node, "clocks", "#clock-cells",
0, &clkspec))
return -EINVAL;
return clkspec.args[0];
domain = clkspec.args[0];
of_node_put(clkspec.np);
return domain;
}
static struct scpi_dvfs_info *scpi_dvfs_info(struct device *dev)

View File

@ -621,6 +621,9 @@ enum amdgpu_enforce_isolation_mode {
struct amdgpu_device {
struct device *dev;
struct pci_dev *pdev;
/* The two ends of the physical PCIe link outside the device. */
struct pci_dev *link_dev;
struct pci_dev *link_partner;
struct drm_device ddev;
#ifdef CONFIG_DRM_AMD_ACP

View File

@ -330,7 +330,7 @@ void amdgpu_amdkfd_clear_kfd_mapping(struct amdgpu_device *adev)
struct kfd_dev *kfd = adev->kfd.dev;
unsigned int i;
if (!kfd)
if (!kfd || !kfd->init_complete)
return;
for (i = 0; i < kfd->num_nodes; i++) {

View File

@ -1954,18 +1954,17 @@ static void amdgpu_uid_fini(struct amdgpu_device *adev)
adev->uid_info = NULL;
}
static struct pci_dev *amdgpu_device_find_parent(struct amdgpu_device *adev)
static void amdgpu_device_init_pcie_links(struct amdgpu_device *adev)
{
struct pci_dev *parent = adev->pdev;
adev->link_dev = adev->pdev;
adev->link_partner = pci_upstream_bridge(adev->link_dev);
/* skip upstream/downstream switches internal to dGPU */
while ((parent = pci_upstream_bridge(parent))) {
if (parent->vendor == PCI_VENDOR_ID_ATI)
continue;
break;
/* Skip upstream/downstream switches internal to the dGPU. */
while (adev->link_partner &&
adev->link_partner->vendor == PCI_VENDOR_ID_ATI) {
adev->link_dev = adev->link_partner;
adev->link_partner = pci_upstream_bridge(adev->link_dev);
}
return parent;
}
/**
@ -1981,7 +1980,6 @@ static struct pci_dev *amdgpu_device_find_parent(struct amdgpu_device *adev)
static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
{
struct amdgpu_ip_block *ip_block;
struct pci_dev *parent;
bool total, skip_bios, early_full_gpu_access = false;
uint32_t bios_flags;
int i, r;
@ -2077,10 +2075,9 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
!dev_is_removable(&adev->pdev->dev))
adev->flags |= AMD_IS_PX;
if (!(adev->flags & AMD_IS_APU)) {
parent = amdgpu_device_find_parent(adev);
adev->has_pr3 = parent ? pci_pr3_present(parent) : false;
}
if (!(adev->flags & AMD_IS_APU))
adev->has_pr3 = adev->link_partner &&
pci_pr3_present(adev->link_partner);
adev->pm.pp_feature = amdgpu_pp_feature_mask;
if (amdgpu_sriov_vf(adev) || sched_policy == KFD_SCHED_POLICY_NO_HWS)
@ -3776,6 +3773,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
adev->shutdown = false;
adev->flags = flags;
amdgpu_device_init_pcie_links(adev);
if (amdgpu_force_asic_type >= 0 && amdgpu_force_asic_type < CHIP_LAST)
adev->asic_type = amdgpu_force_asic_type;
@ -4337,7 +4335,7 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
void amdgpu_device_fini_sw(struct amdgpu_device *adev)
{
int i, idx;
int i;
bool px;
amdgpu_device_ip_fini(adev);
@ -4379,11 +4377,9 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev)
if ((adev->pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
vga_client_unregister(adev->pdev);
if (drm_dev_enter(adev_to_drm(adev), &idx)) {
if (adev->rmmio) {
iounmap(adev->rmmio);
adev->rmmio = NULL;
drm_dev_exit(idx);
}
if (IS_ENABLED(CONFIG_PERF_EVENTS))
@ -5872,11 +5868,9 @@ static void amdgpu_device_partner_bandwidth(struct amdgpu_device *adev,
*width = PCIE_LNK_WIDTH_UNKNOWN;
if (amdgpu_device_pcie_dynamic_switching_supported(adev)) {
struct pci_dev *parent = amdgpu_device_find_parent(adev);
if (parent) {
*speed = pcie_get_speed_cap(parent);
*width = pcie_get_width_cap(parent);
if (adev->link_partner) {
*speed = pcie_get_speed_cap(adev->link_partner);
*width = pcie_get_width_cap(adev->link_partner);
}
} else {
/* use the current speeds rather than max if switching is not supported */
@ -5898,21 +5892,11 @@ static void amdgpu_device_gpu_bandwidth(struct amdgpu_device *adev,
enum pci_bus_speed *speed,
enum pcie_link_width *width)
{
struct pci_dev *parent = adev->pdev;
if (!speed || !width)
return;
/* use the device itself */
*speed = pcie_get_speed_cap(adev->pdev);
*width = pcie_get_width_cap(adev->pdev);
/* use the link outside the device */
parent = amdgpu_device_find_parent(adev);
if (parent) {
*speed = pcie_get_speed_cap(parent);
*width = pcie_get_width_cap(parent);
}
*speed = pcie_get_speed_cap(adev->link_dev);
*width = pcie_get_width_cap(adev->link_dev);
}
/**

View File

@ -43,6 +43,7 @@
#include <linux/dma-buf.h>
#include <linux/dma-fence-array.h>
#include <linux/pci-p2pdma.h>
#include <linux/pm_runtime.h>
static const struct dma_buf_attach_ops amdgpu_dma_buf_attach_ops;
@ -100,15 +101,54 @@ static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf,
pci_p2pdma_distance(adev->pdev, attach->dev, false) < 0)
attach->peer2peer = false;
/*
* Only allow P2P while the exporter is active, and keep it active
* until detach. With runtime PM disabled take a plain reference so
* the put in detach stays balanced.
*/
if (attach->peer2peer) {
struct device *dev = adev_to_drm(adev)->dev;
int ret = pm_runtime_get_if_active(dev);
if (!ret)
attach->peer2peer = false;
else if (ret < 0)
pm_runtime_get_noresume(dev);
}
r = dma_resv_lock(bo->tbo.base.resv, NULL);
if (r)
return r;
goto err_pm_put;
amdgpu_vm_bo_update_shared(bo);
dma_resv_unlock(bo->tbo.base.resv);
return 0;
err_pm_put:
if (attach->peer2peer)
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
return r;
}
/**
* amdgpu_dma_buf_detach - &dma_buf_ops.detach implementation
*
* @dmabuf: DMA-buf where we remove the attachment from
* @attach: the attachment to remove
*
* Drop the runtime PM reference taken in amdgpu_dma_buf_attach().
*/
static void amdgpu_dma_buf_detach(struct dma_buf *dmabuf,
struct dma_buf_attachment *attach)
{
struct drm_gem_object *obj = dmabuf->priv;
struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
if (attach->peer2peer)
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
}
/**
@ -350,6 +390,7 @@ static void amdgpu_dma_buf_vunmap(struct dma_buf *dma_buf, struct iosys_map *map
const struct dma_buf_ops amdgpu_dmabuf_ops = {
.attach = amdgpu_dma_buf_attach,
.detach = amdgpu_dma_buf_detach,
.pin = amdgpu_dma_buf_pin,
.unpin = amdgpu_dma_buf_unpin,
.map_dma_buf = amdgpu_dma_buf_map,

View File

@ -535,7 +535,7 @@ static void nbio_v7_9_handle_ras_controller_intr_no_bifring(struct amdgpu_device
RAS_CNTLR_INTERRUPT_CLEAR, 1);
WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_DOORBELL_INT_CNTL, bif_doorbell_intr_cntl);
if (!ras->disable_ras_err_cnt_harvest) {
if (ras && !ras->disable_ras_err_cnt_harvest && obj) {
/*
* clear error status after ras_controller_intr
* according to hw team and count ue number

View File

@ -770,10 +770,12 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm,
mqd_mgr = dqm->mqd_mgrs[get_mqd_type_from_queue_type(
q->properties.type)];
if (qd && !mqd_mgr->restore_mqd) {
pr_debug("restore_mqd not implemented for this GPU\n");
pr_debug("restore_mqd not implemented for queue type %d\n",
q->properties.type);
retval = -EOPNOTSUPP;
goto deallocate_vmid;
}
if (q->properties.type == KFD_QUEUE_TYPE_COMPUTE) {
retval = allocate_hqd(dqm, q);
if (retval)
@ -2250,7 +2252,8 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
mqd_mgr = dqm->mqd_mgrs[get_mqd_type_from_queue_type(
q->properties.type)];
if (qd && !mqd_mgr->restore_mqd) {
pr_debug("restore_mqd not implemented for this GPU\n");
pr_debug("restore_mqd not implemented for queue type %d\n",
q->properties.type);
retval = -EOPNOTSUPP;
goto out_deallocate_doorbell;
}

View File

@ -204,7 +204,7 @@ static void update_mqd(struct mqd_manager *mm, void *mqd,
* is safe, giving a maximum field value of 0xA.
*/
m->cp_hqd_eop_control = q->eop_ring_buffer_size ? min(0xA,
ffs(q->eop_ring_buffer_size / sizeof(unsigned int)) - 1 - 1) : 0;
ffs(q->eop_ring_buffer_size / sizeof(unsigned int) / 4)) : 0;
m->cp_hqd_eop_base_addr_lo =
lower_32_bits(q->eop_ring_buffer_address >> 8);
m->cp_hqd_eop_base_addr_hi =

View File

@ -242,7 +242,7 @@ static void update_mqd(struct mqd_manager *mm, void *mqd,
* is safe, giving a maximum field value of 0xA.
*/
m->cp_hqd_eop_control = q->eop_ring_buffer_size ? min(0xA,
ffs(q->eop_ring_buffer_size / sizeof(unsigned int)) - 1 - 1) : 0;
ffs(q->eop_ring_buffer_size / sizeof(unsigned int) / 4)) : 0;
m->cp_hqd_eop_base_addr_lo =
lower_32_bits(q->eop_ring_buffer_address >> 8);
m->cp_hqd_eop_base_addr_hi =

View File

@ -217,7 +217,7 @@ static void update_mqd(struct mqd_manager *mm, void *mqd,
* is safe, giving a maximum field value of 0xA.
*/
m->cp_hqd_eop_control = q->eop_ring_buffer_size ? min(0xA,
ffs(q->eop_ring_buffer_size / sizeof(unsigned int)) - 1 - 1) : 0;
ffs(q->eop_ring_buffer_size / sizeof(unsigned int) / 4)) : 0;
m->cp_hqd_eop_base_addr_lo =
lower_32_bits(q->eop_ring_buffer_address >> 8);
m->cp_hqd_eop_base_addr_hi =
@ -380,6 +380,63 @@ static int debugfs_show_mqd_sdma(struct seq_file *m, void *data)
#endif
static void restore_mqd(struct mqd_manager *mm, void **mqd,
struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
struct queue_properties *qp, const void *mqd_src,
const void *ctl_stack_src, const u32 ctl_stack_size)
{
u64 addr;
struct v12_compute_mqd *m;
m = (struct v12_compute_mqd *)mqd_mem_obj->cpu_ptr;
addr = mqd_mem_obj->gpu_addr;
memset(m, 0, AMDGPU_MQD_SIZE_ALIGN(mm->mqd_size));
memcpy(m, mqd_src, sizeof(*m));
/* Update MQD base address to the newly allocated location */
m->cp_mqd_base_addr_lo = lower_32_bits(addr);
m->cp_mqd_base_addr_hi = upper_32_bits(addr);
m->cp_hqd_pq_doorbell_control &=
~CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET_MASK;
m->cp_hqd_pq_doorbell_control |=
qp->doorbell_off << CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET__SHIFT;
pr_debug("cp_hqd_pq_doorbell_control 0x%x\n", m->cp_hqd_pq_doorbell_control);
*mqd = m;
if (gart_addr)
*gart_addr = addr;
qp->is_active = 0;
}
static void restore_mqd_sdma(struct mqd_manager *mm, void **mqd,
struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
struct queue_properties *qp,
const void *mqd_src,
const void *ctl_stack_src,
const u32 ctl_stack_size)
{
u64 addr;
struct v12_sdma_mqd *m;
m = (struct v12_sdma_mqd *)mqd_mem_obj->cpu_ptr;
addr = mqd_mem_obj->gpu_addr;
memset(m, 0, AMDGPU_MQD_SIZE_ALIGN(mm->mqd_size));
memcpy(m, mqd_src, sizeof(*m));
m->sdmax_rlcx_doorbell_offset =
qp->doorbell_off << SDMA0_QUEUE0_DOORBELL_OFFSET__OFFSET__SHIFT;
*mqd = m;
if (gart_addr)
*gart_addr = addr;
qp->is_active = 0;
}
struct mqd_manager *mqd_manager_init_v12(enum KFD_MQD_TYPE type,
struct kfd_node *dev)
{
@ -407,6 +464,7 @@ struct mqd_manager *mqd_manager_init_v12(enum KFD_MQD_TYPE type,
mqd->mqd_size = sizeof(struct v12_compute_mqd);
mqd->get_wave_state = get_wave_state;
mqd->mqd_stride = kfd_mqd_stride;
mqd->restore_mqd = restore_mqd;
#if defined(CONFIG_DEBUG_FS)
mqd->debugfs_show_mqd = debugfs_show_mqd;
#endif
@ -453,6 +511,7 @@ struct mqd_manager *mqd_manager_init_v12(enum KFD_MQD_TYPE type,
mqd->is_occupied = kfd_is_occupied_sdma;
mqd->mqd_size = sizeof(struct v12_sdma_mqd);
mqd->mqd_stride = kfd_mqd_stride;
mqd->restore_mqd = restore_mqd_sdma;
#if defined(CONFIG_DEBUG_FS)
mqd->debugfs_show_mqd = debugfs_show_mqd_sdma;
#endif

View File

@ -295,7 +295,7 @@ static void update_mqd(struct mqd_manager *mm, void *mqd,
* is safe, giving a maximum field value of 0xA.
*/
m->cp_hqd_eop_control = q->eop_ring_buffer_size ? min(0xA,
ffs(q->eop_ring_buffer_size / sizeof(unsigned int)) - 1 - 1) : 0;
ffs(q->eop_ring_buffer_size / sizeof(unsigned int) / 4)) : 0;
m->cp_hqd_eop_base_addr_lo =
lower_32_bits(q->eop_ring_buffer_address >> 8);
m->cp_hqd_eop_base_addr_hi =
@ -641,6 +641,72 @@ static int debugfs_show_mqd_sdma(struct seq_file *m, void *data)
#endif
static void restore_mqd_v12_1(struct mqd_manager *mm, void **mqd,
struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
struct queue_properties *qp, const void *mqd_src,
const void *ctl_stack_src, const u32 ctl_stack_size)
{
u64 addr;
struct v12_1_compute_mqd *m;
/*
* GFX12.1 is multi-XCC capable but this restore handles XCC0 only.
* Multi-XCC CRIU restore is currently unreachable because
* kfd_criu_restore_queue() validates against unscaled mqd_size.
*/
if (NUM_XCC(mm->dev->xcc_mask) > 1)
pr_warn_once("GFX12.1 multi-XCC CRIU restore not fully supported\n");
m = (struct v12_1_compute_mqd *)mqd_mem_obj->cpu_ptr;
addr = mqd_mem_obj->gpu_addr;
memset(m, 0, AMDGPU_MQD_SIZE_ALIGN(mm->mqd_size) *
NUM_XCC(mm->dev->xcc_mask));
memcpy(m, mqd_src, sizeof(*m));
/* Update MQD base address to the newly allocated location */
m->cp_mqd_base_addr_lo = lower_32_bits(addr);
m->cp_mqd_base_addr_hi = upper_32_bits(addr);
m->cp_hqd_pq_doorbell_control &=
~CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET_MASK;
m->cp_hqd_pq_doorbell_control |=
qp->doorbell_off << CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET__SHIFT;
pr_debug("cp_hqd_pq_doorbell_control 0x%x\n", m->cp_hqd_pq_doorbell_control);
*mqd = m;
if (gart_addr)
*gart_addr = addr;
qp->is_active = 0;
}
static void restore_mqd_sdma_v12_1(struct mqd_manager *mm, void **mqd,
struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
struct queue_properties *qp,
const void *mqd_src,
const void *ctl_stack_src,
const u32 ctl_stack_size)
{
u64 addr;
struct v12_sdma_mqd *m;
m = (struct v12_sdma_mqd *)mqd_mem_obj->cpu_ptr;
addr = mqd_mem_obj->gpu_addr;
memset(m, 0, AMDGPU_MQD_SIZE_ALIGN(mm->mqd_size));
memcpy(m, mqd_src, sizeof(*m));
m->sdmax_rlcx_doorbell_offset =
qp->doorbell_off << SDMA0_SDMA_QUEUE0_DOORBELL_OFFSET__OFFSET__SHIFT;
*mqd = m;
if (gart_addr)
*gart_addr = addr;
qp->is_active = 0;
}
struct mqd_manager *mqd_manager_init_v12_1(enum KFD_MQD_TYPE type,
struct kfd_node *dev)
{
@ -668,6 +734,7 @@ struct mqd_manager *mqd_manager_init_v12_1(enum KFD_MQD_TYPE type,
mqd->mqd_size = sizeof(struct v12_1_compute_mqd);
mqd->get_wave_state = get_wave_state_v12_1;
mqd->mqd_stride = kfd_mqd_stride;
mqd->restore_mqd = restore_mqd_v12_1;
#if defined(CONFIG_DEBUG_FS)
mqd->debugfs_show_mqd = debugfs_show_mqd;
#endif
@ -714,6 +781,7 @@ struct mqd_manager *mqd_manager_init_v12_1(enum KFD_MQD_TYPE type,
mqd->is_occupied = kfd_is_occupied_sdma;
mqd->mqd_size = sizeof(struct v12_sdma_mqd);
mqd->mqd_stride = kfd_mqd_stride;
mqd->restore_mqd = restore_mqd_sdma_v12_1;
#if defined(CONFIG_DEBUG_FS)
mqd->debugfs_show_mqd = debugfs_show_mqd_sdma;
#endif

View File

@ -285,6 +285,10 @@ static void update_mqd(struct mqd_manager *mm, void *mqd,
1 << CP_HQD_IB_CONTROL__IB_EXE_DISABLE__SHIFT;
/*
* The lowest 6 bits of eop_control store the EOP ring size. If
* their value is X, the ring size is 2^(X + 1) dwords, or
* 2^(X + 3) bytes.
*
* HW does not clamp this field correctly. Maximum EOP queue size
* is constrained by per-SE EOP done signal count, which is 8-bit.
* Limit is 0xFF EOP entries (= 0x7F8 dwords). CP will not submit
@ -296,7 +300,7 @@ static void update_mqd(struct mqd_manager *mm, void *mqd,
*
*/
m->cp_hqd_eop_control = q->eop_ring_buffer_size ?
min(0xA, order_base_2(q->eop_ring_buffer_size / 4) - 1) : 0;
min(0xA, order_base_2(q->eop_ring_buffer_size / 8)) : 0;
m->cp_hqd_eop_base_addr_lo =
lower_32_bits(q->eop_ring_buffer_address >> 8);

View File

@ -208,6 +208,9 @@ static void __update_mqd(struct mqd_manager *mm, void *mqd,
mtype << CP_HQD_IB_CONTROL__MTYPE__SHIFT;
/*
* The lowest 6 bits of eop_control store the EOP ring size. If
* their value is X, the ring size is 2^(X + 1) dwords, or
* 2^(X + 3) bytes.
* HW does not clamp this field correctly. Maximum EOP queue size
* is constrained by per-SE EOP done signal count, which is 8-bit.
* Limit is 0xFF EOP entries (= 0x7F8 dwords). CP will not submit
@ -215,7 +218,7 @@ static void __update_mqd(struct mqd_manager *mm, void *mqd,
* is safe, giving a maximum field value of 0xA.
*/
m->cp_hqd_eop_control |= q->eop_ring_buffer_size ? min(0xA,
order_base_2(q->eop_ring_buffer_size / 4) - 1) : 0;
order_base_2(q->eop_ring_buffer_size / 8)) : 0;
m->cp_hqd_eop_base_addr_lo =
lower_32_bits(q->eop_ring_buffer_address >> 8);
m->cp_hqd_eop_base_addr_hi =

View File

@ -1420,7 +1420,7 @@ static void dm_gpureset_toggle_interrupts(struct amdgpu_device *adev,
if (acrtc && state->stream_status[i].plane_count != 0 &&
amdgpu_ip_version(adev, DCE_HWIP, 0) == 0) {
irq_source = IRQ_TYPE_PFLIP + acrtc->otg_inst;
rc = dc_interrupt_set(adev->dm.dc, irq_source, enable) ? 0 : -EBUSY;
rc = amdgpu_dm_irq_set(adev, irq_source, enable) ? 0 : -EBUSY;
if (rc)
drm_warn(adev_to_drm(adev), "Failed to %s pflip interrupts\n",
enable ? "enable" : "disable");
@ -1444,7 +1444,7 @@ static void dm_gpureset_toggle_interrupts(struct amdgpu_device *adev,
/* During gpu-reset we disable and then enable vblank irq, so
* don't use amdgpu_irq_get/put() to avoid refcount change.
*/
if (!dc_interrupt_set(adev->dm.dc, irq_source, enable))
if (!amdgpu_dm_irq_set(adev, irq_source, enable))
drm_warn(adev_to_drm(adev), "Failed to %sable vblank interrupt\n", enable ? "en" : "dis");
} else if (acrtc && state->stream_status[i].plane_count != 0) {

View File

@ -552,6 +552,18 @@ struct amdgpu_display_manager {
struct common_irq_params
vupdate_params[DC_IRQ_SOURCE_VUPDATE6 - DC_IRQ_SOURCE_VUPDATE1 + 1];
/**
* @irq_reg_lock:
*
* Serializes the read-modify-writes of the HW interrupt control
* registers. Several interrupt sources share one register - e.g. the
* enable and clear bits of both VSTARTUP (vblank) and VUPDATE_NO_LOCK
* live in OTG_GLOBAL_SYNC_STATUS. Therefore, enabling one source must
* not race with acking another. Held only across amdgpu_dm_irq_set()
* and amdgpu_dm_irq_ack().
*/
spinlock_t irq_reg_lock;
/**
* @dmub_trace_params:
*

View File

@ -31,6 +31,7 @@
#include "amdgpu_dm_psr.h"
#include "amdgpu_dm_replay.h"
#include "amdgpu_dm_crtc.h"
#include "amdgpu_dm_irq.h"
#include "amdgpu_dm_plane.h"
#include "amdgpu_dm_trace.h"
#include "amdgpu_dm_debugfs.h"
@ -91,7 +92,7 @@ int amdgpu_dm_crtc_set_vupdate_irq(struct drm_crtc *crtc, bool enable)
irq_source = IRQ_TYPE_VUPDATE + acrtc->otg_inst;
rc = dc_interrupt_set(adev->dm.dc, irq_source, enable) ? 0 : -EBUSY;
rc = amdgpu_dm_irq_set(adev, irq_source, enable) ? 0 : -EBUSY;
DRM_DEBUG_VBL("crtc %d - vupdate irq %sabling: r=%d\n",
acrtc->crtc_id, enable ? "en" : "dis", rc);

View File

@ -1439,12 +1439,13 @@ void dm_helpers_free_gpu_mem(
bool dm_helpers_dmub_outbox_interrupt_control(struct dc_context *ctx, bool enable)
{
struct amdgpu_device *adev = ctx->driver_context;
enum dc_irq_source irq_source;
bool ret;
irq_source = DC_IRQ_SOURCE_DMCUB_OUTBOX;
ret = dc_interrupt_set(ctx->dc, irq_source, enable);
ret = amdgpu_dm_irq_set(adev, irq_source, enable);
DRM_DEBUG_DRIVER("Dmub trace irq %sabling: r=%d\n",
enable ? "en" : "dis", ret);

View File

@ -396,6 +396,7 @@ int amdgpu_dm_irq_init(struct amdgpu_device *adev)
DRM_DEBUG_KMS("DM_IRQ\n");
spin_lock_init(&adev->dm.irq_handler_list_table_lock);
spin_lock_init(&adev->dm.irq_reg_lock);
adev->dm.irq_wq = alloc_workqueue("amdgpu_dm_irq",
WQ_UNBOUND | WQ_HIGHPRI, 0);
@ -530,7 +531,7 @@ void amdgpu_dm_irq_suspend(struct amdgpu_device *adev)
*/
for (src = DC_IRQ_SOURCE_HPD1; src <= DC_IRQ_SOURCE_HPD6RX; src++) {
hnd_list_l = &adev->dm.irq_handler_list_low_tab[src];
dc_interrupt_set(adev->dm.dc, src, false);
amdgpu_dm_irq_set(adev, src, false);
DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
@ -568,7 +569,7 @@ void amdgpu_dm_irq_resume_early(struct amdgpu_device *adev)
hnd_list_l = &adev->dm.irq_handler_list_low_tab[src];
hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))
dc_interrupt_set(adev->dm.dc, src, true);
amdgpu_dm_irq_set(adev, src, true);
}
DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
@ -594,7 +595,7 @@ void amdgpu_dm_irq_resume_late(struct amdgpu_device *adev)
hnd_list_l = &adev->dm.irq_handler_list_low_tab[src];
hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))
dc_interrupt_set(adev->dm.dc, src, true);
amdgpu_dm_irq_set(adev, src, true);
}
DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
@ -690,6 +691,23 @@ STATIC_IFN_KUNIT void amdgpu_dm_irq_immediate_work(struct amdgpu_device *adev,
}
EXPORT_IF_KUNIT(amdgpu_dm_irq_immediate_work);
bool amdgpu_dm_irq_set(struct amdgpu_device *adev, enum dc_irq_source src,
bool enable)
{
guard(spinlock_irqsave)(&adev->dm.irq_reg_lock);
return dc_interrupt_set(adev->dm.dc, src, enable);
}
EXPORT_IF_KUNIT(amdgpu_dm_irq_set);
void amdgpu_dm_irq_ack(struct amdgpu_device *adev, enum dc_irq_source src)
{
guard(spinlock_irqsave)(&adev->dm.irq_reg_lock);
dc_interrupt_ack(adev->dm.dc, src);
}
EXPORT_IF_KUNIT(amdgpu_dm_irq_ack);
/**
* amdgpu_dm_irq_handler - Generic DM IRQ handler
* @adev: amdgpu base driver device containing the DM device
@ -710,7 +728,7 @@ STATIC_IFN_KUNIT int amdgpu_dm_irq_handler(struct amdgpu_device *adev,
entry->src_id,
entry->src_data[0]);
dc_interrupt_ack(adev->dm.dc, src);
amdgpu_dm_irq_ack(adev, src);
/* Call high irq work immediately */
amdgpu_dm_irq_immediate_work(adev, src);
@ -750,7 +768,7 @@ STATIC_IFN_KUNIT int amdgpu_dm_set_hpd_irq_state(struct amdgpu_device *adev,
enum dc_irq_source src = amdgpu_dm_hpd_to_dal_irq_source(type);
bool st = (state == AMDGPU_IRQ_STATE_ENABLE);
dc_interrupt_set(adev->dm.dc, src, st);
amdgpu_dm_irq_set(adev, src, st);
return 0;
}
EXPORT_IF_KUNIT(amdgpu_dm_set_hpd_irq_state);
@ -785,7 +803,7 @@ static inline int dm_irq_state(struct amdgpu_device *adev,
if (dc && dc->caps.ips_support && dc->idle_optimizations_allowed)
dc_allow_idle_optimizations(dc, false);
dc_interrupt_set(adev->dm.dc, irq_source, st);
amdgpu_dm_irq_set(adev, irq_source, st);
return 0;
}
@ -842,7 +860,7 @@ STATIC_IFN_KUNIT int amdgpu_dm_set_dmub_outbox_irq_state(struct amdgpu_device *a
enum dc_irq_source irq_source = DC_IRQ_SOURCE_DMCUB_OUTBOX;
bool st = (state == AMDGPU_IRQ_STATE_ENABLE);
dc_interrupt_set(adev->dm.dc, irq_source, st);
amdgpu_dm_irq_set(adev, irq_source, st);
return 0;
}
EXPORT_IF_KUNIT(amdgpu_dm_set_dmub_outbox_irq_state);
@ -870,7 +888,7 @@ STATIC_IFN_KUNIT int amdgpu_dm_set_dmub_trace_irq_state(struct amdgpu_device *ad
enum dc_irq_source irq_source = DC_IRQ_SOURCE_DMCUB_OUTBOX0;
bool st = (state == AMDGPU_IRQ_STATE_ENABLE);
dc_interrupt_set(adev->dm.dc, irq_source, st);
amdgpu_dm_irq_set(adev, irq_source, st);
return 0;
}
EXPORT_IF_KUNIT(amdgpu_dm_set_dmub_trace_irq_state);
@ -937,9 +955,7 @@ EXPORT_IF_KUNIT(amdgpu_dm_set_irq_funcs);
void amdgpu_dm_outbox_init(struct amdgpu_device *adev)
{
dc_interrupt_set(adev->dm.dc,
DC_IRQ_SOURCE_DMCUB_OUTBOX,
true);
amdgpu_dm_irq_set(adev, DC_IRQ_SOURCE_DMCUB_OUTBOX, true);
}
EXPORT_IF_KUNIT(amdgpu_dm_outbox_init);
@ -962,7 +978,7 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev)
/* First, clear all hpd and hpdrx interrupts */
for (i = DC_IRQ_SOURCE_HPD1; i <= DC_IRQ_SOURCE_HPD6RX; i++) {
if (!dc_interrupt_set(adev->dm.dc, i, false))
if (!amdgpu_dm_irq_set(adev, i, false))
drm_err(dev, "Failed to clear hpd(rx) source=%d on init\n",
i);
}
@ -991,7 +1007,7 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev)
* of dm. Note that only hpd interrupt types are registered with
* base driver; hpd_rx types aren't. IOW, amdgpu_irq_get/put on
* hpd_rx isn't available. DM currently controls hpd_rx
* explicitly with dc_interrupt_set()
* explicitly with amdgpu_dm_irq_set()
*/
if (dc_link->irq_source_hpd != DC_IRQ_SOURCE_INVALID) {
irq_type = dc_link->irq_source_hpd - DC_IRQ_SOURCE_HPD1;
@ -1000,23 +1016,21 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev)
* and what bios reports as the # of connectors with hpd
* sources. Since the # of hpd source types registered
* with base driver == mode_info.num_hpd, we have to
* fallback to dc_interrupt_set for the remaining types.
* fallback to amdgpu_dm_irq_set for the remaining types.
*/
if (irq_type < adev->mode_info.num_hpd) {
if (amdgpu_irq_get(adev, &adev->hpd_irq, irq_type))
drm_err(dev, "DM_IRQ: Failed get HPD for source=%d)!\n",
dc_link->irq_source_hpd);
} else {
dc_interrupt_set(adev->dm.dc,
dc_link->irq_source_hpd,
true);
amdgpu_dm_irq_set(adev, dc_link->irq_source_hpd,
true);
}
}
if (dc_link->irq_source_hpd_rx != DC_IRQ_SOURCE_INVALID) {
dc_interrupt_set(adev->dm.dc,
dc_link->irq_source_hpd_rx,
true);
amdgpu_dm_irq_set(adev, dc_link->irq_source_hpd_rx,
true);
}
}
drm_connector_list_iter_end(&iter);
@ -1061,16 +1075,14 @@ void amdgpu_dm_hpd_fini(struct amdgpu_device *adev)
drm_err(dev, "DM_IRQ: Failed put HPD for source=%d!\n",
dc_link->irq_source_hpd);
} else {
dc_interrupt_set(adev->dm.dc,
dc_link->irq_source_hpd,
false);
amdgpu_dm_irq_set(adev, dc_link->irq_source_hpd,
false);
}
}
if (dc_link->irq_source_hpd_rx != DC_IRQ_SOURCE_INVALID) {
dc_interrupt_set(adev->dm.dc,
dc_link->irq_source_hpd_rx,
false);
amdgpu_dm_irq_set(adev, dc_link->irq_source_hpd_rx,
false);
}
}
drm_connector_list_iter_end(&iter);

View File

@ -89,6 +89,34 @@ void amdgpu_dm_irq_unregister_interrupt(struct amdgpu_device *adev,
enum dc_irq_source irq_source,
void *ih_index);
/**
* amdgpu_dm_irq_set - enable or disable a DC interrupt source.
*
* @adev: AMD DRM device
* @src: DC interrupt source to toggle
* @enable: true to enable the source, false to disable it
*
* DM-wide replacement for dc_interrupt_set(). As locking is DM's
* responsibility, this is a thin wrapper serializes the underlying
* read-modify-write against the other interrupt sources sharing HW control
* registers with @src, so DM must never call dc_interrupt_set() directly.
*
* Returns: true if the source was toggled.
*/
bool amdgpu_dm_irq_set(struct amdgpu_device *adev, enum dc_irq_source src,
bool enable);
/**
* amdgpu_dm_irq_ack - acknowledge a DC interrupt source.
*
* @adev: AMD DRM device
* @src: DC interrupt source to acknowledge
*
* DM-wide replacement for dc_interrupt_ack(), serialized the same way as
* amdgpu_dm_irq_set().
*/
void amdgpu_dm_irq_ack(struct amdgpu_device *adev, enum dc_irq_source src);
void amdgpu_dm_set_irq_funcs(struct amdgpu_device *adev);
void amdgpu_dm_outbox_init(struct amdgpu_device *adev);

View File

@ -436,7 +436,7 @@ static void dm_test_crtc_set_vupdate_irq_no_otg(struct kunit *test)
* dm_test_crtc_set_vupdate_irq_dc_busy - Test vupdate irq when DC rejects request
* @test: The KUnit test context
*
* With an OTG instance assigned but no DC attached, dc_interrupt_set() returns
* With an OTG instance assigned but no DC attached, amdgpu_dm_irq_set() returns
* false and the function must report the request as busy (-EBUSY).
*/
static void dm_test_crtc_set_vupdate_irq_dc_busy(struct kunit *test)
@ -453,12 +453,12 @@ static void dm_test_crtc_set_vupdate_irq_dc_busy(struct kunit *test)
acrtc->base.dev = &adev->ddev;
acrtc->otg_inst = 0;
/* adev->dm.dc is NULL, so dc_interrupt_set() returns false. */
/* adev->dm.dc is NULL, so amdgpu_dm_irq_set() returns false. */
KUNIT_EXPECT_EQ(test,
amdgpu_dm_crtc_set_vupdate_irq(&acrtc->base, true), -EBUSY);
}
/* Per-source funcs let dc_interrupt_set() succeed without register access. */
/* Per-source funcs let amdgpu_dm_irq_set() succeed without register access. */
static bool dm_test_vupdate_irq_src_set(struct irq_service *irq_service,
const struct irq_source_info *info,
bool enable)
@ -477,7 +477,7 @@ static struct irq_source_info_funcs dm_test_vupdate_irq_src_funcs = {
.ack = dm_test_vupdate_irq_src_ack,
};
/* A .set that fails so dc_interrupt_set() reports the source as busy. */
/* A .set that fails so amdgpu_dm_irq_set() reports the source as busy. */
static bool dm_test_vupdate_irq_src_set_busy(struct irq_service *irq_service,
const struct irq_source_info *info,
bool enable)
@ -519,7 +519,9 @@ static void dm_test_crtc_set_vupdate_irq_enable(struct kunit *test)
irqs = kunit_kzalloc(test, sizeof(*irqs), GFP_KERNEL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, irqs);
/* Populate the per-source info table so dc_interrupt_set() succeeds. */
/*
* Populate the per-source info table so amdgpu_dm_irq_set() succeeds.
*/
info = kunit_kzalloc(test, sizeof(*info) * DAL_IRQ_SOURCES_NUMBER,
GFP_KERNEL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, info);
@ -1018,7 +1020,9 @@ static void dm_test_crtc_enable_vblank_vupdate_busy(struct kunit *test)
irqs = kunit_kzalloc(test, sizeof(*irqs), GFP_KERNEL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, irqs);
/* Per-source .set fails so dc_interrupt_set() reports the source busy. */
/*
* Per-source .set fails so amdgpu_dm_irq_set() reports the source busy.
*/
info = kunit_kzalloc(test, sizeof(*info) * DAL_IRQ_SOURCES_NUMBER,
GFP_KERNEL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, info);

View File

@ -2442,17 +2442,21 @@ static void dm_test_is_dp_sink_present_null_priv(struct kunit *test)
* dm_test_dmub_outbox_interrupt_control_null_dc - Test outbox irq control with NULL dc
* @test: The KUnit test context
*
* dc_interrupt_set() is NULL-safe and returns false when dc is NULL, so the
* amdgpu_dm_irq_set() is NULL-safe and returns false when dc is NULL, so the
* helper returns false without touching real interrupt hardware.
*/
static void dm_test_dmub_outbox_interrupt_control_null_dc(struct kunit *test)
{
struct amdgpu_device *adev;
struct dc_context *ctx;
adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, adev);
ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, ctx);
ctx->driver_context = adev;
/* ctx->dc is NULL → dc_interrupt_set returns false */
/* adev->dm.dc is NULL → amdgpu_dm_irq_set returns false */
KUNIT_EXPECT_FALSE(test, dm_helpers_dmub_outbox_interrupt_control(ctx, true));
KUNIT_EXPECT_FALSE(test, dm_helpers_dmub_outbox_interrupt_control(ctx, false));
}

View File

@ -268,7 +268,7 @@ static bool dm_test_irq_src_ack(struct irq_service *irq_service,
return true;
}
/* Per-source funcs let dc_interrupt_set() succeed without register access. */
/* Per-source funcs let amdgpu_dm_irq_set() succeed without register access. */
static struct irq_source_info_funcs dm_test_irq_src_funcs = {
.set = dm_test_irq_src_set,
.ack = dm_test_irq_src_ack,
@ -290,7 +290,7 @@ static struct dc *dm_test_alloc_dc_with_irq_service(struct kunit *test,
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, irqs);
/*
* Populate the per-source info table so dc_interrupt_set()/_ack()
* Populate the per-source info table so amdgpu_dm_irq_set()/_ack()
* succeed without touching hardware registers.
*/
info = kunit_kzalloc(test, sizeof(*info) * DAL_IRQ_SOURCES_NUMBER,
@ -1227,7 +1227,7 @@ static void dm_test_irq_suspend_empty(struct kunit *test)
KUNIT_ASSERT_EQ(test, amdgpu_dm_irq_init(adev), 0);
/*
* With no registered handlers the HW dc_interrupt_set() calls are
* With no registered handlers the amdgpu_dm_irq_set() calls are
* skipped, so suspend must complete without touching the (absent) DC.
*/
amdgpu_dm_irq_suspend(adev);
@ -1275,11 +1275,11 @@ static void dm_test_irq_resume_late_empty(struct kunit *test)
}
/**
* dm_test_irq_suspend_registered - Test suspend reaches the dc_interrupt_set path
* dm_test_irq_suspend_registered - Test suspend reaches the irq set path
* @test: The KUnit test context
*
* Registers a low-context HPD handler so the handler list is non-empty,
* forcing amdgpu_dm_irq_suspend() to call dc_interrupt_set() (NULL-safe with
* forcing amdgpu_dm_irq_suspend() to call amdgpu_dm_irq_set() (NULL-safe with
* no DC) and flush_work() on the registered handler.
*/
static void dm_test_irq_suspend_registered(struct kunit *test)
@ -1330,11 +1330,11 @@ static void dm_test_irq_suspend_disables_polling(struct kunit *test)
}
/**
* dm_test_irq_resume_early_registered - Test early resume reaches dc_interrupt_set
* dm_test_irq_resume_early_registered - Test early resume reaches irq set
* @test: The KUnit test context
*
* Registers a low-context HPD RX handler so early resume calls
* dc_interrupt_set() for the short-pulse interrupt source.
* amdgpu_dm_irq_set() for the short-pulse interrupt source.
*/
static void dm_test_irq_resume_early_registered(struct kunit *test)
{
@ -1358,10 +1358,10 @@ static void dm_test_irq_resume_early_registered(struct kunit *test)
}
/**
* dm_test_irq_resume_late_registered - Test late resume reaches dc_interrupt_set
* dm_test_irq_resume_late_registered - Test late resume reaches irq set
* @test: The KUnit test context
*
* Registers a low-context HPD handler so late resume calls dc_interrupt_set()
* Registers a low-context HPD handler so late resume calls amdgpu_dm_irq_set()
* for the HPD interrupt source.
*/
static void dm_test_irq_resume_late_registered(struct kunit *test)
@ -1592,7 +1592,7 @@ static void dm_test_set_crtc_irq_state_enable(struct kunit *test)
/*
* otg_inst >= 0 computes the irq source and reaches the NULL-safe
* dc_interrupt_set(); the ips_support branch is skipped (dc == NULL).
* amdgpu_dm_irq_set(); the ips_support branch is skipped (dc == NULL).
*/
acrtc->otg_inst = 3;
adev->mode_info.crtcs[0] = acrtc;
@ -1671,8 +1671,8 @@ static void dm_test_set_vupdate_irq_state_enable(struct kunit *test)
*
* With a non-NULL DC that advertises IPS support and currently allows idle
* optimizations, dm_irq_state() must call dc_allow_idle_optimizations() before
* dc_interrupt_set(). disable_idle_power_optimizations makes that call a safe
* early return, and per-source stub funcs let dc_interrupt_set() succeed.
* amdgpu_dm_irq_set(). disable_idle_power_optimizations makes that call a safe
* early return, and per-source stub funcs let amdgpu_dm_irq_set() succeed.
*/
static void dm_test_set_crtc_irq_state_allows_idle(struct kunit *test)
{
@ -1891,7 +1891,7 @@ static void dm_test_set_hpd_irq_state_null_dc(struct kunit *test)
adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
/* dc_interrupt_set() is a no-op when dc is NULL, so both states
/* amdgpu_dm_irq_set() is a no-op when dc is NULL, so both states
* return 0 without dereferencing the (absent) DC.
*/
KUNIT_EXPECT_EQ(test, amdgpu_dm_set_hpd_irq_state(adev, NULL, AMDGPU_HPD_1,
@ -1951,7 +1951,7 @@ static void dm_test_outbox_init_null_dc(struct kunit *test)
adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
/* Single dc_interrupt_set() call must be skipped when dc is NULL. */
/* Single amdgpu_dm_irq_set() call must be skipped when dc is NULL. */
amdgpu_dm_outbox_init(adev);
}
@ -1969,7 +1969,7 @@ static void dm_test_hpd_init_empty_connectors(struct kunit *test)
/*
* With an empty connector list the per-connector loop is skipped and
* the initial clear loop relies on dc_interrupt_set() being a no-op
* the initial clear loop relies on amdgpu_dm_irq_set() being a no-op
* for a NULL dc, so init must complete without touching the DC.
*/
amdgpu_dm_hpd_init(adev);
@ -2004,7 +2004,7 @@ static void dm_test_hpd_init_fini_with_connectors(struct kunit *test)
/*
* num_hpd = 0 forces irq_type >= num_hpd so the loop takes the HW
* fallback (dc_interrupt_set()) instead of amdgpu_irq_get(); with a
* fallback (amdgpu_dm_irq_set()) instead of amdgpu_irq_get(); with a
* NULL dc that fallback is a safe no-op.
*/
adev->mode_info.num_hpd = 0;
@ -2090,7 +2090,7 @@ static void dm_test_hpd_init_fini_irq_ref(struct kunit *test)
/*
* num_hpd >= 1 makes irq_type (0) < num_hpd, so the loop takes the
* amdgpu_irq_get()/amdgpu_irq_put() branch instead of the
* dc_interrupt_set() fallback. The mock device has irq.installed ==
* amdgpu_dm_irq_set() fallback. The mock device has irq.installed ==
* false, so both calls fail early with -ENOENT (logging an error)
* without touching the base-driver irq state.
*/

View File

@ -1064,10 +1064,12 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable)
*/
unsigned int denom = refresh_hz * 6528;
unsigned int stutter_period = dc->current_state->perf_params.stutter_period_us;
uint64_t num = (1000000LL + 2 * stutter_period * refresh_hz) *
(100LL + dc->debug.mall_additional_timer_percent);
uint64_t tmr_ticks;
tmr_delay = (uint32_t)(div_u64(((1000000LL + 2 * stutter_period * refresh_hz) *
(100LL + dc->debug.mall_additional_timer_percent) + denom - 1),
denom) - 64LL);
tmr_ticks = div_u64(num + denom - 1, denom);
tmr_delay = tmr_ticks > 64 ? (uint32_t)(tmr_ticks - 64) : 0;
/* In some cases the stutter period is really big (tiny modes) in these
* cases MALL cant be enabled, So skip these cases to avoid a ASSERT()
@ -1089,9 +1091,8 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable)
}
denom *= 2;
tmr_delay = (uint32_t)(div_u64(((1000000LL + 2 * stutter_period * refresh_hz) *
(100LL + dc->debug.mall_additional_timer_percent) + denom - 1),
denom) - 64LL);
tmr_ticks = div_u64(num + denom - 1, denom);
tmr_delay = tmr_ticks > 64 ? (uint32_t)(tmr_ticks - 64) : 0;
}
/* Copy HW cursor */

View File

@ -67,7 +67,8 @@ static void dcn50_initialize_min_clocks(struct dc *dc)
* audio corruption. Read current DISPCLK from DENTIST and request the same
* freq to ensure that the timing is valid and unchanged.
*/
clocks->dispclk_khz = dc->clk_mgr->funcs->get_dispclk_from_dentist(dc->clk_mgr);
if (dc->clk_mgr->funcs->get_dispclk_from_dentist)
clocks->dispclk_khz = dc->clk_mgr->funcs->get_dispclk_from_dentist(dc->clk_mgr);
}
clocks->ref_dtbclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dtbclk_mhz * 1000;
clocks->fclk_p_state_change_support = true;
@ -639,7 +640,8 @@ void dcn50_init_hw(struct dc *dc)
dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
!dc->res_pool->hubbub->ctx->dc->debug.disable_stutter);
dcn50_initialize_min_clocks(dc);
if (dc->clk_mgr && dc->clk_mgr->funcs)
dcn50_initialize_min_clocks(dc);
/* On HW init, allow idle optimizations after pipes have been turned off.
*

Some files were not shown because too many files have changed in this diff Show More