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

Cross-merge networking fixes after downstream PR (net-7.0-rc8).

Conflicts:

net/ipv6/seg6_iptunnel.c
  c3812651b5 ("seg6: separate dst_cache for input and output paths in seg6 lwtunnel")
  78723a62b9 ("seg6: add per-route tunnel source address")
https://lore.kernel.org/adZhwtOYfo-0ImSa@sirena.org.uk

net/ipv4/icmp.c
  fde29fd934 ("ipv4: icmp: fix null-ptr-deref in icmp_build_probe()")
  d98adfbdd5 ("ipv4: drop ipv6_stub usage and use direct function calls")
https://lore.kernel.org/adO3dccqnr6j-BL9@sirena.org.uk

Adjacent changes:

drivers/net/ethernet/stmicro/stmmac/chain_mode.c
  51f4e090b9 ("net: stmmac: fix integer underflow in chain mode")
  6b4286e055 ("net: stmmac: rename STMMAC_GET_ENTRY() -> STMMAC_NEXT_ENTRY()")

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski
2026-04-02 10:57:09 -07:00
410 changed files with 5337 additions and 1964 deletions

View File

@@ -1,6 +1,7 @@
Alan Cox <alan@lxorguk.ukuu.org.uk> Alan Cox <alan@lxorguk.ukuu.org.uk>
Alan Cox <root@hraefn.swansea.linux.org.uk> Alan Cox <root@hraefn.swansea.linux.org.uk>
Alyssa Rosenzweig <alyssa@rosenzweig.io> Alyssa Rosenzweig <alyssa@rosenzweig.io>
Askar Safin <safinaskar@gmail.com>
Christoph Hellwig <hch@lst.de> Christoph Hellwig <hch@lst.de>
Jeff Kirsher <jeffrey.t.kirsher@intel.com> Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Marc Gonzalez <marc.w.gonzalez@free.fr> Marc Gonzalez <marc.w.gonzalez@free.fr>

View File

@@ -301,6 +301,7 @@ properties:
maxItems: 4 maxItems: 4
dependencies: dependencies:
pd-disable: [typec-power-opmode]
sink-vdos-v1: [ sink-vdos ] sink-vdos-v1: [ sink-vdos ]
sink-vdos: [ sink-vdos-v1 ] sink-vdos: [ sink-vdos-v1 ]

View File

@@ -33,7 +33,7 @@ properties:
- const: core - const: core
iommus: iommus:
maxItems: 2 maxItems: 1
interconnects: interconnects:
items: items:
@@ -107,8 +107,7 @@ examples:
interconnect-names = "mdp0-mem", interconnect-names = "mdp0-mem",
"cpu-cfg"; "cpu-cfg";
iommus = <&apps_smmu 0x420 0x2>, iommus = <&apps_smmu 0x420 0x2>;
<&apps_smmu 0x421 0x0>;
ranges; ranges;
display-controller@5e01000 { display-controller@5e01000 {

View File

@@ -37,7 +37,7 @@ properties:
const: 2 const: 2
"#interrupt-cells": "#interrupt-cells":
const: 1 const: 2
ngpios: ngpios:
description: description:
@@ -86,7 +86,7 @@ examples:
gpio-controller; gpio-controller;
#gpio-cells = <2>; #gpio-cells = <2>;
interrupt-controller; interrupt-controller;
#interrupt-cells = <1>; #interrupt-cells = <2>;
interrupts = <53>, <53>, <53>, <53>, interrupts = <53>, <53>, <53>, <53>,
<53>, <53>, <53>, <53>, <53>, <53>, <53>, <53>,
<53>, <53>, <53>, <53>, <53>, <53>, <53>, <53>,

View File

@@ -42,7 +42,7 @@ properties:
- const: vcodec0_bus - const: vcodec0_bus
iommus: iommus:
maxItems: 5 maxItems: 2
interconnects: interconnects:
maxItems: 2 maxItems: 2
@@ -102,10 +102,7 @@ examples:
memory-region = <&pil_video_mem>; memory-region = <&pil_video_mem>;
iommus = <&apps_smmu 0x860 0x0>, iommus = <&apps_smmu 0x860 0x0>,
<&apps_smmu 0x880 0x0>, <&apps_smmu 0x880 0x0>;
<&apps_smmu 0x861 0x04>,
<&apps_smmu 0x863 0x0>,
<&apps_smmu 0x804 0xe0>;
interconnects = <&mmnrt_virt MASTER_VIDEO_P0 RPM_ALWAYS_TAG interconnects = <&mmnrt_virt MASTER_VIDEO_P0 RPM_ALWAYS_TAG
&bimc SLAVE_EBI1 RPM_ALWAYS_TAG>, &bimc SLAVE_EBI1 RPM_ALWAYS_TAG>,

View File

@@ -42,7 +42,7 @@ properties:
- const: mgbe - const: mgbe
- const: mac - const: mac
- const: mac-divider - const: mac-divider
- const: ptp-ref - const: ptp_ref
- const: rx-input-m - const: rx-input-m
- const: rx-input - const: rx-input
- const: tx - const: tx
@@ -133,7 +133,7 @@ examples:
<&bpmp TEGRA234_CLK_MGBE0_RX_PCS_M>, <&bpmp TEGRA234_CLK_MGBE0_RX_PCS_M>,
<&bpmp TEGRA234_CLK_MGBE0_RX_PCS>, <&bpmp TEGRA234_CLK_MGBE0_RX_PCS>,
<&bpmp TEGRA234_CLK_MGBE0_TX_PCS>; <&bpmp TEGRA234_CLK_MGBE0_TX_PCS>;
clock-names = "mgbe", "mac", "mac-divider", "ptp-ref", "rx-input-m", clock-names = "mgbe", "mac", "mac-divider", "ptp_ref", "rx-input-m",
"rx-input", "tx", "eee-pcs", "rx-pcs-input", "rx-pcs-m", "rx-input", "tx", "eee-pcs", "rx-pcs-input", "rx-pcs-m",
"rx-pcs", "tx-pcs"; "rx-pcs", "tx-pcs";
resets = <&bpmp TEGRA234_RESET_MGBE0_MAC>, resets = <&bpmp TEGRA234_RESET_MGBE0_MAC>,

View File

@@ -5,8 +5,138 @@ Security bugs
Linux kernel developers take security very seriously. As such, we'd Linux kernel developers take security very seriously. As such, we'd
like to know when a security bug is found so that it can be fixed and like to know when a security bug is found so that it can be fixed and
disclosed as quickly as possible. Please report security bugs to the disclosed as quickly as possible.
Linux kernel security team.
Preparing your report
---------------------
Like with any bug report, a security bug report requires a lot of analysis work
from the developers, so the more information you can share about the issue, the
better. Please review the procedure outlined in
Documentation/admin-guide/reporting-issues.rst if you are unclear about what
information is helpful. The following information are absolutely necessary in
**any** security bug report:
* **affected kernel version range**: with no version indication, your report
will not be processed. A significant part of reports are for bugs that
have already been fixed, so it is extremely important that vulnerabilities
are verified on recent versions (development tree or latest stable
version), at least by verifying that the code has not changed since the
version where it was detected.
* **description of the problem**: a detailed description of the problem, with
traces showing its manifestation, and why you consider that the observed
behavior as a problem in the kernel, is necessary.
* **reproducer**: developers will need to be able to reproduce the problem to
consider a fix as effective. This includes both a way to trigger the issue
and a way to confirm it happens. A reproducer with low complexity
dependencies will be needed (source code, shell script, sequence of
instructions, file-system image etc). Binary-only executables are not
accepted. Working exploits are extremely helpful and will not be released
without consent from the reporter, unless they are already public. By
definition if an issue cannot be reproduced, it is not exploitable, thus it
is not a security bug.
* **conditions**: if the bug depends on certain configuration options,
sysctls, permissions, timing, code modifications etc, these should be
indicated.
In addition, the following information are highly desirable:
* **suspected location of the bug**: the file names and functions where the
bug is suspected to be present are very important, at least to help forward
the report to the appropriate maintainers. When not possible (for example,
"system freezes each time I run this command"), the security team will help
identify the source of the bug.
* **a proposed fix**: bug reporters who have analyzed the cause of a bug in
the source code almost always have an accurate idea on how to fix it,
because they spent a long time studying it and its implications. Proposing
a tested fix will save maintainers a lot of time, even if the fix ends up
not being the right one, because it helps understand the bug. When
proposing a tested fix, please always format it in a way that can be
immediately merged (see Documentation/process/submitting-patches.rst).
This will save some back-and-forth exchanges if it is accepted, and you
will be credited for finding and fixing this issue. Note that in this case
only a ``Signed-off-by:`` tag is needed, without ``Reported-by:`` when the
reporter and author are the same.
* **mitigations**: very often during a bug analysis, some ways of mitigating
the issue appear. It is useful to share them, as they can be helpful to
keep end users protected during the time it takes them to apply the fix.
Identifying contacts
--------------------
The most effective way to report a security bug is to send it directly to the
affected subsystem's maintainers and Cc: the Linux kernel security team. Do
not send it to a public list at this stage, unless you have good reasons to
consider the issue as being public or trivial to discover (e.g. result of a
widely available automated vulnerability scanning tool that can be repeated by
anyone).
If you're sending a report for issues affecting multiple parts in the kernel,
even if they're fairly similar issues, please send individual messages (think
that maintainers will not all work on the issues at the same time). The only
exception is when an issue concerns closely related parts maintained by the
exact same subset of maintainers, and these parts are expected to be fixed all
at once by the same commit, then it may be acceptable to report them at once.
One difficulty for most first-time reporters is to figure the right list of
recipients to send a report to. In the Linux kernel, all official maintainers
are trusted, so the consequences of accidentally including the wrong maintainer
are essentially a bit more noise for that person, i.e. nothing dramatic. As
such, a suitable method to figure the list of maintainers (which kernel
security officers use) is to rely on the get_maintainer.pl script, tuned to
only report maintainers. This script, when passed a file name, will look for
its path in the MAINTAINERS file to figure a hierarchical list of relevant
maintainers. Calling it a first time with the finest level of filtering will
most of the time return a short list of this specific file's maintainers::
$ ./scripts/get_maintainer.pl --no-l --no-r --pattern-depth 1 \
drivers/example.c
Developer One <dev1@example.com> (maintainer:example driver)
Developer Two <dev2@example.org> (maintainer:example driver)
These two maintainers should then receive the message. If the command does not
return anything, it means the affected file is part of a wider subsystem, so we
should be less specific::
$ ./scripts/get_maintainer.pl --no-l --no-r drivers/example.c
Developer One <dev1@example.com> (maintainer:example subsystem)
Developer Two <dev2@example.org> (maintainer:example subsystem)
Developer Three <dev3@example.com> (maintainer:example subsystem [GENERAL])
Developer Four <dev4@example.org> (maintainer:example subsystem [GENERAL])
Here, picking the first, most specific ones, is sufficient. When the list is
long, it is possible to produce a comma-delimited e-mail address list on a
single line suitable for use in the To: field of a mailer like this::
$ ./scripts/get_maintainer.pl --no-tree --no-l --no-r --no-n --m \
--no-git-fallback --no-substatus --no-rolestats --no-multiline \
--pattern-depth 1 drivers/example.c
dev1@example.com, dev2@example.org
or this for the wider list::
$ ./scripts/get_maintainer.pl --no-tree --no-l --no-r --no-n --m \
--no-git-fallback --no-substatus --no-rolestats --no-multiline \
drivers/example.c
dev1@example.com, dev2@example.org, dev3@example.com, dev4@example.org
If at this point you're still facing difficulties spotting the right
maintainers, **and only in this case**, it's possible to send your report to
the Linux kernel security team only. Your message will be triaged, and you
will receive instructions about whom to contact, if needed. Your message may
equally be forwarded as-is to the relevant maintainers.
Sending the report
------------------
Reports are to be sent over e-mail exclusively. Please use a working e-mail
address, preferably the same that you want to appear in ``Reported-by`` tags
if any. If unsure, send your report to yourself first.
The security team and maintainers almost always require additional The security team and maintainers almost always require additional
information beyond what was initially provided in a report and rely on information beyond what was initially provided in a report and rely on
@@ -18,20 +148,12 @@ run additional tests. Reports where the reporter does not respond promptly
or cannot effectively discuss their findings may be abandoned if the or cannot effectively discuss their findings may be abandoned if the
communication does not quickly improve. communication does not quickly improve.
As it is with any bug, the more information provided the easier it The report must be sent to maintainers, with the security team in ``Cc:``.
will be to diagnose and fix. Please review the procedure outlined in
'Documentation/admin-guide/reporting-issues.rst' if you are unclear about what
information is helpful. Any exploit code is very helpful and will not
be released without consent from the reporter unless it has already been
made public.
The Linux kernel security team can be contacted by email at The Linux kernel security team can be contacted by email at
<security@kernel.org>. This is a private list of security officers <security@kernel.org>. This is a private list of security officers
who will help verify the bug report and develop and release a fix. who will help verify the bug report and assist developers working on a fix.
If you already have a fix, please include it with your report, as It is possible that the security team will bring in extra help from area
that can speed up the process considerably. It is possible that the maintainers to understand and fix the security vulnerability.
security team will bring in extra help from area maintainers to
understand and fix the security vulnerability.
Please send **plain text** emails without attachments where possible. Please send **plain text** emails without attachments where possible.
It is much harder to have a context-quoted discussion about a complex It is much harder to have a context-quoted discussion about a complex
@@ -42,7 +164,9 @@ reproduction steps, and follow it with a proposed fix, all in plain text.
Markdown, HTML and RST formatted reports are particularly frowned upon since Markdown, HTML and RST formatted reports are particularly frowned upon since
they're quite hard to read for humans and encourage to use dedicated viewers, they're quite hard to read for humans and encourage to use dedicated viewers,
sometimes online, which by definition is not acceptable for a confidential sometimes online, which by definition is not acceptable for a confidential
security report. security report. Note that some mailers tend to mangle formatting of plain
text by default, please consult Documentation/process/email-clients.rst for
more info.
Disclosure and embargoed information Disclosure and embargoed information
------------------------------------ ------------------------------------

View File

@@ -1285,6 +1285,7 @@ F: include/uapi/drm/amdxdna_accel.h
AMD XGBE DRIVER AMD XGBE DRIVER
M: Raju Rangoju <Raju.Rangoju@amd.com> M: Raju Rangoju <Raju.Rangoju@amd.com>
M: Prashanth Kumar K R <PrashanthKumar.K.R@amd.com>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
S: Maintained S: Maintained
F: arch/arm64/boot/dts/amd/amd-seattle-xgbe*.dtsi F: arch/arm64/boot/dts/amd/amd-seattle-xgbe*.dtsi
@@ -21067,8 +21068,7 @@ F: include/uapi/linux/atmppp.h
F: net/atm/pppoatm.c F: net/atm/pppoatm.c
PPP OVER ETHERNET PPP OVER ETHERNET
M: Michal Ostrowski <mostrows@earthlink.net> S: Orphan
S: Maintained
F: drivers/net/ppp/pppoe.c F: drivers/net/ppp/pppoe.c
F: drivers/net/ppp/pppox.c F: drivers/net/ppp/pppox.c
@@ -22123,7 +22123,7 @@ S: Supported
F: drivers/infiniband/sw/rdmavt F: drivers/infiniband/sw/rdmavt
RDS - RELIABLE DATAGRAM SOCKETS RDS - RELIABLE DATAGRAM SOCKETS
M: Allison Henderson <allison.henderson@oracle.com> M: Allison Henderson <achender@kernel.org>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
L: linux-rdma@vger.kernel.org L: linux-rdma@vger.kernel.org
L: rds-devel@oss.oracle.com (moderated for non-subscribers) L: rds-devel@oss.oracle.com (moderated for non-subscribers)

View File

@@ -2,7 +2,7 @@
VERSION = 7 VERSION = 7
PATCHLEVEL = 0 PATCHLEVEL = 0
SUBLEVEL = 0 SUBLEVEL = 0
EXTRAVERSION = -rc6 EXTRAVERSION = -rc7
NAME = Baby Opossum Posse NAME = Baby Opossum Posse
# *DOCUMENTATION* # *DOCUMENTATION*

View File

@@ -1226,7 +1226,7 @@
interrupt-controller; interrupt-controller;
#gpio-cells = <2>; #gpio-cells = <2>;
gpio-controller; gpio-controller;
#gpio-lines = <26>; #gpio-lines = <27>;
clocks = <&pmc PMC_TYPE_PERIPHERAL 3>; clocks = <&pmc PMC_TYPE_PERIPHERAL 3>;
}; };

View File

@@ -36,12 +36,8 @@
&gpmi { &gpmi {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>; pinctrl-0 = <&pinctrl_gpmi_nand>;
nand-on-flash-bbt;
status = "okay"; status = "okay";
nand@0 {
reg = <0>;
nand-on-flash-bbt;
};
}; };
&i2c3 { &i2c3 {

View File

@@ -172,12 +172,8 @@
&gpmi { &gpmi {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>; pinctrl-0 = <&pinctrl_gpmi_nand>;
nand-on-flash-bbt;
status = "okay"; status = "okay";
nand@0 {
reg = <0>;
nand-on-flash-bbt;
};
}; };
&i2c1 { &i2c1 {

View File

@@ -102,12 +102,8 @@
&gpmi { &gpmi {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>; pinctrl-0 = <&pinctrl_gpmi_nand>;
nand-on-flash-bbt;
status = "okay"; status = "okay";
nand@0 {
reg = <0>;
nand-on-flash-bbt;
};
}; };
&i2c1 { &i2c1 {

View File

@@ -73,12 +73,8 @@
&gpmi { &gpmi {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>; pinctrl-0 = <&pinctrl_gpmi_nand>;
nand-on-flash-bbt;
status = "disabled"; status = "disabled";
nand@0 {
reg = <0>;
nand-on-flash-bbt;
};
}; };
&i2c3 { &i2c3 {

View File

@@ -260,14 +260,10 @@
&gpmi { &gpmi {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>; pinctrl-0 = <&pinctrl_gpmi_nand>;
nand-on-flash-bbt;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
status = "okay"; status = "okay";
nand@0 {
reg = <0>;
nand-on-flash-bbt;
};
}; };
&i2c3 { &i2c3 {

View File

@@ -252,13 +252,9 @@
&gpmi { &gpmi {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>; pinctrl-0 = <&pinctrl_gpmi_nand>;
nand-on-flash-bbt;
fsl,no-blockmark-swap; fsl,no-blockmark-swap;
status = "okay"; status = "okay";
nand@0 {
reg = <0>;
nand-on-flash-bbt;
};
}; };
&i2c1 { &i2c1 {

View File

@@ -133,12 +133,8 @@
&gpmi { &gpmi {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>; pinctrl-0 = <&pinctrl_gpmi_nand>;
nand-on-flash-bbt;
status = "okay"; status = "okay";
nand@0 {
reg = <0>;
nand-on-flash-bbt;
};
}; };
&i2c1 { &i2c1 {

View File

@@ -101,12 +101,8 @@
&gpmi { &gpmi {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>; pinctrl-0 = <&pinctrl_gpmi_nand>;
nand-on-flash-bbt;
status = "disabled"; status = "disabled";
nand@0 {
reg = <0>;
nand-on-flash-bbt;
};
}; };
&i2c1 { &i2c1 {

View File

@@ -63,12 +63,8 @@
&gpmi { &gpmi {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>; pinctrl-0 = <&pinctrl_gpmi_nand>;
nand-on-flash-bbt;
status = "disabled"; status = "disabled";
nand@0 {
reg = <0>;
nand-on-flash-bbt;
};
}; };
&i2c1 { &i2c1 {

View File

@@ -296,13 +296,9 @@
&gpmi { &gpmi {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>; pinctrl-0 = <&pinctrl_gpmi_nand>;
nand-on-flash-bbt;
fsl,no-blockmark-swap; fsl,no-blockmark-swap;
status = "okay"; status = "okay";
nand@0 {
reg = <0>;
nand-on-flash-bbt;
};
}; };
&i2c2 { &i2c2 {

View File

@@ -160,15 +160,11 @@
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>; pinctrl-0 = <&pinctrl_gpmi_nand>;
fsl,use-minimum-ecc; fsl,use-minimum-ecc;
nand-on-flash-bbt;
nand-ecc-mode = "hw";
nand-ecc-strength = <8>;
nand-ecc-step-size = <512>;
status = "okay"; status = "okay";
nand@0 {
reg = <0>;
nand-on-flash-bbt;
nand-ecc-mode = "hw";
nand-ecc-strength = <8>;
nand-ecc-step-size = <512>;
};
}; };
/* I2C3_SDA/SCL on SODIMM 194/196 (e.g. RTC on carrier board) */ /* I2C3_SDA/SCL on SODIMM 194/196 (e.g. RTC on carrier board) */

View File

@@ -43,15 +43,11 @@
&gpmi { &gpmi {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>; pinctrl-0 = <&pinctrl_gpmi_nand>;
nand-ecc-mode = "hw";
nand-ecc-strength = <0>;
nand-ecc-step-size = <0>;
nand-on-flash-bbt;
status = "okay"; status = "okay";
nand@0 {
reg = <0>;
nand-ecc-mode = "hw";
nand-ecc-strength = <0>;
nand-ecc-step-size = <0>;
nand-on-flash-bbt;
};
}; };
&iomuxc { &iomuxc {

View File

@@ -60,12 +60,8 @@
&gpmi { &gpmi {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>; pinctrl-0 = <&pinctrl_gpmi_nand>;
nand-on-flash-bbt;
status = "disabled"; status = "disabled";
nand@0 {
reg = <0>;
nand-on-flash-bbt;
};
}; };
&uart1 { &uart1 {

View File

@@ -25,12 +25,8 @@
&gpmi { &gpmi {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>; pinctrl-0 = <&pinctrl_gpmi_nand>;
nand-on-flash-bbt;
status = "okay"; status = "okay";
nand@0 {
reg = <0>;
nand-on-flash-bbt;
};
}; };
&snvs_poweroff { &snvs_poweroff {

View File

@@ -375,14 +375,10 @@
/* NAND on such SKUs */ /* NAND on such SKUs */
&gpmi { &gpmi {
fsl,use-minimum-ecc; fsl,use-minimum-ecc;
nand-ecc-mode = "hw";
nand-on-flash-bbt;
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>; pinctrl-0 = <&pinctrl_gpmi_nand>;
nand@0 {
reg = <0>;
nand-ecc-mode = "hw";
nand-on-flash-bbt;
};
}; };
/* On-module Power I2C */ /* On-module Power I2C */

View File

@@ -252,6 +252,7 @@ config ARM64
select HAVE_RSEQ select HAVE_RSEQ
select HAVE_RUST if RUSTC_SUPPORTS_ARM64 select HAVE_RUST if RUSTC_SUPPORTS_ARM64
select HAVE_STACKPROTECTOR select HAVE_STACKPROTECTOR
select HAVE_STATIC_CALL if CFI
select HAVE_SYSCALL_TRACEPOINTS select HAVE_SYSCALL_TRACEPOINTS
select HAVE_KPROBES select HAVE_KPROBES
select HAVE_KRETPROBES select HAVE_KRETPROBES

View File

@@ -901,7 +901,7 @@
interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&r_ccu CLK_BUS_R_SPI>, <&r_ccu CLK_R_SPI>; clocks = <&r_ccu CLK_BUS_R_SPI>, <&r_ccu CLK_R_SPI>;
clock-names = "ahb", "mod"; clock-names = "ahb", "mod";
dmas = <&dma 53>, <&dma 53>; dmas = <&mcu_dma 13>, <&mcu_dma 13>;
dma-names = "rx", "tx"; dma-names = "rx", "tx";
resets = <&r_ccu RST_BUS_R_SPI>; resets = <&r_ccu RST_BUS_R_SPI>;
status = "disabled"; status = "disabled";

View File

@@ -7,7 +7,7 @@
&a53_opp_table { &a53_opp_table {
opp-1000000000 { opp-1000000000 {
opp-microvolt = <950000>; opp-microvolt = <1000000>;
}; };
}; };

View File

@@ -880,9 +880,9 @@
regulator-max-microvolt = <1300000>; regulator-max-microvolt = <1300000>;
regulator-boot-on; regulator-boot-on;
regulator-ramp-delay = <1250>; regulator-ramp-delay = <1250>;
rohm,dvs-run-voltage = <880000>; rohm,dvs-run-voltage = <900000>;
rohm,dvs-idle-voltage = <820000>; rohm,dvs-idle-voltage = <850000>;
rohm,dvs-suspend-voltage = <810000>; rohm,dvs-suspend-voltage = <850000>;
regulator-always-on; regulator-always-on;
}; };
@@ -892,8 +892,8 @@
regulator-max-microvolt = <1300000>; regulator-max-microvolt = <1300000>;
regulator-boot-on; regulator-boot-on;
regulator-ramp-delay = <1250>; regulator-ramp-delay = <1250>;
rohm,dvs-run-voltage = <950000>; rohm,dvs-run-voltage = <1000000>;
rohm,dvs-idle-voltage = <850000>; rohm,dvs-idle-voltage = <900000>;
regulator-always-on; regulator-always-on;
}; };
@@ -902,14 +902,14 @@
regulator-min-microvolt = <700000>; regulator-min-microvolt = <700000>;
regulator-max-microvolt = <1300000>; regulator-max-microvolt = <1300000>;
regulator-boot-on; regulator-boot-on;
rohm,dvs-run-voltage = <850000>; rohm,dvs-run-voltage = <900000>;
}; };
buck4_reg: BUCK4 { buck4_reg: BUCK4 {
regulator-name = "buck4"; regulator-name = "buck4";
regulator-min-microvolt = <700000>; regulator-min-microvolt = <700000>;
regulator-max-microvolt = <1300000>; regulator-max-microvolt = <1300000>;
rohm,dvs-run-voltage = <930000>; rohm,dvs-run-voltage = <1000000>;
}; };
buck5_reg: BUCK5 { buck5_reg: BUCK5 {
@@ -1448,13 +1448,3 @@
fsl,ext-reset-output; fsl,ext-reset-output;
status = "okay"; status = "okay";
}; };
&a53_opp_table {
opp-1000000000 {
opp-microvolt = <850000>;
};
opp-1500000000 {
opp-microvolt = <950000>;
};
};

View File

@@ -1632,7 +1632,7 @@
<&clk IMX8MQ_GPU_PLL_OUT>, <&clk IMX8MQ_GPU_PLL_OUT>,
<&clk IMX8MQ_GPU_PLL>; <&clk IMX8MQ_GPU_PLL>;
assigned-clock-rates = <800000000>, <800000000>, assigned-clock-rates = <800000000>, <800000000>,
<800000000>, <800000000>, <0>; <800000000>, <400000000>, <0>;
power-domains = <&pgc_gpu>; power-domains = <&pgc_gpu>;
}; };

View File

@@ -272,20 +272,20 @@
/* enable SION for data and cmd pad due to ERR052021 */ /* enable SION for data and cmd pad due to ERR052021 */
pinctrl_usdhc1: usdhc1grp { pinctrl_usdhc1: usdhc1grp {
fsl,pins = /* PD | FSEL 3 | DSE X5 */ fsl,pins = /* PD | FSEL 3 | DSE X5 */
<MX91_PAD_SD1_CLK__USDHC1_CLK 0x5be>, <MX91_PAD_SD1_CLK__USDHC1_CLK 0x59e>,
/* HYS | FSEL 0 | no drive */ /* HYS | FSEL 0 | no drive */
<MX91_PAD_SD1_STROBE__USDHC1_STROBE 0x1000>, <MX91_PAD_SD1_STROBE__USDHC1_STROBE 0x1000>,
/* HYS | FSEL 3 | X5 */ /* HYS | FSEL 3 | X5 */
<MX91_PAD_SD1_CMD__USDHC1_CMD 0x400011be>, <MX91_PAD_SD1_CMD__USDHC1_CMD 0x4000139e>,
/* HYS | FSEL 3 | X4 */ /* HYS | FSEL 3 | X4 */
<MX91_PAD_SD1_DATA0__USDHC1_DATA0 0x4000119e>, <MX91_PAD_SD1_DATA0__USDHC1_DATA0 0x4000139e>,
<MX91_PAD_SD1_DATA1__USDHC1_DATA1 0x4000119e>, <MX91_PAD_SD1_DATA1__USDHC1_DATA1 0x4000139e>,
<MX91_PAD_SD1_DATA2__USDHC1_DATA2 0x4000119e>, <MX91_PAD_SD1_DATA2__USDHC1_DATA2 0x4000139e>,
<MX91_PAD_SD1_DATA3__USDHC1_DATA3 0x4000119e>, <MX91_PAD_SD1_DATA3__USDHC1_DATA3 0x4000139e>,
<MX91_PAD_SD1_DATA4__USDHC1_DATA4 0x4000119e>, <MX91_PAD_SD1_DATA4__USDHC1_DATA4 0x4000139e>,
<MX91_PAD_SD1_DATA5__USDHC1_DATA5 0x4000119e>, <MX91_PAD_SD1_DATA5__USDHC1_DATA5 0x4000139e>,
<MX91_PAD_SD1_DATA6__USDHC1_DATA6 0x4000119e>, <MX91_PAD_SD1_DATA6__USDHC1_DATA6 0x4000139e>,
<MX91_PAD_SD1_DATA7__USDHC1_DATA7 0x4000119e>; <MX91_PAD_SD1_DATA7__USDHC1_DATA7 0x4000139e>;
}; };
pinctrl_wdog: wdoggrp { pinctrl_wdog: wdoggrp {

View File

@@ -507,6 +507,7 @@
pinctrl-2 = <&pinctrl_usdhc1_200mhz>; pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
bus-width = <8>; bus-width = <8>;
non-removable; non-removable;
fsl,tuning-step = <1>;
status = "okay"; status = "okay";
}; };
@@ -519,6 +520,7 @@
vmmc-supply = <&reg_usdhc2_vmmc>; vmmc-supply = <&reg_usdhc2_vmmc>;
bus-width = <4>; bus-width = <4>;
no-mmc; no-mmc;
fsl,tuning-step = <1>;
status = "okay"; status = "okay";
}; };

View File

@@ -271,21 +271,21 @@
/* enable SION for data and cmd pad due to ERR052021 */ /* enable SION for data and cmd pad due to ERR052021 */
pinctrl_usdhc1: usdhc1grp { pinctrl_usdhc1: usdhc1grp {
fsl,pins = < fsl,pins = <
/* PD | FSEL 3 | DSE X5 */ /* PD | FSEL 3 | DSE X4 */
MX93_PAD_SD1_CLK__USDHC1_CLK 0x5be MX93_PAD_SD1_CLK__USDHC1_CLK 0x59e
/* HYS | FSEL 0 | no drive */ /* HYS | FSEL 0 | no drive */
MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x1000 MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x1000
/* HYS | FSEL 3 | X5 */ /* HYS | PU | FSEL 3 | DSE X4 */
MX93_PAD_SD1_CMD__USDHC1_CMD 0x400011be MX93_PAD_SD1_CMD__USDHC1_CMD 0x4000139e
/* HYS | FSEL 3 | X4 */ /* HYS | PU | FSEL 3 | DSE X4 */
MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x4000119e MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x4000139e
MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x4000119e MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x4000139e
MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x4000119e MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x4000139e
MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x4000119e MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x4000139e
MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x4000119e MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x4000139e
MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x4000119e MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x4000139e
MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x4000119e MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x4000139e
MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x4000119e MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x4000139e
>; >;
}; };

View File

@@ -179,7 +179,7 @@
}; };
&pcie { &pcie {
reset-gpios = <&gpio4 4 GPIO_ACTIVE_HIGH>; reset-gpios = <&gpio4 4 GPIO_ACTIVE_LOW>;
vpcie-supply = <&reg_pcie>; vpcie-supply = <&reg_pcie>;
status = "okay"; status = "okay";
}; };

View File

@@ -122,6 +122,7 @@
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
ranges = <0x0 0x0 0xf0000000 0x10000000>; ranges = <0x0 0x0 0xf0000000 0x10000000>;
dma-ranges = <0x0 0x0 0x0 0x40000000>;
crg: clock-reset-controller@8a22000 { crg: clock-reset-controller@8a22000 {
compatible = "hisilicon,hi3798cv200-crg", "syscon", "simple-mfd"; compatible = "hisilicon,hi3798cv200-crg", "syscon", "simple-mfd";

View File

@@ -1669,8 +1669,7 @@
&bimc SLAVE_EBI1 RPM_ALWAYS_TAG>; &bimc SLAVE_EBI1 RPM_ALWAYS_TAG>;
interconnect-names = "gfx-mem"; interconnect-names = "gfx-mem";
iommus = <&adreno_smmu 0 1>, iommus = <&adreno_smmu 0 1>;
<&adreno_smmu 2 0>;
operating-points-v2 = <&gpu_opp_table>; operating-points-v2 = <&gpu_opp_table>;
power-domains = <&rpmpd QCM2290_VDDCX>; power-domains = <&rpmpd QCM2290_VDDCX>;
qcom,gmu = <&gmu_wrapper>; qcom,gmu = <&gmu_wrapper>;
@@ -1951,8 +1950,7 @@
power-domains = <&dispcc MDSS_GDSC>; power-domains = <&dispcc MDSS_GDSC>;
iommus = <&apps_smmu 0x420 0x2>, iommus = <&apps_smmu 0x420 0x2>;
<&apps_smmu 0x421 0x0>;
interconnects = <&mmrt_virt MASTER_MDP0 RPM_ALWAYS_TAG interconnects = <&mmrt_virt MASTER_MDP0 RPM_ALWAYS_TAG
&bimc SLAVE_EBI1 RPM_ALWAYS_TAG>, &bimc SLAVE_EBI1 RPM_ALWAYS_TAG>,
<&bimc MASTER_APPSS_PROC RPM_ALWAYS_TAG <&bimc MASTER_APPSS_PROC RPM_ALWAYS_TAG
@@ -2436,10 +2434,7 @@
memory-region = <&pil_video_mem>; memory-region = <&pil_video_mem>;
iommus = <&apps_smmu 0x860 0x0>, iommus = <&apps_smmu 0x860 0x0>,
<&apps_smmu 0x880 0x0>, <&apps_smmu 0x880 0x0>;
<&apps_smmu 0x861 0x04>,
<&apps_smmu 0x863 0x0>,
<&apps_smmu 0x804 0xe0>;
interconnects = <&mmnrt_virt MASTER_VIDEO_P0 RPM_ALWAYS_TAG interconnects = <&mmnrt_virt MASTER_VIDEO_P0 RPM_ALWAYS_TAG
&bimc SLAVE_EBI1 RPM_ALWAYS_TAG>, &bimc SLAVE_EBI1 RPM_ALWAYS_TAG>,

View File

@@ -269,7 +269,7 @@
idle-state-name = "ret"; idle-state-name = "ret";
arm,psci-suspend-param = <0x00000004>; arm,psci-suspend-param = <0x00000004>;
entry-latency-us = <180>; entry-latency-us = <180>;
exit-latency-us = <500>; exit-latency-us = <320>;
min-residency-us = <600>; min-residency-us = <600>;
}; };
}; };

View File

@@ -765,6 +765,11 @@
hwlocks = <&tcsr_mutex 3>; hwlocks = <&tcsr_mutex 3>;
}; };
gunyah_md_mem: gunyah-md-region@91a80000 {
reg = <0x0 0x91a80000 0x0 0x80000>;
no-map;
};
lpass_machine_learning_mem: lpass-machine-learning-region@93b00000 { lpass_machine_learning_mem: lpass-machine-learning-region@93b00000 {
reg = <0x0 0x93b00000 0x0 0xf00000>; reg = <0x0 0x93b00000 0x0 0xf00000>;
no-map; no-map;
@@ -6414,12 +6419,12 @@
}; };
qup_uart10_rts: qup-uart10-rts-state { qup_uart10_rts: qup-uart10-rts-state {
pins = "gpio84"; pins = "gpio85";
function = "qup1_se2"; function = "qup1_se2";
}; };
qup_uart10_tx: qup-uart10-tx-state { qup_uart10_tx: qup-uart10-tx-state {
pins = "gpio85"; pins = "gpio86";
function = "qup1_se2"; function = "qup1_se2";
}; };

View File

@@ -177,7 +177,7 @@
pinctrl-0 = <&wcd_default>; pinctrl-0 = <&wcd_default>;
pinctrl-names = "default"; pinctrl-names = "default";
reset-gpios = <&tlmm 83 GPIO_ACTIVE_HIGH>; reset-gpios = <&tlmm 83 GPIO_ACTIVE_LOW>;
vdd-buck-supply = <&vreg_l17b_1p7>; vdd-buck-supply = <&vreg_l17b_1p7>;
vdd-rxtx-supply = <&vreg_l18b_1p8>; vdd-rxtx-supply = <&vreg_l18b_1p8>;

View File

@@ -1032,9 +1032,6 @@
}; };
&pcie4 { &pcie4 {
perst-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>;
pinctrl-0 = <&pcie4_default>; pinctrl-0 = <&pcie4_default>;
pinctrl-names = "default"; pinctrl-names = "default";
@@ -1048,10 +1045,12 @@
status = "okay"; status = "okay";
}; };
&pcie6a { &pcie4_port0 {
perst-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>; reset-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>; wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>;
};
&pcie6a {
vddpe-3v3-supply = <&vreg_nvme>; vddpe-3v3-supply = <&vreg_nvme>;
pinctrl-0 = <&pcie6a_default>; pinctrl-0 = <&pcie6a_default>;
@@ -1067,6 +1066,11 @@
status = "okay"; status = "okay";
}; };
&pcie6a_port0 {
reset-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>;
};
&pm8550_gpios { &pm8550_gpios {
rtmr0_default: rtmr0-reset-n-active-state { rtmr0_default: rtmr0-reset-n-active-state {
pins = "gpio10"; pins = "gpio10";

View File

@@ -1216,15 +1216,17 @@
}; };
&pcie4 { &pcie4 {
perst-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>;
pinctrl-0 = <&pcie4_default>; pinctrl-0 = <&pcie4_default>;
pinctrl-names = "default"; pinctrl-names = "default";
status = "okay"; status = "okay";
}; };
&pcie4_port0 {
reset-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>;
};
&pcie4_phy { &pcie4_phy {
vdda-phy-supply = <&vreg_l3i_0p8>; vdda-phy-supply = <&vreg_l3i_0p8>;
vdda-pll-supply = <&vreg_l3e_1p2>; vdda-pll-supply = <&vreg_l3e_1p2>;
@@ -1233,9 +1235,6 @@
}; };
&pcie5 { &pcie5 {
perst-gpios = <&tlmm 149 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 151 GPIO_ACTIVE_LOW>;
vddpe-3v3-supply = <&vreg_wwan>; vddpe-3v3-supply = <&vreg_wwan>;
pinctrl-0 = <&pcie5_default>; pinctrl-0 = <&pcie5_default>;
@@ -1251,10 +1250,12 @@
status = "okay"; status = "okay";
}; };
&pcie6a { &pcie5_port0 {
perst-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>; reset-gpios = <&tlmm 149 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>; wake-gpios = <&tlmm 151 GPIO_ACTIVE_LOW>;
};
&pcie6a {
vddpe-3v3-supply = <&vreg_nvme>; vddpe-3v3-supply = <&vreg_nvme>;
pinctrl-names = "default"; pinctrl-names = "default";
@@ -1270,6 +1271,11 @@
status = "okay"; status = "okay";
}; };
&pcie6a_port0 {
reset-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>;
};
&pm8550_gpios { &pm8550_gpios {
kypd_vol_up_n: kypd-vol-up-n-state { kypd_vol_up_n: kypd-vol-up-n-state {
pins = "gpio6"; pins = "gpio6";

View File

@@ -1081,9 +1081,6 @@
}; };
&pcie4 { &pcie4 {
perst-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>;
pinctrl-0 = <&pcie4_default>; pinctrl-0 = <&pcie4_default>;
pinctrl-names = "default"; pinctrl-names = "default";
@@ -1098,6 +1095,9 @@
}; };
&pcie4_port0 { &pcie4_port0 {
reset-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>;
wifi@0 { wifi@0 {
compatible = "pci17cb,1107"; compatible = "pci17cb,1107";
reg = <0x10000 0x0 0x0 0x0 0x0>; reg = <0x10000 0x0 0x0 0x0 0x0>;
@@ -1115,9 +1115,6 @@
}; };
&pcie6a { &pcie6a {
perst-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>;
vddpe-3v3-supply = <&vreg_nvme>; vddpe-3v3-supply = <&vreg_nvme>;
pinctrl-0 = <&pcie6a_default>; pinctrl-0 = <&pcie6a_default>;
@@ -1126,6 +1123,11 @@
status = "okay"; status = "okay";
}; };
&pcie6a_port0 {
reset-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>;
};
&pcie6a_phy { &pcie6a_phy {
vdda-phy-supply = <&vreg_l1d_0p8>; vdda-phy-supply = <&vreg_l1d_0p8>;
vdda-pll-supply = <&vreg_l2j_1p2>; vdda-pll-supply = <&vreg_l2j_1p2>;

View File

@@ -1065,9 +1065,6 @@
}; };
&pcie4 { &pcie4 {
perst-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>;
pinctrl-0 = <&pcie4_default>; pinctrl-0 = <&pcie4_default>;
pinctrl-names = "default"; pinctrl-names = "default";
@@ -1082,6 +1079,9 @@
}; };
&pcie4_port0 { &pcie4_port0 {
reset-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>;
wifi@0 { wifi@0 {
compatible = "pci17cb,1107"; compatible = "pci17cb,1107";
reg = <0x10000 0x0 0x0 0x0 0x0>; reg = <0x10000 0x0 0x0 0x0 0x0>;
@@ -1099,9 +1099,6 @@
}; };
&pcie6a { &pcie6a {
perst-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>;
vddpe-3v3-supply = <&vreg_nvme>; vddpe-3v3-supply = <&vreg_nvme>;
pinctrl-0 = <&pcie6a_default>; pinctrl-0 = <&pcie6a_default>;
@@ -1110,6 +1107,11 @@
status = "okay"; status = "okay";
}; };
&pcie6a_port0 {
reset-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>;
};
&pcie6a_phy { &pcie6a_phy {
vdda-phy-supply = <&vreg_l1d_0p8>; vdda-phy-supply = <&vreg_l1d_0p8>;
vdda-pll-supply = <&vreg_l2j_1p2>; vdda-pll-supply = <&vreg_l2j_1p2>;

View File

@@ -964,9 +964,6 @@
}; };
&pcie6a { &pcie6a {
perst-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>;
vddpe-3v3-supply = <&vreg_nvme>; vddpe-3v3-supply = <&vreg_nvme>;
pinctrl-0 = <&pcie6a_default>; pinctrl-0 = <&pcie6a_default>;
@@ -982,6 +979,11 @@
status = "okay"; status = "okay";
}; };
&pcie6a_port0 {
reset-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>;
};
&pm8550_gpios { &pm8550_gpios {
rtmr0_default: rtmr0-reset-n-active-state { rtmr0_default: rtmr0-reset-n-active-state {
pins = "gpio10"; pins = "gpio10";

View File

@@ -1126,9 +1126,6 @@
}; };
&pcie4 { &pcie4 {
perst-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>;
pinctrl-0 = <&pcie4_default>; pinctrl-0 = <&pcie4_default>;
pinctrl-names = "default"; pinctrl-names = "default";
@@ -1143,6 +1140,9 @@
}; };
&pcie4_port0 { &pcie4_port0 {
reset-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>;
wifi@0 { wifi@0 {
compatible = "pci17cb,1107"; compatible = "pci17cb,1107";
reg = <0x10000 0x0 0x0 0x0 0x0>; reg = <0x10000 0x0 0x0 0x0 0x0>;

View File

@@ -1033,9 +1033,6 @@
}; };
&pcie4 { &pcie4 {
perst-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>;
pinctrl-0 = <&pcie4_default>; pinctrl-0 = <&pcie4_default>;
pinctrl-names = "default"; pinctrl-names = "default";
@@ -1050,6 +1047,9 @@
}; };
&pcie4_port0 { &pcie4_port0 {
reset-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>;
wifi@0 { wifi@0 {
compatible = "pci17cb,1107"; compatible = "pci17cb,1107";
reg = <0x10000 0x0 0x0 0x0 0x0>; reg = <0x10000 0x0 0x0 0x0 0x0>;
@@ -1067,10 +1067,6 @@
}; };
&pcie6a { &pcie6a {
perst-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>;
vddpe-3v3-supply = <&vreg_nvme>; vddpe-3v3-supply = <&vreg_nvme>;
pinctrl-0 = <&pcie6a_default>; pinctrl-0 = <&pcie6a_default>;
@@ -1086,6 +1082,11 @@
status = "okay"; status = "okay";
}; };
&pcie6a_port0 {
reset-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>;
};
&pm8550_gpios { &pm8550_gpios {
rtmr0_default: rtmr0-reset-n-active-state { rtmr0_default: rtmr0-reset-n-active-state {
pins = "gpio10"; pins = "gpio10";

View File

@@ -1131,9 +1131,6 @@
}; };
&pcie4 { &pcie4 {
perst-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>;
pinctrl-0 = <&pcie4_default>; pinctrl-0 = <&pcie4_default>;
pinctrl-names = "default"; pinctrl-names = "default";
@@ -1148,6 +1145,9 @@
}; };
&pcie4_port0 { &pcie4_port0 {
reset-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>;
wifi@0 { wifi@0 {
compatible = "pci17cb,1107"; compatible = "pci17cb,1107";
reg = <0x10000 0x0 0x0 0x0 0x0>; reg = <0x10000 0x0 0x0 0x0 0x0>;
@@ -1165,9 +1165,6 @@
}; };
&pcie6a { &pcie6a {
perst-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>;
vddpe-3v3-supply = <&vreg_nvme>; vddpe-3v3-supply = <&vreg_nvme>;
pinctrl-0 = <&pcie6a_default>; pinctrl-0 = <&pcie6a_default>;
@@ -1183,6 +1180,11 @@
status = "okay"; status = "okay";
}; };
&pcie6a_port0 {
reset-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>;
};
&pm8550_pwm { &pm8550_pwm {
status = "okay"; status = "okay";
}; };

View File

@@ -118,6 +118,17 @@
reg = <0x6 0x00000000 0x1 0x00000000>; reg = <0x6 0x00000000 0x1 0x00000000>;
}; };
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
tfa@40000000 {
reg = <0x0 0x40000000 0x0 0x8000000>;
no-map;
};
};
/* Page 27 / DSI to Display */ /* Page 27 / DSI to Display */
dp-con { dp-con {
compatible = "dp-connector"; compatible = "dp-connector";

View File

@@ -879,12 +879,6 @@
}; };
}; };
wifi {
wifi_host_wake_l: wifi-host-wake-l {
rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
wireless-bluetooth { wireless-bluetooth {
bt_wake_pin: bt-wake-pin { bt_wake_pin: bt-wake-pin {
rockchip,pins = <2 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>; rockchip,pins = <2 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -942,19 +936,7 @@
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>; pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>;
sd-uhs-sdr104; sd-uhs-sdr104;
#address-cells = <1>;
#size-cells = <0>;
status = "okay"; status = "okay";
brcmf: wifi@1 {
compatible = "brcm,bcm4329-fmac";
reg = <1>;
interrupt-parent = <&gpio0>;
interrupts = <RK_PA3 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "host-wake";
pinctrl-names = "default";
pinctrl-0 = <&wifi_host_wake_l>;
};
}; };
&sdhci { &sdhci {

View File

@@ -0,0 +1,31 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_STATIC_CALL_H
#define _ASM_STATIC_CALL_H
#define __ARCH_DEFINE_STATIC_CALL_TRAMP(name, target) \
asm(" .pushsection .static_call.text, \"ax\" \n" \
" .align 4 \n" \
" .globl " name " \n" \
name ": \n" \
" hint 34 /* BTI C */ \n" \
" adrp x16, 1f \n" \
" ldr x16, [x16, :lo12:1f] \n" \
" br x16 \n" \
" .type " name ", %function \n" \
" .size " name ", . - " name " \n" \
" .popsection \n" \
" .pushsection .rodata, \"a\" \n" \
" .align 3 \n" \
"1: .quad " target " \n" \
" .popsection \n")
#define ARCH_DEFINE_STATIC_CALL_TRAMP(name, func) \
__ARCH_DEFINE_STATIC_CALL_TRAMP(STATIC_CALL_TRAMP_STR(name), #func)
#define ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name) \
ARCH_DEFINE_STATIC_CALL_TRAMP(name, __static_call_return0)
#define ARCH_DEFINE_STATIC_CALL_RET0_TRAMP(name) \
ARCH_DEFINE_STATIC_CALL_TRAMP(name, __static_call_return0)
#endif /* _ASM_STATIC_CALL_H */

View File

@@ -46,6 +46,7 @@ obj-$(CONFIG_MODULES) += module.o module-plts.o
obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o
obj-$(CONFIG_HARDLOCKUP_DETECTOR_PERF) += watchdog_hld.o obj-$(CONFIG_HARDLOCKUP_DETECTOR_PERF) += watchdog_hld.o
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
obj-$(CONFIG_HAVE_STATIC_CALL) += static_call.o
obj-$(CONFIG_CPU_PM) += sleep.o suspend.o obj-$(CONFIG_CPU_PM) += sleep.o suspend.o
obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_EFI) += efi.o efi-rt-wrapper.o obj-$(CONFIG_EFI) += efi.o efi-rt-wrapper.o

View File

@@ -0,0 +1,23 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/static_call.h>
#include <linux/memory.h>
#include <asm/text-patching.h>
void arch_static_call_transform(void *site, void *tramp, void *func, bool tail)
{
u64 literal;
int ret;
if (!func)
func = __static_call_return0;
/* decode the instructions to discover the literal address */
literal = ALIGN_DOWN((u64)tramp + 4, SZ_4K) +
aarch64_insn_adrp_get_offset(le32_to_cpup(tramp + 4)) +
8 * aarch64_insn_decode_immediate(AARCH64_INSN_IMM_12,
le32_to_cpup(tramp + 8));
ret = aarch64_insn_write_literal_u64((void *)literal, (u64)func);
WARN_ON_ONCE(ret);
}
EXPORT_SYMBOL_GPL(arch_static_call_transform);

View File

@@ -191,6 +191,7 @@ SECTIONS
LOCK_TEXT LOCK_TEXT
KPROBES_TEXT KPROBES_TEXT
HYPERVISOR_TEXT HYPERVISOR_TEXT
STATIC_CALL_TEXT
*(.gnu.warning) *(.gnu.warning)
} }

View File

@@ -484,7 +484,6 @@
# endif # endif
# ifndef cpu_vmbits # ifndef cpu_vmbits
# define cpu_vmbits cpu_data[0].vmbits # define cpu_vmbits cpu_data[0].vmbits
# define __NEED_VMBITS_PROBE
# endif # endif
#endif #endif

View File

@@ -80,9 +80,7 @@ struct cpuinfo_mips {
int srsets; /* Shadow register sets */ int srsets; /* Shadow register sets */
int package;/* physical package number */ int package;/* physical package number */
unsigned int globalnumber; unsigned int globalnumber;
#ifdef CONFIG_64BIT
int vmbits; /* Virtual memory size in bits */ int vmbits; /* Virtual memory size in bits */
#endif
void *data; /* Additional data */ void *data; /* Additional data */
unsigned int watch_reg_count; /* Number that exist */ unsigned int watch_reg_count; /* Number that exist */
unsigned int watch_reg_use_cnt; /* Usable by ptrace */ unsigned int watch_reg_use_cnt; /* Usable by ptrace */

View File

@@ -1871,6 +1871,8 @@ do { \
#define read_c0_entryhi() __read_ulong_c0_register($10, 0) #define read_c0_entryhi() __read_ulong_c0_register($10, 0)
#define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val) #define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val)
#define read_c0_entryhi_64() __read_64bit_c0_register($10, 0)
#define write_c0_entryhi_64(val) __write_64bit_c0_register($10, 0, val)
#define read_c0_guestctl1() __read_32bit_c0_register($10, 4) #define read_c0_guestctl1() __read_32bit_c0_register($10, 4)
#define write_c0_guestctl1(val) __write_32bit_c0_register($10, 4, val) #define write_c0_guestctl1(val) __write_32bit_c0_register($10, 4, val)

View File

@@ -210,11 +210,14 @@ static inline void set_elf_base_platform(const char *plat)
static inline void cpu_probe_vmbits(struct cpuinfo_mips *c) static inline void cpu_probe_vmbits(struct cpuinfo_mips *c)
{ {
#ifdef __NEED_VMBITS_PROBE int vmbits = 31;
write_c0_entryhi(0x3fffffffffffe000ULL);
back_to_back_c0_hazard(); if (cpu_has_64bits) {
c->vmbits = fls64(read_c0_entryhi() & 0x3fffffffffffe000ULL); write_c0_entryhi_64(0x3fffffffffffe000ULL);
#endif back_to_back_c0_hazard();
vmbits = fls64(read_c0_entryhi_64() & 0x3fffffffffffe000ULL);
}
c->vmbits = vmbits;
} }
static void set_isa(struct cpuinfo_mips *c, unsigned int isa) static void set_isa(struct cpuinfo_mips *c, unsigned int isa)

View File

@@ -137,6 +137,8 @@ void cpu_probe(void)
else else
cpu_set_nofpu_opts(c); cpu_set_nofpu_opts(c);
c->vmbits = 31;
reserve_exception_space(0, 0x400); reserve_exception_space(0, 0x400);
} }

View File

@@ -4,12 +4,12 @@
#include "libgcc.h" #include "libgcc.h"
/* /*
* GCC 7 & older can suboptimally generate __multi3 calls for mips64r6, so for * GCC 9 & older can suboptimally generate __multi3 calls for mips64r6, so for
* that specific case only we implement that intrinsic here. * that specific case only we implement that intrinsic here.
* *
* See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82981 * See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82981
*/ */
#if defined(CONFIG_64BIT) && defined(CONFIG_CPU_MIPSR6) && (__GNUC__ < 8) #if defined(CONFIG_64BIT) && defined(CONFIG_CPU_MIPSR6) && (__GNUC__ < 10)
/* multiply 64-bit values, low 64-bits returned */ /* multiply 64-bit values, low 64-bits returned */
static inline long long notrace dmulu(long long a, long long b) static inline long long notrace dmulu(long long a, long long b)
@@ -51,4 +51,4 @@ ti_type notrace __multi3(ti_type a, ti_type b)
} }
EXPORT_SYMBOL(__multi3); EXPORT_SYMBOL(__multi3);
#endif /* 64BIT && CPU_MIPSR6 && GCC7 */ #endif /* 64BIT && CPU_MIPSR6 && GCC9 */

View File

@@ -17,7 +17,9 @@
#include <linux/dma-map-ops.h> #include <linux/dma-map-ops.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/libfdt.h> #include <linux/libfdt.h>
#include <linux/minmax.h>
#include <linux/pci_ids.h> #include <linux/pci_ids.h>
#include <linux/serial_core.h>
#include <linux/string_choices.h> #include <linux/string_choices.h>
#include <asm/bootinfo.h> #include <asm/bootinfo.h>
#include <loongson.h> #include <loongson.h>
@@ -106,9 +108,23 @@ static void __init lefi_fixup_fdt(struct system_loongson *system)
is_loongson64g = (read_c0_prid() & PRID_IMP_MASK) == PRID_IMP_LOONGSON_64G; is_loongson64g = (read_c0_prid() & PRID_IMP_MASK) == PRID_IMP_LOONGSON_64G;
for (i = 0; i < system->nr_uarts; i++) { for (i = 0; i < min(system->nr_uarts, MAX_UARTS); i++) {
uartdev = &system->uarts[i]; uartdev = &system->uarts[i];
/*
* Some firmware does not set nr_uarts properly and passes empty
* items. Ignore them silently.
*/
if (uartdev->uart_base == 0)
continue;
/* Our DT only works with UPIO_MEM. */
if (uartdev->iotype != UPIO_MEM) {
pr_warn("Ignore UART 0x%llx with iotype %u passed by firmware\n",
uartdev->uart_base, uartdev->iotype);
continue;
}
ret = lefi_fixup_fdt_serial(fdt_buf, uartdev->uart_base, ret = lefi_fixup_fdt_serial(fdt_buf, uartdev->uart_base,
uartdev->uartclk); uartdev->uartclk);
/* /*

View File

@@ -207,7 +207,8 @@ void cpu_cache_init(void)
{ {
if (IS_ENABLED(CONFIG_CPU_R3000) && cpu_has_3k_cache) if (IS_ENABLED(CONFIG_CPU_R3000) && cpu_has_3k_cache)
r3k_cache_init(); r3k_cache_init();
if (IS_ENABLED(CONFIG_CPU_R4K_CACHE_TLB) && cpu_has_4k_cache) if ((IS_ENABLED(CONFIG_CPU_R4K_CACHE_TLB) ||
IS_ENABLED(CONFIG_CPU_SB1)) && cpu_has_4k_cache)
r4k_cache_init(); r4k_cache_init();
if (IS_ENABLED(CONFIG_CPU_CAVIUM_OCTEON) && cpu_has_octeon_cache) if (IS_ENABLED(CONFIG_CPU_CAVIUM_OCTEON) && cpu_has_octeon_cache)

View File

@@ -13,6 +13,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/memblock.h> #include <linux/memblock.h>
#include <linux/minmax.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/hugetlb.h> #include <linux/hugetlb.h>
#include <linux/export.h> #include <linux/export.h>
@@ -24,6 +25,7 @@
#include <asm/hazards.h> #include <asm/hazards.h>
#include <asm/mmu_context.h> #include <asm/mmu_context.h>
#include <asm/tlb.h> #include <asm/tlb.h>
#include <asm/tlbdebug.h>
#include <asm/tlbex.h> #include <asm/tlbex.h>
#include <asm/tlbmisc.h> #include <asm/tlbmisc.h>
#include <asm/setup.h> #include <asm/setup.h>
@@ -511,12 +513,229 @@ static int __init set_ntlb(char *str)
__setup("ntlb=", set_ntlb); __setup("ntlb=", set_ntlb);
/* Comparison function for EntryHi VPN fields. */ /* The start bit position of VPN2 and Mask in EntryHi/PageMask registers. */
static int r4k_vpn_cmp(const void *a, const void *b) #define VPN2_SHIFT 13
/* Read full EntryHi even with CONFIG_32BIT. */
static inline unsigned long long read_c0_entryhi_native(void)
{ {
long v = *(unsigned long *)a - *(unsigned long *)b; return cpu_has_64bits ? read_c0_entryhi_64() : read_c0_entryhi();
int s = sizeof(long) > sizeof(int) ? sizeof(long) * 8 - 1: 0; }
return s ? (v != 0) | v >> s : v;
/* Write full EntryHi even with CONFIG_32BIT. */
static inline void write_c0_entryhi_native(unsigned long long v)
{
if (cpu_has_64bits)
write_c0_entryhi_64(v);
else
write_c0_entryhi(v);
}
/* TLB entry state for uniquification. */
struct tlbent {
unsigned long long wired:1;
unsigned long long global:1;
unsigned long long asid:10;
unsigned long long vpn:51;
unsigned long long pagesz:5;
unsigned long long index:14;
};
/*
* Comparison function for TLB entry sorting. Place wired entries first,
* then global entries, then order by the increasing VPN/ASID and the
* decreasing page size. This lets us avoid clashes with wired entries
* easily and get entries for larger pages out of the way first.
*
* We could group bits so as to reduce the number of comparisons, but this
* is seldom executed and not performance-critical, so prefer legibility.
*/
static int r4k_entry_cmp(const void *a, const void *b)
{
struct tlbent ea = *(struct tlbent *)a, eb = *(struct tlbent *)b;
if (ea.wired > eb.wired)
return -1;
else if (ea.wired < eb.wired)
return 1;
else if (ea.global > eb.global)
return -1;
else if (ea.global < eb.global)
return 1;
else if (ea.vpn < eb.vpn)
return -1;
else if (ea.vpn > eb.vpn)
return 1;
else if (ea.asid < eb.asid)
return -1;
else if (ea.asid > eb.asid)
return 1;
else if (ea.pagesz > eb.pagesz)
return -1;
else if (ea.pagesz < eb.pagesz)
return 1;
else
return 0;
}
/*
* Fetch all the TLB entries. Mask individual VPN values retrieved with
* the corresponding page mask and ignoring any 1KiB extension as we'll
* be using 4KiB pages for uniquification.
*/
static void __ref r4k_tlb_uniquify_read(struct tlbent *tlb_vpns, int tlbsize)
{
int start = num_wired_entries();
unsigned long long vpn_mask;
bool global;
int i;
vpn_mask = GENMASK(current_cpu_data.vmbits - 1, VPN2_SHIFT);
vpn_mask |= cpu_has_64bits ? 3ULL << 62 : 1 << 31;
for (i = 0; i < tlbsize; i++) {
unsigned long long entryhi, vpn, mask, asid;
unsigned int pagesz;
write_c0_index(i);
mtc0_tlbr_hazard();
tlb_read();
tlb_read_hazard();
global = !!(read_c0_entrylo0() & ENTRYLO_G);
entryhi = read_c0_entryhi_native();
mask = read_c0_pagemask();
asid = entryhi & cpu_asid_mask(&current_cpu_data);
vpn = (entryhi & vpn_mask & ~mask) >> VPN2_SHIFT;
pagesz = ilog2((mask >> VPN2_SHIFT) + 1);
tlb_vpns[i].global = global;
tlb_vpns[i].asid = global ? 0 : asid;
tlb_vpns[i].vpn = vpn;
tlb_vpns[i].pagesz = pagesz;
tlb_vpns[i].wired = i < start;
tlb_vpns[i].index = i;
}
}
/*
* Write unique values to all but the wired TLB entries each, using
* the 4KiB page size. This size might not be supported with R6, but
* EHINV is mandatory for R6, so we won't ever be called in that case.
*
* A sorted table is supplied with any wired entries at the beginning,
* followed by any global entries, and then finally regular entries.
* We start at the VPN and ASID values of zero and only assign user
* addresses, therefore guaranteeing no clash with addresses produced
* by UNIQUE_ENTRYHI. We avoid any VPN values used by wired or global
* entries, by increasing the VPN value beyond the span of such entry.
*
* When a VPN/ASID clash is found with a regular entry we increment the
* ASID instead until no VPN/ASID clash has been found or the ASID space
* has been exhausted, in which case we increase the VPN value beyond
* the span of the largest clashing entry.
*
* We do not need to be concerned about FTLB or MMID configurations as
* those are required to implement the EHINV feature.
*/
static void __ref r4k_tlb_uniquify_write(struct tlbent *tlb_vpns, int tlbsize)
{
unsigned long long asid, vpn, vpn_size, pagesz;
int widx, gidx, idx, sidx, lidx, i;
vpn_size = 1ULL << (current_cpu_data.vmbits - VPN2_SHIFT);
pagesz = ilog2((PM_4K >> VPN2_SHIFT) + 1);
write_c0_pagemask(PM_4K);
write_c0_entrylo0(0);
write_c0_entrylo1(0);
asid = 0;
vpn = 0;
widx = 0;
gidx = 0;
for (sidx = 0; sidx < tlbsize && tlb_vpns[sidx].wired; sidx++)
;
for (lidx = sidx; lidx < tlbsize && tlb_vpns[lidx].global; lidx++)
;
idx = gidx = sidx + 1;
for (i = sidx; i < tlbsize; i++) {
unsigned long long entryhi, vpn_pagesz = 0;
while (1) {
if (WARN_ON(vpn >= vpn_size)) {
dump_tlb_all();
/* Pray local_flush_tlb_all() will cope. */
return;
}
/* VPN must be below the next wired entry. */
if (widx < sidx && vpn >= tlb_vpns[widx].vpn) {
vpn = max(vpn,
(tlb_vpns[widx].vpn +
(1ULL << tlb_vpns[widx].pagesz)));
asid = 0;
widx++;
continue;
}
/* VPN must be below the next global entry. */
if (gidx < lidx && vpn >= tlb_vpns[gidx].vpn) {
vpn = max(vpn,
(tlb_vpns[gidx].vpn +
(1ULL << tlb_vpns[gidx].pagesz)));
asid = 0;
gidx++;
continue;
}
/* Try to find a free ASID so as to conserve VPNs. */
if (idx < tlbsize && vpn == tlb_vpns[idx].vpn &&
asid == tlb_vpns[idx].asid) {
unsigned long long idx_pagesz;
idx_pagesz = tlb_vpns[idx].pagesz;
vpn_pagesz = max(vpn_pagesz, idx_pagesz);
do
idx++;
while (idx < tlbsize &&
vpn == tlb_vpns[idx].vpn &&
asid == tlb_vpns[idx].asid);
asid++;
if (asid > cpu_asid_mask(&current_cpu_data)) {
vpn += vpn_pagesz;
asid = 0;
vpn_pagesz = 0;
}
continue;
}
/* VPN mustn't be above the next regular entry. */
if (idx < tlbsize && vpn > tlb_vpns[idx].vpn) {
vpn = max(vpn,
(tlb_vpns[idx].vpn +
(1ULL << tlb_vpns[idx].pagesz)));
asid = 0;
idx++;
continue;
}
break;
}
entryhi = (vpn << VPN2_SHIFT) | asid;
write_c0_entryhi_native(entryhi);
write_c0_index(tlb_vpns[i].index);
mtc0_tlbw_hazard();
tlb_write_indexed();
tlb_vpns[i].asid = asid;
tlb_vpns[i].vpn = vpn;
tlb_vpns[i].pagesz = pagesz;
asid++;
if (asid > cpu_asid_mask(&current_cpu_data)) {
vpn += 1ULL << pagesz;
asid = 0;
}
}
} }
/* /*
@@ -527,70 +746,25 @@ static void __ref r4k_tlb_uniquify(void)
{ {
int tlbsize = current_cpu_data.tlbsize; int tlbsize = current_cpu_data.tlbsize;
bool use_slab = slab_is_available(); bool use_slab = slab_is_available();
int start = num_wired_entries();
phys_addr_t tlb_vpn_size; phys_addr_t tlb_vpn_size;
unsigned long *tlb_vpns; struct tlbent *tlb_vpns;
unsigned long vpn_mask;
int cnt, ent, idx, i;
vpn_mask = GENMASK(cpu_vmbits - 1, 13);
vpn_mask |= IS_ENABLED(CONFIG_64BIT) ? 3ULL << 62 : 1 << 31;
tlb_vpn_size = tlbsize * sizeof(*tlb_vpns); tlb_vpn_size = tlbsize * sizeof(*tlb_vpns);
tlb_vpns = (use_slab ? tlb_vpns = (use_slab ?
kmalloc(tlb_vpn_size, GFP_KERNEL) : kmalloc(tlb_vpn_size, GFP_ATOMIC) :
memblock_alloc_raw(tlb_vpn_size, sizeof(*tlb_vpns))); memblock_alloc_raw(tlb_vpn_size, sizeof(*tlb_vpns)));
if (WARN_ON(!tlb_vpns)) if (WARN_ON(!tlb_vpns))
return; /* Pray local_flush_tlb_all() is good enough. */ return; /* Pray local_flush_tlb_all() is good enough. */
htw_stop(); htw_stop();
for (i = start, cnt = 0; i < tlbsize; i++, cnt++) { r4k_tlb_uniquify_read(tlb_vpns, tlbsize);
unsigned long vpn;
write_c0_index(i); sort(tlb_vpns, tlbsize, sizeof(*tlb_vpns), r4k_entry_cmp, NULL);
mtc0_tlbr_hazard();
tlb_read();
tlb_read_hazard();
vpn = read_c0_entryhi();
vpn &= vpn_mask & PAGE_MASK;
tlb_vpns[cnt] = vpn;
/* Prevent any large pages from overlapping regular ones. */ r4k_tlb_uniquify_write(tlb_vpns, tlbsize);
write_c0_pagemask(read_c0_pagemask() & PM_DEFAULT_MASK);
mtc0_tlbw_hazard();
tlb_write_indexed();
tlbw_use_hazard();
}
sort(tlb_vpns, cnt, sizeof(tlb_vpns[0]), r4k_vpn_cmp, NULL);
write_c0_pagemask(PM_DEFAULT_MASK); write_c0_pagemask(PM_DEFAULT_MASK);
write_c0_entrylo0(0);
write_c0_entrylo1(0);
idx = 0;
ent = tlbsize;
for (i = start; i < tlbsize; i++)
while (1) {
unsigned long entryhi, vpn;
entryhi = UNIQUE_ENTRYHI(ent);
vpn = entryhi & vpn_mask & PAGE_MASK;
if (idx >= cnt || vpn < tlb_vpns[idx]) {
write_c0_entryhi(entryhi);
write_c0_index(i);
mtc0_tlbw_hazard();
tlb_write_indexed();
ent++;
break;
} else if (vpn == tlb_vpns[idx]) {
ent++;
} else {
idx++;
}
}
tlbw_use_hazard(); tlbw_use_hazard();
htw_start(); htw_start();
@@ -640,7 +814,8 @@ static void r4k_tlb_configure(void)
temp_tlb_entry = current_cpu_data.tlbsize - 1; temp_tlb_entry = current_cpu_data.tlbsize - 1;
/* From this point on the ARC firmware is dead. */ /* From this point on the ARC firmware is dead. */
r4k_tlb_uniquify(); if (!cpu_has_tlbinv)
r4k_tlb_uniquify();
local_flush_tlb_all(); local_flush_tlb_all();
/* Did I tell you that ARC SUCKS? */ /* Did I tell you that ARC SUCKS? */

View File

@@ -21,16 +21,16 @@ static const char *clk_cpu(int *idx)
{ {
switch (ralink_soc) { switch (ralink_soc) {
case RT2880_SOC: case RT2880_SOC:
*idx = 0; *idx = 1;
return "ralink,rt2880-sysc"; return "ralink,rt2880-sysc";
case RT3883_SOC: case RT3883_SOC:
*idx = 0; *idx = 1;
return "ralink,rt3883-sysc"; return "ralink,rt3883-sysc";
case RT305X_SOC_RT3050: case RT305X_SOC_RT3050:
*idx = 0; *idx = 1;
return "ralink,rt3050-sysc"; return "ralink,rt3050-sysc";
case RT305X_SOC_RT3052: case RT305X_SOC_RT3052:
*idx = 0; *idx = 1;
return "ralink,rt3052-sysc"; return "ralink,rt3052-sysc";
case RT305X_SOC_RT3350: case RT305X_SOC_RT3350:
*idx = 1; *idx = 1;

View File

@@ -67,7 +67,7 @@ bool arch_dma_unmap_sg_direct(struct device *dev, struct scatterlist *sg,
} }
bool arch_dma_alloc_direct(struct device *dev) bool arch_dma_alloc_direct(struct device *dev)
{ {
if (dev->dma_ops_bypass) if (dev->dma_ops_bypass && dev->bus_dma_limit)
return true; return true;
return false; return false;
@@ -75,7 +75,7 @@ bool arch_dma_alloc_direct(struct device *dev)
bool arch_dma_free_direct(struct device *dev, dma_addr_t dma_handle) bool arch_dma_free_direct(struct device *dev, dma_addr_t dma_handle)
{ {
if (!dev->dma_ops_bypass) if (!dev->dma_ops_bypass || !dev->bus_dma_limit)
return false; return false;
return is_direct_handle(dev, dma_handle); return is_direct_handle(dev, dma_handle);

View File

@@ -2,6 +2,10 @@
#ifndef _ASM_RISCV_RUNTIME_CONST_H #ifndef _ASM_RISCV_RUNTIME_CONST_H
#define _ASM_RISCV_RUNTIME_CONST_H #define _ASM_RISCV_RUNTIME_CONST_H
#ifdef MODULE
#error "Cannot use runtime-const infrastructure from modules"
#endif
#include <asm/asm.h> #include <asm/asm.h>
#include <asm/alternative.h> #include <asm/alternative.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>

View File

@@ -9,6 +9,7 @@
#ifndef __ASSEMBLER__ #ifndef __ASSEMBLER__
#include <linux/types.h> #include <linux/types.h>
#include <linux/const.h>
#define PTRACE_GETFDPIC 33 #define PTRACE_GETFDPIC 33
@@ -138,12 +139,12 @@ struct __sc_riscv_cfi_state {
#define PTRACE_CFI_SS_LOCK_BIT 4 #define PTRACE_CFI_SS_LOCK_BIT 4
#define PTRACE_CFI_SS_PTR_BIT 5 #define PTRACE_CFI_SS_PTR_BIT 5
#define PTRACE_CFI_LP_EN_STATE BIT(PTRACE_CFI_LP_EN_BIT) #define PTRACE_CFI_LP_EN_STATE _BITUL(PTRACE_CFI_LP_EN_BIT)
#define PTRACE_CFI_LP_LOCK_STATE BIT(PTRACE_CFI_LP_LOCK_BIT) #define PTRACE_CFI_LP_LOCK_STATE _BITUL(PTRACE_CFI_LP_LOCK_BIT)
#define PTRACE_CFI_ELP_STATE BIT(PTRACE_CFI_ELP_BIT) #define PTRACE_CFI_ELP_STATE _BITUL(PTRACE_CFI_ELP_BIT)
#define PTRACE_CFI_SS_EN_STATE BIT(PTRACE_CFI_SS_EN_BIT) #define PTRACE_CFI_SS_EN_STATE _BITUL(PTRACE_CFI_SS_EN_BIT)
#define PTRACE_CFI_SS_LOCK_STATE BIT(PTRACE_CFI_SS_LOCK_BIT) #define PTRACE_CFI_SS_LOCK_STATE _BITUL(PTRACE_CFI_SS_LOCK_BIT)
#define PTRACE_CFI_SS_PTR_STATE BIT(PTRACE_CFI_SS_PTR_BIT) #define PTRACE_CFI_SS_PTR_STATE _BITUL(PTRACE_CFI_SS_PTR_BIT)
#define PRACE_CFI_STATE_INVALID_MASK ~(PTRACE_CFI_LP_EN_STATE | \ #define PRACE_CFI_STATE_INVALID_MASK ~(PTRACE_CFI_LP_EN_STATE | \
PTRACE_CFI_LP_LOCK_STATE | \ PTRACE_CFI_LP_LOCK_STATE | \

View File

@@ -175,7 +175,7 @@ struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
{DBG_REG_T1, GDB_SIZEOF_REG, offsetof(struct pt_regs, t1)}, {DBG_REG_T1, GDB_SIZEOF_REG, offsetof(struct pt_regs, t1)},
{DBG_REG_T2, GDB_SIZEOF_REG, offsetof(struct pt_regs, t2)}, {DBG_REG_T2, GDB_SIZEOF_REG, offsetof(struct pt_regs, t2)},
{DBG_REG_FP, GDB_SIZEOF_REG, offsetof(struct pt_regs, s0)}, {DBG_REG_FP, GDB_SIZEOF_REG, offsetof(struct pt_regs, s0)},
{DBG_REG_S1, GDB_SIZEOF_REG, offsetof(struct pt_regs, a1)}, {DBG_REG_S1, GDB_SIZEOF_REG, offsetof(struct pt_regs, s1)},
{DBG_REG_A0, GDB_SIZEOF_REG, offsetof(struct pt_regs, a0)}, {DBG_REG_A0, GDB_SIZEOF_REG, offsetof(struct pt_regs, a0)},
{DBG_REG_A1, GDB_SIZEOF_REG, offsetof(struct pt_regs, a1)}, {DBG_REG_A1, GDB_SIZEOF_REG, offsetof(struct pt_regs, a1)},
{DBG_REG_A2, GDB_SIZEOF_REG, offsetof(struct pt_regs, a2)}, {DBG_REG_A2, GDB_SIZEOF_REG, offsetof(struct pt_regs, a2)},
@@ -244,8 +244,9 @@ sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
gdb_regs[DBG_REG_S6_OFF] = task->thread.s[6]; gdb_regs[DBG_REG_S6_OFF] = task->thread.s[6];
gdb_regs[DBG_REG_S7_OFF] = task->thread.s[7]; gdb_regs[DBG_REG_S7_OFF] = task->thread.s[7];
gdb_regs[DBG_REG_S8_OFF] = task->thread.s[8]; gdb_regs[DBG_REG_S8_OFF] = task->thread.s[8];
gdb_regs[DBG_REG_S9_OFF] = task->thread.s[10]; gdb_regs[DBG_REG_S9_OFF] = task->thread.s[9];
gdb_regs[DBG_REG_S10_OFF] = task->thread.s[11]; gdb_regs[DBG_REG_S10_OFF] = task->thread.s[10];
gdb_regs[DBG_REG_S11_OFF] = task->thread.s[11];
gdb_regs[DBG_REG_EPC_OFF] = task->thread.ra; gdb_regs[DBG_REG_EPC_OFF] = task->thread.ra;
} }

View File

@@ -42,19 +42,20 @@ static inline bool is_kernel_exittext(uintptr_t addr)
static __always_inline void *patch_map(void *addr, const unsigned int fixmap) static __always_inline void *patch_map(void *addr, const unsigned int fixmap)
{ {
uintptr_t uintaddr = (uintptr_t) addr; uintptr_t uintaddr = (uintptr_t) addr;
struct page *page; phys_addr_t phys;
if (core_kernel_text(uintaddr) || is_kernel_exittext(uintaddr)) if (core_kernel_text(uintaddr) || is_kernel_exittext(uintaddr)) {
page = phys_to_page(__pa_symbol(addr)); phys = __pa_symbol(addr);
else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) } else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) {
page = vmalloc_to_page(addr); struct page *page = vmalloc_to_page(addr);
else
BUG_ON(!page);
phys = page_to_phys(page) + offset_in_page(addr);
} else {
return addr; return addr;
}
BUG_ON(!page); return (void *)set_fixmap_offset(fixmap, phys);
return (void *)set_fixmap_offset(fixmap, page_to_phys(page) +
offset_in_page(addr));
} }
static void patch_unmap(int fixmap) static void patch_unmap(int fixmap)

View File

@@ -347,8 +347,10 @@ long set_tagged_addr_ctrl(struct task_struct *task, unsigned long arg)
if (arg & PR_TAGGED_ADDR_ENABLE && (tagged_addr_disabled || !pmlen)) if (arg & PR_TAGGED_ADDR_ENABLE && (tagged_addr_disabled || !pmlen))
return -EINVAL; return -EINVAL;
if (!(arg & PR_TAGGED_ADDR_ENABLE)) if (!(arg & PR_TAGGED_ADDR_ENABLE)) {
pmlen = PMLEN_0; pmlen = PMLEN_0;
pmm = ENVCFG_PMM_PMLEN_0;
}
if (mmap_write_lock_killable(mm)) if (mmap_write_lock_killable(mm))
return -EINTR; return -EINTR;

View File

@@ -1168,6 +1168,7 @@ static void hw_collect_samples(struct perf_event *event, unsigned long *sdbt,
static void hw_perf_event_update(struct perf_event *event, int flush_all) static void hw_perf_event_update(struct perf_event *event, int flush_all)
{ {
unsigned long long event_overflow, sampl_overflow, num_sdb; unsigned long long event_overflow, sampl_overflow, num_sdb;
struct cpu_hw_sf *cpuhw = this_cpu_ptr(&cpu_hw_sf);
struct hw_perf_event *hwc = &event->hw; struct hw_perf_event *hwc = &event->hw;
union hws_trailer_header prev, new; union hws_trailer_header prev, new;
struct hws_trailer_entry *te; struct hws_trailer_entry *te;
@@ -1247,8 +1248,11 @@ static void hw_perf_event_update(struct perf_event *event, int flush_all)
* are dropped. * are dropped.
* Slightly increase the interval to avoid hitting this limit. * Slightly increase the interval to avoid hitting this limit.
*/ */
if (event_overflow) if (event_overflow) {
SAMPL_RATE(hwc) += DIV_ROUND_UP(SAMPL_RATE(hwc), 10); SAMPL_RATE(hwc) += DIV_ROUND_UP(SAMPL_RATE(hwc), 10);
if (SAMPL_RATE(hwc) > cpuhw->qsi.max_sampl_rate)
SAMPL_RATE(hwc) = cpuhw->qsi.max_sampl_rate;
}
} }
static inline unsigned long aux_sdb_index(struct aux_buffer *aux, static inline unsigned long aux_sdb_index(struct aux_buffer *aux,

View File

@@ -4855,8 +4855,10 @@ static int intel_pmu_hw_config(struct perf_event *event)
intel_pmu_set_acr_caused_constr(leader, idx++, cause_mask); intel_pmu_set_acr_caused_constr(leader, idx++, cause_mask);
if (leader->nr_siblings) { if (leader->nr_siblings) {
for_each_sibling_event(sibling, leader) for_each_sibling_event(sibling, leader) {
intel_pmu_set_acr_caused_constr(sibling, idx++, cause_mask); if (is_x86_event(sibling))
intel_pmu_set_acr_caused_constr(sibling, idx++, cause_mask);
}
} }
if (leader != event) if (leader != event)

View File

@@ -44,6 +44,20 @@ KCOV_INSTRUMENT_unwind_orc.o := n
KCOV_INSTRUMENT_unwind_frame.o := n KCOV_INSTRUMENT_unwind_frame.o := n
KCOV_INSTRUMENT_unwind_guess.o := n KCOV_INSTRUMENT_unwind_guess.o := n
# Disable KCOV to prevent crashes during kexec: load_segments() invalidates
# the GS base, which KCOV relies on for per-CPU data.
#
# As KCOV and KEXEC compatibility should be preserved (e.g. syzkaller is
# using it to collect crash dumps during kernel fuzzing), disabling
# KCOV for KEXEC kernels is not an option. Selectively disabling KCOV
# instrumentation for individual affected functions can be fragile, while
# adding more checks to KCOV would slow it down.
#
# As a compromise solution, disable KCOV instrumentation for the whole
# source code file. If its coverage is ever needed, other approaches
# should be considered.
KCOV_INSTRUMENT_machine_kexec_64.o := n
CFLAGS_head32.o := -fno-stack-protector CFLAGS_head32.o := -fno-stack-protector
CFLAGS_head64.o := -fno-stack-protector CFLAGS_head64.o := -fno-stack-protector
CFLAGS_irq.o := -I $(src)/../include/asm/trace CFLAGS_irq.o := -I $(src)/../include/asm/trace

View File

@@ -351,7 +351,8 @@ static int shstk_pop_sigframe(unsigned long *ssp)
need_to_check_vma = PAGE_ALIGN(*ssp) == *ssp; need_to_check_vma = PAGE_ALIGN(*ssp) == *ssp;
if (need_to_check_vma) if (need_to_check_vma)
mmap_read_lock_killable(current->mm); if (mmap_read_lock_killable(current->mm))
return -EINTR;
err = get_shstk_data(&token_addr, (unsigned long __user *)*ssp); err = get_shstk_data(&token_addr, (unsigned long __user *)*ssp);
if (unlikely(err)) if (unlikely(err))

View File

@@ -4,6 +4,8 @@ KCOV_INSTRUMENT_tlb.o := n
KCOV_INSTRUMENT_mem_encrypt.o := n KCOV_INSTRUMENT_mem_encrypt.o := n
KCOV_INSTRUMENT_mem_encrypt_amd.o := n KCOV_INSTRUMENT_mem_encrypt_amd.o := n
KCOV_INSTRUMENT_pgprot.o := n KCOV_INSTRUMENT_pgprot.o := n
# See the "Disable KCOV" comment in arch/x86/kernel/Makefile.
KCOV_INSTRUMENT_physaddr.o := n
KASAN_SANITIZE_mem_encrypt.o := n KASAN_SANITIZE_mem_encrypt.o := n
KASAN_SANITIZE_mem_encrypt_amd.o := n KASAN_SANITIZE_mem_encrypt_amd.o := n

View File

@@ -28,8 +28,10 @@ static const struct software_node geode_gpio_keys_node = {
.properties = geode_gpio_keys_props, .properties = geode_gpio_keys_props,
}; };
static struct property_entry geode_restart_key_props[] = { static struct software_node_ref_args geode_restart_gpio_ref;
{ /* Placeholder for GPIO property */ },
static const struct property_entry geode_restart_key_props[] = {
PROPERTY_ENTRY_REF_ARRAY_LEN("gpios", &geode_restart_gpio_ref, 1),
PROPERTY_ENTRY_U32("linux,code", KEY_RESTART), PROPERTY_ENTRY_U32("linux,code", KEY_RESTART),
PROPERTY_ENTRY_STRING("label", "Reset button"), PROPERTY_ENTRY_STRING("label", "Reset button"),
PROPERTY_ENTRY_U32("debounce-interval", 100), PROPERTY_ENTRY_U32("debounce-interval", 100),
@@ -64,8 +66,7 @@ int __init geode_create_restart_key(unsigned int pin)
struct platform_device *pd; struct platform_device *pd;
int err; int err;
geode_restart_key_props[0] = PROPERTY_ENTRY_GPIO("gpios", geode_restart_gpio_ref = SOFTWARE_NODE_REFERENCE(&geode_gpiochip_node,
&geode_gpiochip_node,
pin, GPIO_ACTIVE_LOW); pin, GPIO_ACTIVE_LOW);
err = software_node_register_node_group(geode_gpio_keys_swnodes); err = software_node_register_node_group(geode_gpio_keys_swnodes);
@@ -99,6 +100,7 @@ int __init geode_create_leds(const char *label, const struct geode_led *leds,
const struct software_node *group[MAX_LEDS + 2] = { 0 }; const struct software_node *group[MAX_LEDS + 2] = { 0 };
struct software_node *swnodes; struct software_node *swnodes;
struct property_entry *props; struct property_entry *props;
struct software_node_ref_args *gpio_refs;
struct platform_device_info led_info = { struct platform_device_info led_info = {
.name = "leds-gpio", .name = "leds-gpio",
.id = PLATFORM_DEVID_NONE, .id = PLATFORM_DEVID_NONE,
@@ -127,6 +129,12 @@ int __init geode_create_leds(const char *label, const struct geode_led *leds,
goto err_free_swnodes; goto err_free_swnodes;
} }
gpio_refs = kzalloc_objs(*gpio_refs, n_leds);
if (!gpio_refs) {
err = -ENOMEM;
goto err_free_props;
}
group[0] = &geode_gpio_leds_node; group[0] = &geode_gpio_leds_node;
for (i = 0; i < n_leds; i++) { for (i = 0; i < n_leds; i++) {
node_name = kasprintf(GFP_KERNEL, "%s:%d", label, i); node_name = kasprintf(GFP_KERNEL, "%s:%d", label, i);
@@ -135,9 +143,11 @@ int __init geode_create_leds(const char *label, const struct geode_led *leds,
goto err_free_names; goto err_free_names;
} }
gpio_refs[i] = SOFTWARE_NODE_REFERENCE(&geode_gpiochip_node,
leds[i].pin,
GPIO_ACTIVE_LOW);
props[i * 3 + 0] = props[i * 3 + 0] =
PROPERTY_ENTRY_GPIO("gpios", &geode_gpiochip_node, PROPERTY_ENTRY_REF_ARRAY_LEN("gpios", &gpio_refs[i], 1);
leds[i].pin, GPIO_ACTIVE_LOW);
props[i * 3 + 1] = props[i * 3 + 1] =
PROPERTY_ENTRY_STRING("linux,default-trigger", PROPERTY_ENTRY_STRING("linux,default-trigger",
leds[i].default_on ? leds[i].default_on ?
@@ -171,6 +181,8 @@ err_unregister_group:
err_free_names: err_free_names:
while (--i >= 0) while (--i >= 0)
kfree(swnodes[i].name); kfree(swnodes[i].name);
kfree(gpio_refs);
err_free_props:
kfree(props); kfree(props);
err_free_swnodes: err_free_swnodes:
kfree(swnodes); kfree(swnodes);

View File

@@ -623,8 +623,10 @@ static int af_alg_alloc_tsgl(struct sock *sk)
sg_init_table(sgl->sg, MAX_SGL_ENTS + 1); sg_init_table(sgl->sg, MAX_SGL_ENTS + 1);
sgl->cur = 0; sgl->cur = 0;
if (sg) if (sg) {
sg_unmark_end(sg + MAX_SGL_ENTS - 1);
sg_chain(sg, MAX_SGL_ENTS + 1, sgl->sg); sg_chain(sg, MAX_SGL_ENTS + 1, sgl->sg);
}
list_add_tail(&sgl->list, &ctx->tsgl_list); list_add_tail(&sgl->list, &ctx->tsgl_list);
} }
@@ -635,15 +637,13 @@ static int af_alg_alloc_tsgl(struct sock *sk)
/** /**
* af_alg_count_tsgl - Count number of TX SG entries * af_alg_count_tsgl - Count number of TX SG entries
* *
* The counting starts from the beginning of the SGL to @bytes. If * The counting starts from the beginning of the SGL to @bytes.
* an @offset is provided, the counting of the SG entries starts at the @offset.
* *
* @sk: socket of connection to user space * @sk: socket of connection to user space
* @bytes: Count the number of SG entries holding given number of bytes. * @bytes: Count the number of SG entries holding given number of bytes.
* @offset: Start the counting of SG entries from the given offset.
* Return: Number of TX SG entries found given the constraints * Return: Number of TX SG entries found given the constraints
*/ */
unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset) unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes)
{ {
const struct alg_sock *ask = alg_sk(sk); const struct alg_sock *ask = alg_sk(sk);
const struct af_alg_ctx *ctx = ask->private; const struct af_alg_ctx *ctx = ask->private;
@@ -658,25 +658,11 @@ unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset)
const struct scatterlist *sg = sgl->sg; const struct scatterlist *sg = sgl->sg;
for (i = 0; i < sgl->cur; i++) { for (i = 0; i < sgl->cur; i++) {
size_t bytes_count;
/* Skip offset */
if (offset >= sg[i].length) {
offset -= sg[i].length;
bytes -= sg[i].length;
continue;
}
bytes_count = sg[i].length - offset;
offset = 0;
sgl_count++; sgl_count++;
if (sg[i].length >= bytes)
/* If we have seen requested number of bytes, stop */
if (bytes_count >= bytes)
return sgl_count; return sgl_count;
bytes -= bytes_count; bytes -= sg[i].length;
} }
} }
@@ -688,19 +674,14 @@ EXPORT_SYMBOL_GPL(af_alg_count_tsgl);
* af_alg_pull_tsgl - Release the specified buffers from TX SGL * af_alg_pull_tsgl - Release the specified buffers from TX SGL
* *
* If @dst is non-null, reassign the pages to @dst. The caller must release * If @dst is non-null, reassign the pages to @dst. The caller must release
* the pages. If @dst_offset is given only reassign the pages to @dst starting * the pages.
* at the @dst_offset (byte). The caller must ensure that @dst is large
* enough (e.g. by using af_alg_count_tsgl with the same offset).
* *
* @sk: socket of connection to user space * @sk: socket of connection to user space
* @used: Number of bytes to pull from TX SGL * @used: Number of bytes to pull from TX SGL
* @dst: If non-NULL, buffer is reassigned to dst SGL instead of releasing. The * @dst: If non-NULL, buffer is reassigned to dst SGL instead of releasing. The
* caller must release the buffers in dst. * caller must release the buffers in dst.
* @dst_offset: Reassign the TX SGL from given offset. All buffers before
* reaching the offset is released.
*/ */
void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst, void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst)
size_t dst_offset)
{ {
struct alg_sock *ask = alg_sk(sk); struct alg_sock *ask = alg_sk(sk);
struct af_alg_ctx *ctx = ask->private; struct af_alg_ctx *ctx = ask->private;
@@ -725,18 +706,10 @@ void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst,
* SG entries in dst. * SG entries in dst.
*/ */
if (dst) { if (dst) {
if (dst_offset >= plen) { /* reassign page to dst after offset */
/* discard page before offset */ get_page(page);
dst_offset -= plen; sg_set_page(dst + j, page, plen, sg[i].offset);
} else { j++;
/* reassign page to dst after offset */
get_page(page);
sg_set_page(dst + j, page,
plen - dst_offset,
sg[i].offset + dst_offset);
dst_offset = 0;
j++;
}
} }
sg[i].length -= plen; sg[i].length -= plen;

View File

@@ -26,7 +26,6 @@
#include <crypto/internal/aead.h> #include <crypto/internal/aead.h>
#include <crypto/scatterwalk.h> #include <crypto/scatterwalk.h>
#include <crypto/if_alg.h> #include <crypto/if_alg.h>
#include <crypto/skcipher.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/kernel.h> #include <linux/kernel.h>
@@ -72,9 +71,8 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
struct alg_sock *pask = alg_sk(psk); struct alg_sock *pask = alg_sk(psk);
struct af_alg_ctx *ctx = ask->private; struct af_alg_ctx *ctx = ask->private;
struct crypto_aead *tfm = pask->private; struct crypto_aead *tfm = pask->private;
unsigned int i, as = crypto_aead_authsize(tfm); unsigned int as = crypto_aead_authsize(tfm);
struct af_alg_async_req *areq; struct af_alg_async_req *areq;
struct af_alg_tsgl *tsgl, *tmp;
struct scatterlist *rsgl_src, *tsgl_src = NULL; struct scatterlist *rsgl_src, *tsgl_src = NULL;
int err = 0; int err = 0;
size_t used = 0; /* [in] TX bufs to be en/decrypted */ size_t used = 0; /* [in] TX bufs to be en/decrypted */
@@ -154,23 +152,24 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
outlen -= less; outlen -= less;
} }
/*
* Create a per request TX SGL for this request which tracks the
* SG entries from the global TX SGL.
*/
processed = used + ctx->aead_assoclen; processed = used + ctx->aead_assoclen;
list_for_each_entry_safe(tsgl, tmp, &ctx->tsgl_list, list) { areq->tsgl_entries = af_alg_count_tsgl(sk, processed);
for (i = 0; i < tsgl->cur; i++) { if (!areq->tsgl_entries)
struct scatterlist *process_sg = tsgl->sg + i; areq->tsgl_entries = 1;
areq->tsgl = sock_kmalloc(sk, array_size(sizeof(*areq->tsgl),
if (!(process_sg->length) || !sg_page(process_sg)) areq->tsgl_entries),
continue; GFP_KERNEL);
tsgl_src = process_sg; if (!areq->tsgl) {
break; err = -ENOMEM;
}
if (tsgl_src)
break;
}
if (processed && !tsgl_src) {
err = -EFAULT;
goto free; goto free;
} }
sg_init_table(areq->tsgl, areq->tsgl_entries);
af_alg_pull_tsgl(sk, processed, areq->tsgl);
tsgl_src = areq->tsgl;
/* /*
* Copy of AAD from source to destination * Copy of AAD from source to destination
@@ -179,76 +178,15 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
* when user space uses an in-place cipher operation, the kernel * when user space uses an in-place cipher operation, the kernel
* will copy the data as it does not see whether such in-place operation * will copy the data as it does not see whether such in-place operation
* is initiated. * is initiated.
*
* To ensure efficiency, the following implementation ensure that the
* ciphers are invoked to perform a crypto operation in-place. This
* is achieved by memory management specified as follows.
*/ */
/* Use the RX SGL as source (and destination) for crypto op. */ /* Use the RX SGL as source (and destination) for crypto op. */
rsgl_src = areq->first_rsgl.sgl.sgt.sgl; rsgl_src = areq->first_rsgl.sgl.sgt.sgl;
if (ctx->enc) { memcpy_sglist(rsgl_src, tsgl_src, ctx->aead_assoclen);
/*
* Encryption operation - The in-place cipher operation is
* achieved by the following operation:
*
* TX SGL: AAD || PT
* | |
* | copy |
* v v
* RX SGL: AAD || PT || Tag
*/
memcpy_sglist(areq->first_rsgl.sgl.sgt.sgl, tsgl_src,
processed);
af_alg_pull_tsgl(sk, processed, NULL, 0);
} else {
/*
* Decryption operation - To achieve an in-place cipher
* operation, the following SGL structure is used:
*
* TX SGL: AAD || CT || Tag
* | | ^
* | copy | | Create SGL link.
* v v |
* RX SGL: AAD || CT ----+
*/
/* Copy AAD || CT to RX SGL buffer for in-place operation. */
memcpy_sglist(areq->first_rsgl.sgl.sgt.sgl, tsgl_src, outlen);
/* Create TX SGL for tag and chain it to RX SGL. */
areq->tsgl_entries = af_alg_count_tsgl(sk, processed,
processed - as);
if (!areq->tsgl_entries)
areq->tsgl_entries = 1;
areq->tsgl = sock_kmalloc(sk, array_size(sizeof(*areq->tsgl),
areq->tsgl_entries),
GFP_KERNEL);
if (!areq->tsgl) {
err = -ENOMEM;
goto free;
}
sg_init_table(areq->tsgl, areq->tsgl_entries);
/* Release TX SGL, except for tag data and reassign tag data. */
af_alg_pull_tsgl(sk, processed, areq->tsgl, processed - as);
/* chain the areq TX SGL holding the tag with RX SGL */
if (usedpages) {
/* RX SGL present */
struct af_alg_sgl *sgl_prev = &areq->last_rsgl->sgl;
struct scatterlist *sg = sgl_prev->sgt.sgl;
sg_unmark_end(sg + sgl_prev->sgt.nents - 1);
sg_chain(sg, sgl_prev->sgt.nents + 1, areq->tsgl);
} else
/* no RX SGL present (e.g. authentication only) */
rsgl_src = areq->tsgl;
}
/* Initialize the crypto operation */ /* Initialize the crypto operation */
aead_request_set_crypt(&areq->cra_u.aead_req, rsgl_src, aead_request_set_crypt(&areq->cra_u.aead_req, tsgl_src,
areq->first_rsgl.sgl.sgt.sgl, used, ctx->iv); areq->first_rsgl.sgl.sgt.sgl, used, ctx->iv);
aead_request_set_ad(&areq->cra_u.aead_req, ctx->aead_assoclen); aead_request_set_ad(&areq->cra_u.aead_req, ctx->aead_assoclen);
aead_request_set_tfm(&areq->cra_u.aead_req, tfm); aead_request_set_tfm(&areq->cra_u.aead_req, tfm);
@@ -450,7 +388,7 @@ static void aead_sock_destruct(struct sock *sk)
struct crypto_aead *tfm = pask->private; struct crypto_aead *tfm = pask->private;
unsigned int ivlen = crypto_aead_ivsize(tfm); unsigned int ivlen = crypto_aead_ivsize(tfm);
af_alg_pull_tsgl(sk, ctx->used, NULL, 0); af_alg_pull_tsgl(sk, ctx->used, NULL);
sock_kzfree_s(sk, ctx->iv, ivlen); sock_kzfree_s(sk, ctx->iv, ivlen);
sock_kfree_s(sk, ctx, ctx->len); sock_kfree_s(sk, ctx, ctx->len);
af_alg_release_parent(sk); af_alg_release_parent(sk);

View File

@@ -138,7 +138,7 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
* Create a per request TX SGL for this request which tracks the * Create a per request TX SGL for this request which tracks the
* SG entries from the global TX SGL. * SG entries from the global TX SGL.
*/ */
areq->tsgl_entries = af_alg_count_tsgl(sk, len, 0); areq->tsgl_entries = af_alg_count_tsgl(sk, len);
if (!areq->tsgl_entries) if (!areq->tsgl_entries)
areq->tsgl_entries = 1; areq->tsgl_entries = 1;
areq->tsgl = sock_kmalloc(sk, array_size(sizeof(*areq->tsgl), areq->tsgl = sock_kmalloc(sk, array_size(sizeof(*areq->tsgl),
@@ -149,7 +149,7 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
goto free; goto free;
} }
sg_init_table(areq->tsgl, areq->tsgl_entries); sg_init_table(areq->tsgl, areq->tsgl_entries);
af_alg_pull_tsgl(sk, len, areq->tsgl, 0); af_alg_pull_tsgl(sk, len, areq->tsgl);
/* Initialize the crypto operation */ /* Initialize the crypto operation */
skcipher_request_set_tfm(&areq->cra_u.skcipher_req, tfm); skcipher_request_set_tfm(&areq->cra_u.skcipher_req, tfm);
@@ -363,7 +363,7 @@ static void skcipher_sock_destruct(struct sock *sk)
struct alg_sock *pask = alg_sk(psk); struct alg_sock *pask = alg_sk(psk);
struct crypto_skcipher *tfm = pask->private; struct crypto_skcipher *tfm = pask->private;
af_alg_pull_tsgl(sk, ctx->used, NULL, 0); af_alg_pull_tsgl(sk, ctx->used, NULL);
sock_kzfree_s(sk, ctx->iv, crypto_skcipher_ivsize(tfm)); sock_kzfree_s(sk, ctx->iv, crypto_skcipher_ivsize(tfm));
if (ctx->state) if (ctx->state)
sock_kzfree_s(sk, ctx->state, crypto_skcipher_statesize(tfm)); sock_kzfree_s(sk, ctx->state, crypto_skcipher_statesize(tfm));

View File

@@ -207,6 +207,7 @@ static int crypto_authenc_esn_decrypt_tail(struct aead_request *req,
u8 *ohash = areq_ctx->tail; u8 *ohash = areq_ctx->tail;
unsigned int cryptlen = req->cryptlen - authsize; unsigned int cryptlen = req->cryptlen - authsize;
unsigned int assoclen = req->assoclen; unsigned int assoclen = req->assoclen;
struct scatterlist *src = req->src;
struct scatterlist *dst = req->dst; struct scatterlist *dst = req->dst;
u8 *ihash = ohash + crypto_ahash_digestsize(auth); u8 *ihash = ohash + crypto_ahash_digestsize(auth);
u32 tmp[2]; u32 tmp[2];
@@ -214,23 +215,27 @@ static int crypto_authenc_esn_decrypt_tail(struct aead_request *req,
if (!authsize) if (!authsize)
goto decrypt; goto decrypt;
/* Move high-order bits of sequence number back. */ if (src == dst) {
scatterwalk_map_and_copy(tmp, dst, 4, 4, 0); /* Move high-order bits of sequence number back. */
scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 0); scatterwalk_map_and_copy(tmp, dst, 4, 4, 0);
scatterwalk_map_and_copy(tmp, dst, 0, 8, 1); scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 0);
scatterwalk_map_and_copy(tmp, dst, 0, 8, 1);
} else
memcpy_sglist(dst, src, assoclen);
if (crypto_memneq(ihash, ohash, authsize)) if (crypto_memneq(ihash, ohash, authsize))
return -EBADMSG; return -EBADMSG;
decrypt: decrypt:
sg_init_table(areq_ctx->dst, 2); if (src != dst)
src = scatterwalk_ffwd(areq_ctx->src, src, assoclen);
dst = scatterwalk_ffwd(areq_ctx->dst, dst, assoclen); dst = scatterwalk_ffwd(areq_ctx->dst, dst, assoclen);
skcipher_request_set_tfm(skreq, ctx->enc); skcipher_request_set_tfm(skreq, ctx->enc);
skcipher_request_set_callback(skreq, flags, skcipher_request_set_callback(skreq, flags,
req->base.complete, req->base.data); req->base.complete, req->base.data);
skcipher_request_set_crypt(skreq, dst, dst, cryptlen, req->iv); skcipher_request_set_crypt(skreq, src, dst, cryptlen, req->iv);
return crypto_skcipher_decrypt(skreq); return crypto_skcipher_decrypt(skreq);
} }
@@ -255,6 +260,7 @@ static int crypto_authenc_esn_decrypt(struct aead_request *req)
unsigned int assoclen = req->assoclen; unsigned int assoclen = req->assoclen;
unsigned int cryptlen = req->cryptlen; unsigned int cryptlen = req->cryptlen;
u8 *ihash = ohash + crypto_ahash_digestsize(auth); u8 *ihash = ohash + crypto_ahash_digestsize(auth);
struct scatterlist *src = req->src;
struct scatterlist *dst = req->dst; struct scatterlist *dst = req->dst;
u32 tmp[2]; u32 tmp[2];
int err; int err;
@@ -262,24 +268,28 @@ static int crypto_authenc_esn_decrypt(struct aead_request *req)
if (assoclen < 8) if (assoclen < 8)
return -EINVAL; return -EINVAL;
cryptlen -= authsize;
if (req->src != dst)
memcpy_sglist(dst, req->src, assoclen + cryptlen);
scatterwalk_map_and_copy(ihash, req->src, assoclen + cryptlen,
authsize, 0);
if (!authsize) if (!authsize)
goto tail; goto tail;
/* Move high-order bits of sequence number to the end. */ cryptlen -= authsize;
scatterwalk_map_and_copy(tmp, dst, 0, 8, 0); scatterwalk_map_and_copy(ihash, req->src, assoclen + cryptlen,
scatterwalk_map_and_copy(tmp, dst, 4, 4, 1); authsize, 0);
scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);
sg_init_table(areq_ctx->dst, 2); /* Move high-order bits of sequence number to the end. */
dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4); scatterwalk_map_and_copy(tmp, src, 0, 8, 0);
if (src == dst) {
scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);
scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);
dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4);
} else {
scatterwalk_map_and_copy(tmp, dst, 0, 4, 1);
scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen - 4, 4, 1);
src = scatterwalk_ffwd(areq_ctx->src, src, 8);
dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4);
memcpy_sglist(dst, src, assoclen + cryptlen - 8);
dst = req->dst;
}
ahash_request_set_tfm(ahreq, auth); ahash_request_set_tfm(ahreq, auth);
ahash_request_set_crypt(ahreq, dst, ohash, assoclen + cryptlen); ahash_request_set_crypt(ahreq, dst, ohash, assoclen + cryptlen);

View File

@@ -164,18 +164,21 @@ static int deflate_decompress_one(struct acomp_req *req,
do { do {
unsigned int dcur; unsigned int dcur;
unsigned long avail_in;
dcur = acomp_walk_next_dst(&walk); dcur = acomp_walk_next_dst(&walk);
if (!dcur) {
out_of_space = true;
break;
}
stream->avail_out = dcur; stream->avail_out = dcur;
stream->next_out = walk.dst.virt.addr; stream->next_out = walk.dst.virt.addr;
avail_in = stream->avail_in;
ret = zlib_inflate(stream, Z_NO_FLUSH); ret = zlib_inflate(stream, Z_NO_FLUSH);
if (!dcur && avail_in == stream->avail_in) {
out_of_space = true;
break;
}
dcur -= stream->avail_out; dcur -= stream->avail_out;
acomp_walk_done_dst(&walk, dcur); acomp_walk_done_dst(&walk, dcur);
} while (ret == Z_OK && stream->avail_in); } while (ret == Z_OK && stream->avail_in);

View File

@@ -914,7 +914,7 @@ static int decode_deactivate(struct qaic_device *qdev, void *trans, u32 *msg_len
*/ */
return -ENODEV; return -ENODEV;
if (status) { if (usr && status) {
/* /*
* Releasing resources failed on the device side, which puts * Releasing resources failed on the device side, which puts
* us in a bind since they may still be in use, so enable the * us in a bind since they may still be in use, so enable the
@@ -1109,6 +1109,9 @@ static void *msg_xfer(struct qaic_device *qdev, struct wrapper_list *wrappers, u
mutex_lock(&qdev->cntl_mutex); mutex_lock(&qdev->cntl_mutex);
if (!list_empty(&elem.list)) if (!list_empty(&elem.list))
list_del(&elem.list); list_del(&elem.list);
/* resp_worker() processed the response but the wait was interrupted */
else if (ret == -ERESTARTSYS)
ret = 0;
if (!ret && !elem.buf) if (!ret && !elem.buf)
ret = -ETIMEDOUT; ret = -ETIMEDOUT;
else if (ret > 0 && !elem.buf) else if (ret > 0 && !elem.buf)
@@ -1419,9 +1422,49 @@ static void resp_worker(struct work_struct *work)
} }
mutex_unlock(&qdev->cntl_mutex); mutex_unlock(&qdev->cntl_mutex);
if (!found) if (!found) {
/*
* The user might have gone away at this point without waiting
* for QAIC_TRANS_DEACTIVATE_FROM_DEV transaction coming from
* the device. If this is not handled correctly, the host will
* not know that the DBC[n] has been freed on the device.
* Due to this failure in synchronization between the device and
* the host, if another user requests to activate a network, and
* the device assigns DBC[n] again, save_dbc_buf() will hang,
* waiting for dbc[n]->in_use to be set to false, which will not
* happen unless the qaic_dev_reset_clean_local_state() gets
* called by resetting the device (or re-inserting the module).
*
* As a solution, we look for QAIC_TRANS_DEACTIVATE_FROM_DEV
* transactions in the message before disposing of it, then
* handle releasing the DBC resources.
*
* Since the user has gone away, if the device could not
* deactivate the network (status != 0), there is no way to
* enable and reassign the DBC to the user. We can put trust in
* the device that it will release all the active DBCs in
* response to the QAIC_TRANS_TERMINATE_TO_DEV transaction,
* otherwise, the user can issue an soc_reset to the device.
*/
u32 msg_count = le32_to_cpu(msg->hdr.count);
u32 msg_len = le32_to_cpu(msg->hdr.len);
u32 len = 0;
int j;
for (j = 0; j < msg_count && len < msg_len; ++j) {
struct wire_trans_hdr *trans_hdr;
trans_hdr = (struct wire_trans_hdr *)(msg->data + len);
if (le32_to_cpu(trans_hdr->type) == QAIC_TRANS_DEACTIVATE_FROM_DEV) {
if (decode_deactivate(qdev, trans_hdr, &len, NULL))
len += le32_to_cpu(trans_hdr->len);
} else {
len += le32_to_cpu(trans_hdr->len);
}
}
/* request must have timed out, drop packet */ /* request must have timed out, drop packet */
kfree(msg); kfree(msg);
}
kfree(resp); kfree(resp);
} }

View File

@@ -263,6 +263,13 @@ static int rimt_iommu_xlate(struct device *dev, struct acpi_rimt_node *node, u32
if (!rimt_fwnode) if (!rimt_fwnode)
return -EPROBE_DEFER; return -EPROBE_DEFER;
/*
* EPROBE_DEFER ensures IOMMU is probed before the devices that
* depend on them. During shutdown, however, the IOMMU may be removed
* first, leading to issues. To avoid this, a device link is added
* which enforces the correct removal order.
*/
device_link_add(dev, rimt_fwnode->dev, DL_FLAG_AUTOREMOVE_CONSUMER);
return acpi_iommu_fwspec_init(dev, deviceid, rimt_fwnode); return acpi_iommu_fwspec_init(dev, deviceid, rimt_fwnode);
} }

View File

@@ -13,6 +13,8 @@
// //
// The shrinker will use trylock methods because it locks them in a different order. // The shrinker will use trylock methods because it locks them in a different order.
use crate::AssertSync;
use core::{ use core::{
marker::PhantomPinned, marker::PhantomPinned,
mem::{size_of, size_of_val, MaybeUninit}, mem::{size_of, size_of_val, MaybeUninit},
@@ -143,14 +145,14 @@ pub(crate) struct ShrinkablePageRange {
} }
// We do not define any ops. For now, used only to check identity of vmas. // We do not define any ops. For now, used only to check identity of vmas.
static BINDER_VM_OPS: bindings::vm_operations_struct = pin_init::zeroed(); static BINDER_VM_OPS: AssertSync<bindings::vm_operations_struct> = AssertSync(pin_init::zeroed());
// To ensure that we do not accidentally install pages into or zap pages from the wrong vma, we // To ensure that we do not accidentally install pages into or zap pages from the wrong vma, we
// check its vm_ops and private data before using it. // check its vm_ops and private data before using it.
fn check_vma(vma: &virt::VmaRef, owner: *const ShrinkablePageRange) -> Option<&virt::VmaMixedMap> { fn check_vma(vma: &virt::VmaRef, owner: *const ShrinkablePageRange) -> Option<&virt::VmaMixedMap> {
// SAFETY: Just reading the vm_ops pointer of any active vma is safe. // SAFETY: Just reading the vm_ops pointer of any active vma is safe.
let vm_ops = unsafe { (*vma.as_ptr()).vm_ops }; let vm_ops = unsafe { (*vma.as_ptr()).vm_ops };
if !ptr::eq(vm_ops, &BINDER_VM_OPS) { if !ptr::eq(vm_ops, &BINDER_VM_OPS.0) {
return None; return None;
} }
@@ -342,7 +344,7 @@ impl ShrinkablePageRange {
// SAFETY: We own the vma, and we don't use any methods on VmaNew that rely on // SAFETY: We own the vma, and we don't use any methods on VmaNew that rely on
// `vm_ops`. // `vm_ops`.
unsafe { (*vma.as_ptr()).vm_ops = &BINDER_VM_OPS }; unsafe { (*vma.as_ptr()).vm_ops = &BINDER_VM_OPS.0 };
Ok(num_pages) Ok(num_pages)
} }

View File

@@ -306,7 +306,7 @@ impl kernel::Module for BinderModule {
/// Makes the inner type Sync. /// Makes the inner type Sync.
#[repr(transparent)] #[repr(transparent)]
pub struct AssertSync<T>(T); pub struct AssertSync<T>(T);
// SAFETY: Used only to insert `file_operations` into a global, which is safe. // SAFETY: Used only to insert C bindings types into globals, which is safe.
unsafe impl<T> Sync for AssertSync<T> {} unsafe impl<T> Sync for AssertSync<T> {}
/// File operations that rust_binderfs.c can use. /// File operations that rust_binderfs.c can use.

View File

@@ -68,6 +68,7 @@ enum board_ids {
/* board IDs for specific chipsets in alphabetical order */ /* board IDs for specific chipsets in alphabetical order */
board_ahci_al, board_ahci_al,
board_ahci_avn, board_ahci_avn,
board_ahci_jmb585,
board_ahci_mcp65, board_ahci_mcp65,
board_ahci_mcp77, board_ahci_mcp77,
board_ahci_mcp89, board_ahci_mcp89,
@@ -212,6 +213,15 @@ static const struct ata_port_info ahci_port_info[] = {
.udma_mask = ATA_UDMA6, .udma_mask = ATA_UDMA6,
.port_ops = &ahci_avn_ops, .port_ops = &ahci_avn_ops,
}, },
/* JMicron JMB582/585: 64-bit DMA is broken, force 32-bit */
[board_ahci_jmb585] = {
AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR |
AHCI_HFLAG_32BIT_ONLY),
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
[board_ahci_mcp65] = { [board_ahci_mcp65] = {
AHCI_HFLAGS (AHCI_HFLAG_NO_FPDMA_AA | AHCI_HFLAG_NO_PMP | AHCI_HFLAGS (AHCI_HFLAG_NO_FPDMA_AA | AHCI_HFLAG_NO_PMP |
AHCI_HFLAG_YES_NCQ), AHCI_HFLAG_YES_NCQ),
@@ -439,6 +449,10 @@ static const struct pci_device_id ahci_pci_tbl[] = {
/* Elkhart Lake IDs 0x4b60 & 0x4b62 https://sata-io.org/product/8803 not tested yet */ /* Elkhart Lake IDs 0x4b60 & 0x4b62 https://sata-io.org/product/8803 not tested yet */
{ PCI_VDEVICE(INTEL, 0x4b63), board_ahci_pcs_quirk }, /* Elkhart Lake AHCI */ { PCI_VDEVICE(INTEL, 0x4b63), board_ahci_pcs_quirk }, /* Elkhart Lake AHCI */
/* JMicron JMB582/585: force 32-bit DMA (broken 64-bit implementation) */
{ PCI_VDEVICE(JMICRON, 0x0582), board_ahci_jmb585 },
{ PCI_VDEVICE(JMICRON, 0x0585), board_ahci_jmb585 },
/* JMicron 360/1/3/5/6, match class to avoid IDE function */ /* JMicron 360/1/3/5/6, match class to avoid IDE function */
{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr }, PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr },

View File

@@ -793,13 +793,15 @@ static void do_become_nonbusy(struct comedi_device *dev,
__comedi_clear_subdevice_runflags(s, COMEDI_SRF_RUNNING | __comedi_clear_subdevice_runflags(s, COMEDI_SRF_RUNNING |
COMEDI_SRF_BUSY); COMEDI_SRF_BUSY);
spin_unlock_irqrestore(&s->spin_lock, flags); spin_unlock_irqrestore(&s->spin_lock, flags);
if (comedi_is_runflags_busy(runflags)) { if (async) {
/* /*
* "Run active" counter was set to 1 when setting up the * "Run active" counter was set to 1 when setting up the
* command. Decrement it and wait for it to become 0. * command. Decrement it and wait for it to become 0.
*/ */
comedi_put_is_subdevice_running(s); if (comedi_is_runflags_busy(runflags)) {
wait_for_completion(&async->run_complete); comedi_put_is_subdevice_running(s);
wait_for_completion(&async->run_complete);
}
comedi_buf_reset(s); comedi_buf_reset(s);
async->inttrig = NULL; async->inttrig = NULL;
kfree(async->cmd.chanlist); kfree(async->cmd.chanlist);

View File

@@ -1063,6 +1063,14 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it)
ret = -EIO; ret = -EIO;
goto out; goto out;
} }
if (IS_ENABLED(CONFIG_LOCKDEP)) {
/*
* dev->spinlock is for private use by the attached low-level
* driver. Reinitialize it to stop lock-dependency tracking
* between attachments to different low-level drivers.
*/
spin_lock_init(&dev->spinlock);
}
dev->driver = driv; dev->driver = driv;
dev->board_name = dev->board_ptr ? *(const char **)dev->board_ptr dev->board_name = dev->board_ptr ? *(const char **)dev->board_ptr
: dev->driver->driver_name; : dev->driver->driver_name;

View File

@@ -175,6 +175,18 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
? current_range_type : voltage_range_type; ? current_range_type : voltage_range_type;
} }
/*
* Check if hardware is present before attempting any I/O operations.
* Reading 0xff from status register typically indicates no hardware
* on the bus (floating bus reads as all 1s).
*/
if (inb(dev->iobase + DT2815_STATUS) == 0xff) {
dev_err(dev->class_dev,
"No hardware detected at I/O base 0x%lx\n",
dev->iobase);
return -ENODEV;
}
/* Init the 2815 */ /* Init the 2815 */
outb(0x00, dev->iobase + DT2815_STATUS); outb(0x00, dev->iobase + DT2815_STATUS);
for (i = 0; i < 100; i++) { for (i = 0; i < 100; i++) {

View File

@@ -315,6 +315,18 @@ static int me4000_xilinx_download(struct comedi_device *dev,
unsigned int val; unsigned int val;
unsigned int i; unsigned int i;
/* Get data stream length from header. */
if (size >= 4) {
file_length = (((unsigned int)data[0] & 0xff) << 24) +
(((unsigned int)data[1] & 0xff) << 16) +
(((unsigned int)data[2] & 0xff) << 8) +
((unsigned int)data[3] & 0xff);
}
if (size < 16 || file_length > size - 16) {
dev_err(dev->class_dev, "Firmware length inconsistency\n");
return -EINVAL;
}
if (!xilinx_iobase) if (!xilinx_iobase)
return -ENODEV; return -ENODEV;
@@ -346,10 +358,6 @@ static int me4000_xilinx_download(struct comedi_device *dev,
outl(val, devpriv->plx_regbase + PLX9052_CNTRL); outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
/* Download Xilinx firmware */ /* Download Xilinx firmware */
file_length = (((unsigned int)data[0] & 0xff) << 24) +
(((unsigned int)data[1] & 0xff) << 16) +
(((unsigned int)data[2] & 0xff) << 8) +
((unsigned int)data[3] & 0xff);
usleep_range(10, 1000); usleep_range(10, 1000);
for (i = 0; i < file_length; i++) { for (i = 0; i < file_length; i++) {

View File

@@ -344,6 +344,25 @@ static int me2600_xilinx_download(struct comedi_device *dev,
unsigned int file_length; unsigned int file_length;
unsigned int i; unsigned int i;
/*
* Format of the firmware
* Build longs from the byte-wise coded header
* Byte 1-3: length of the array
* Byte 4-7: version
* Byte 8-11: date
* Byte 12-15: reserved
*/
if (size >= 4) {
file_length = (((unsigned int)data[0] & 0xff) << 24) +
(((unsigned int)data[1] & 0xff) << 16) +
(((unsigned int)data[2] & 0xff) << 8) +
((unsigned int)data[3] & 0xff);
}
if (size < 16 || file_length > size - 16) {
dev_err(dev->class_dev, "Firmware length inconsistency\n");
return -EINVAL;
}
/* disable irq's on PLX */ /* disable irq's on PLX */
writel(0x00, devpriv->plx_regbase + PLX9052_INTCSR); writel(0x00, devpriv->plx_regbase + PLX9052_INTCSR);
@@ -357,22 +376,6 @@ static int me2600_xilinx_download(struct comedi_device *dev,
writeb(0x00, dev->mmio + 0x0); writeb(0x00, dev->mmio + 0x0);
sleep(1); sleep(1);
/*
* Format of the firmware
* Build longs from the byte-wise coded header
* Byte 1-3: length of the array
* Byte 4-7: version
* Byte 8-11: date
* Byte 12-15: reserved
*/
if (size < 16)
return -EINVAL;
file_length = (((unsigned int)data[0] & 0xff) << 24) +
(((unsigned int)data[1] & 0xff) << 16) +
(((unsigned int)data[2] & 0xff) << 8) +
((unsigned int)data[3] & 0xff);
/* /*
* Loop for writing firmware byte by byte to xilinx * Loop for writing firmware byte by byte to xilinx
* Firmware data start at offset 16 * Firmware data start at offset 16

View File

@@ -698,7 +698,8 @@ static int atmio16d_attach(struct comedi_device *dev,
static void atmio16d_detach(struct comedi_device *dev) static void atmio16d_detach(struct comedi_device *dev)
{ {
reset_atmio16d(dev); if (dev->private)
reset_atmio16d(dev);
comedi_legacy_detach(dev); comedi_legacy_detach(dev);
} }

View File

@@ -107,9 +107,9 @@ static bool rz_mtu3_is_counter_invalid(struct counter_device *counter, int id)
struct rz_mtu3_cnt *const priv = counter_priv(counter); struct rz_mtu3_cnt *const priv = counter_priv(counter);
unsigned long tmdr; unsigned long tmdr;
pm_runtime_get_sync(priv->ch->dev); pm_runtime_get_sync(counter->parent);
tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3); tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3);
pm_runtime_put(priv->ch->dev); pm_runtime_put(counter->parent);
if (id == RZ_MTU3_32_BIT_CH && test_bit(RZ_MTU3_TMDR3_LWA, &tmdr)) if (id == RZ_MTU3_32_BIT_CH && test_bit(RZ_MTU3_TMDR3_LWA, &tmdr))
return false; return false;
@@ -165,12 +165,12 @@ static int rz_mtu3_count_read(struct counter_device *counter,
if (ret) if (ret)
return ret; return ret;
pm_runtime_get_sync(ch->dev); pm_runtime_get_sync(counter->parent);
if (count->id == RZ_MTU3_32_BIT_CH) if (count->id == RZ_MTU3_32_BIT_CH)
*val = rz_mtu3_32bit_ch_read(ch, RZ_MTU3_TCNTLW); *val = rz_mtu3_32bit_ch_read(ch, RZ_MTU3_TCNTLW);
else else
*val = rz_mtu3_16bit_ch_read(ch, RZ_MTU3_TCNT); *val = rz_mtu3_16bit_ch_read(ch, RZ_MTU3_TCNT);
pm_runtime_put(ch->dev); pm_runtime_put(counter->parent);
mutex_unlock(&priv->lock); mutex_unlock(&priv->lock);
return 0; return 0;
@@ -187,26 +187,26 @@ static int rz_mtu3_count_write(struct counter_device *counter,
if (ret) if (ret)
return ret; return ret;
pm_runtime_get_sync(ch->dev); pm_runtime_get_sync(counter->parent);
if (count->id == RZ_MTU3_32_BIT_CH) if (count->id == RZ_MTU3_32_BIT_CH)
rz_mtu3_32bit_ch_write(ch, RZ_MTU3_TCNTLW, val); rz_mtu3_32bit_ch_write(ch, RZ_MTU3_TCNTLW, val);
else else
rz_mtu3_16bit_ch_write(ch, RZ_MTU3_TCNT, val); rz_mtu3_16bit_ch_write(ch, RZ_MTU3_TCNT, val);
pm_runtime_put(ch->dev); pm_runtime_put(counter->parent);
mutex_unlock(&priv->lock); mutex_unlock(&priv->lock);
return 0; return 0;
} }
static int rz_mtu3_count_function_read_helper(struct rz_mtu3_channel *const ch, static int rz_mtu3_count_function_read_helper(struct rz_mtu3_channel *const ch,
struct rz_mtu3_cnt *const priv, struct counter_device *const counter,
enum counter_function *function) enum counter_function *function)
{ {
u8 timer_mode; u8 timer_mode;
pm_runtime_get_sync(ch->dev); pm_runtime_get_sync(counter->parent);
timer_mode = rz_mtu3_8bit_ch_read(ch, RZ_MTU3_TMDR1); timer_mode = rz_mtu3_8bit_ch_read(ch, RZ_MTU3_TMDR1);
pm_runtime_put(ch->dev); pm_runtime_put(counter->parent);
switch (timer_mode & RZ_MTU3_TMDR1_PH_CNT_MODE_MASK) { switch (timer_mode & RZ_MTU3_TMDR1_PH_CNT_MODE_MASK) {
case RZ_MTU3_TMDR1_PH_CNT_MODE_1: case RZ_MTU3_TMDR1_PH_CNT_MODE_1:
@@ -240,7 +240,7 @@ static int rz_mtu3_count_function_read(struct counter_device *counter,
if (ret) if (ret)
return ret; return ret;
ret = rz_mtu3_count_function_read_helper(ch, priv, function); ret = rz_mtu3_count_function_read_helper(ch, counter, function);
mutex_unlock(&priv->lock); mutex_unlock(&priv->lock);
return ret; return ret;
@@ -279,9 +279,9 @@ static int rz_mtu3_count_function_write(struct counter_device *counter,
return -EINVAL; return -EINVAL;
} }
pm_runtime_get_sync(ch->dev); pm_runtime_get_sync(counter->parent);
rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TMDR1, timer_mode); rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TMDR1, timer_mode);
pm_runtime_put(ch->dev); pm_runtime_put(counter->parent);
mutex_unlock(&priv->lock); mutex_unlock(&priv->lock);
return 0; return 0;
@@ -300,9 +300,9 @@ static int rz_mtu3_count_direction_read(struct counter_device *counter,
if (ret) if (ret)
return ret; return ret;
pm_runtime_get_sync(ch->dev); pm_runtime_get_sync(counter->parent);
tsr = rz_mtu3_8bit_ch_read(ch, RZ_MTU3_TSR); tsr = rz_mtu3_8bit_ch_read(ch, RZ_MTU3_TSR);
pm_runtime_put(ch->dev); pm_runtime_put(counter->parent);
*direction = (tsr & RZ_MTU3_TSR_TCFD) ? *direction = (tsr & RZ_MTU3_TSR_TCFD) ?
COUNTER_COUNT_DIRECTION_FORWARD : COUNTER_COUNT_DIRECTION_BACKWARD; COUNTER_COUNT_DIRECTION_FORWARD : COUNTER_COUNT_DIRECTION_BACKWARD;
@@ -377,14 +377,14 @@ static int rz_mtu3_count_ceiling_write(struct counter_device *counter,
return -EINVAL; return -EINVAL;
} }
pm_runtime_get_sync(ch->dev); pm_runtime_get_sync(counter->parent);
if (count->id == RZ_MTU3_32_BIT_CH) if (count->id == RZ_MTU3_32_BIT_CH)
rz_mtu3_32bit_ch_write(ch, RZ_MTU3_TGRALW, ceiling); rz_mtu3_32bit_ch_write(ch, RZ_MTU3_TGRALW, ceiling);
else else
rz_mtu3_16bit_ch_write(ch, RZ_MTU3_TGRA, ceiling); rz_mtu3_16bit_ch_write(ch, RZ_MTU3_TGRA, ceiling);
rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TCR, RZ_MTU3_TCR_CCLR_TGRA); rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TCR, RZ_MTU3_TCR_CCLR_TGRA);
pm_runtime_put(ch->dev); pm_runtime_put(counter->parent);
mutex_unlock(&priv->lock); mutex_unlock(&priv->lock);
return 0; return 0;
@@ -495,25 +495,28 @@ static int rz_mtu3_count_enable_read(struct counter_device *counter,
static int rz_mtu3_count_enable_write(struct counter_device *counter, static int rz_mtu3_count_enable_write(struct counter_device *counter,
struct counter_count *count, u8 enable) struct counter_count *count, u8 enable)
{ {
struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, count->id);
struct rz_mtu3_cnt *const priv = counter_priv(counter); struct rz_mtu3_cnt *const priv = counter_priv(counter);
int ret = 0; int ret = 0;
mutex_lock(&priv->lock);
if (priv->count_is_enabled[count->id] == enable)
goto exit;
if (enable) { if (enable) {
mutex_lock(&priv->lock); pm_runtime_get_sync(counter->parent);
pm_runtime_get_sync(ch->dev);
ret = rz_mtu3_initialize_counter(counter, count->id); ret = rz_mtu3_initialize_counter(counter, count->id);
if (ret == 0) if (ret == 0)
priv->count_is_enabled[count->id] = true; priv->count_is_enabled[count->id] = true;
mutex_unlock(&priv->lock);
} else { } else {
mutex_lock(&priv->lock);
rz_mtu3_terminate_counter(counter, count->id); rz_mtu3_terminate_counter(counter, count->id);
priv->count_is_enabled[count->id] = false; priv->count_is_enabled[count->id] = false;
pm_runtime_put(ch->dev); pm_runtime_put(counter->parent);
mutex_unlock(&priv->lock);
} }
exit:
mutex_unlock(&priv->lock);
return ret; return ret;
} }
@@ -540,9 +543,9 @@ static int rz_mtu3_cascade_counts_enable_get(struct counter_device *counter,
if (ret) if (ret)
return ret; return ret;
pm_runtime_get_sync(priv->ch->dev); pm_runtime_get_sync(counter->parent);
tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3); tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3);
pm_runtime_put(priv->ch->dev); pm_runtime_put(counter->parent);
*cascade_enable = test_bit(RZ_MTU3_TMDR3_LWA, &tmdr); *cascade_enable = test_bit(RZ_MTU3_TMDR3_LWA, &tmdr);
mutex_unlock(&priv->lock); mutex_unlock(&priv->lock);
@@ -559,10 +562,10 @@ static int rz_mtu3_cascade_counts_enable_set(struct counter_device *counter,
if (ret) if (ret)
return ret; return ret;
pm_runtime_get_sync(priv->ch->dev); pm_runtime_get_sync(counter->parent);
rz_mtu3_shared_reg_update_bit(priv->ch, RZ_MTU3_TMDR3, rz_mtu3_shared_reg_update_bit(priv->ch, RZ_MTU3_TMDR3,
RZ_MTU3_TMDR3_LWA, cascade_enable); RZ_MTU3_TMDR3_LWA, cascade_enable);
pm_runtime_put(priv->ch->dev); pm_runtime_put(counter->parent);
mutex_unlock(&priv->lock); mutex_unlock(&priv->lock);
return 0; return 0;
@@ -579,9 +582,9 @@ static int rz_mtu3_ext_input_phase_clock_select_get(struct counter_device *count
if (ret) if (ret)
return ret; return ret;
pm_runtime_get_sync(priv->ch->dev); pm_runtime_get_sync(counter->parent);
tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3); tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3);
pm_runtime_put(priv->ch->dev); pm_runtime_put(counter->parent);
*ext_input_phase_clock_select = test_bit(RZ_MTU3_TMDR3_PHCKSEL, &tmdr); *ext_input_phase_clock_select = test_bit(RZ_MTU3_TMDR3_PHCKSEL, &tmdr);
mutex_unlock(&priv->lock); mutex_unlock(&priv->lock);
@@ -598,11 +601,11 @@ static int rz_mtu3_ext_input_phase_clock_select_set(struct counter_device *count
if (ret) if (ret)
return ret; return ret;
pm_runtime_get_sync(priv->ch->dev); pm_runtime_get_sync(counter->parent);
rz_mtu3_shared_reg_update_bit(priv->ch, RZ_MTU3_TMDR3, rz_mtu3_shared_reg_update_bit(priv->ch, RZ_MTU3_TMDR3,
RZ_MTU3_TMDR3_PHCKSEL, RZ_MTU3_TMDR3_PHCKSEL,
ext_input_phase_clock_select); ext_input_phase_clock_select);
pm_runtime_put(priv->ch->dev); pm_runtime_put(counter->parent);
mutex_unlock(&priv->lock); mutex_unlock(&priv->lock);
return 0; return 0;
@@ -640,7 +643,7 @@ static int rz_mtu3_action_read(struct counter_device *counter,
if (ret) if (ret)
return ret; return ret;
ret = rz_mtu3_count_function_read_helper(ch, priv, &function); ret = rz_mtu3_count_function_read_helper(ch, counter, &function);
if (ret) { if (ret) {
mutex_unlock(&priv->lock); mutex_unlock(&priv->lock);
return ret; return ret;

View File

@@ -468,13 +468,13 @@ int cpufreq_dbs_governor_init(struct cpufreq_policy *policy)
/* Failure, so roll back. */ /* Failure, so roll back. */
pr_err("initialization failed (dbs_data kobject init error %d)\n", ret); pr_err("initialization failed (dbs_data kobject init error %d)\n", ret);
kobject_put(&dbs_data->attr_set.kobj);
policy->governor_data = NULL; policy->governor_data = NULL;
if (!have_governor_per_policy()) if (!have_governor_per_policy())
gov->gdbs_data = NULL; gov->gdbs_data = NULL;
gov->exit(dbs_data);
kobject_put(&dbs_data->attr_set.kobj);
goto free_policy_dbs_info;
free_dbs_data: free_dbs_data:
kfree(dbs_data); kfree(dbs_data);

View File

@@ -3326,9 +3326,10 @@ static int ahash_setkey(struct crypto_ahash *ahash, const u8 *key,
if (aligned_len < keylen) if (aligned_len < keylen)
return -EOVERFLOW; return -EOVERFLOW;
hashed_key = kmemdup(key, aligned_len, GFP_KERNEL); hashed_key = kmalloc(aligned_len, GFP_KERNEL);
if (!hashed_key) if (!hashed_key)
return -ENOMEM; return -ENOMEM;
memcpy(hashed_key, key, keylen);
ret = hash_digest_key(ctx, &keylen, hashed_key, digestsize); ret = hash_digest_key(ctx, &keylen, hashed_key, digestsize);
if (ret) if (ret)
goto bad_free_key; goto bad_free_key;

View File

@@ -441,9 +441,10 @@ static int ahash_setkey(struct crypto_ahash *ahash,
if (aligned_len < keylen) if (aligned_len < keylen)
return -EOVERFLOW; return -EOVERFLOW;
hashed_key = kmemdup(key, keylen, GFP_KERNEL); hashed_key = kmalloc(aligned_len, GFP_KERNEL);
if (!hashed_key) if (!hashed_key)
return -ENOMEM; return -ENOMEM;
memcpy(hashed_key, key, keylen);
ret = hash_digest_key(ctx, &keylen, hashed_key, digestsize); ret = hash_digest_key(ctx, &keylen, hashed_key, digestsize);
if (ret) if (ret)
goto bad_free_key; goto bad_free_key;

View File

@@ -529,7 +529,7 @@ static struct tegra_se_alg tegra_aes_algs[] = {
.cra_name = "cbc(aes)", .cra_name = "cbc(aes)",
.cra_driver_name = "cbc-aes-tegra", .cra_driver_name = "cbc-aes-tegra",
.cra_priority = 500, .cra_priority = 500,
.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER | CRYPTO_ALG_ASYNC, .cra_flags = CRYPTO_ALG_ASYNC,
.cra_blocksize = AES_BLOCK_SIZE, .cra_blocksize = AES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct tegra_aes_ctx), .cra_ctxsize = sizeof(struct tegra_aes_ctx),
.cra_alignmask = 0xf, .cra_alignmask = 0xf,
@@ -550,7 +550,7 @@ static struct tegra_se_alg tegra_aes_algs[] = {
.cra_name = "ecb(aes)", .cra_name = "ecb(aes)",
.cra_driver_name = "ecb-aes-tegra", .cra_driver_name = "ecb-aes-tegra",
.cra_priority = 500, .cra_priority = 500,
.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER | CRYPTO_ALG_ASYNC, .cra_flags = CRYPTO_ALG_ASYNC,
.cra_blocksize = AES_BLOCK_SIZE, .cra_blocksize = AES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct tegra_aes_ctx), .cra_ctxsize = sizeof(struct tegra_aes_ctx),
.cra_alignmask = 0xf, .cra_alignmask = 0xf,
@@ -572,7 +572,7 @@ static struct tegra_se_alg tegra_aes_algs[] = {
.cra_name = "ctr(aes)", .cra_name = "ctr(aes)",
.cra_driver_name = "ctr-aes-tegra", .cra_driver_name = "ctr-aes-tegra",
.cra_priority = 500, .cra_priority = 500,
.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER | CRYPTO_ALG_ASYNC, .cra_flags = CRYPTO_ALG_ASYNC,
.cra_blocksize = 1, .cra_blocksize = 1,
.cra_ctxsize = sizeof(struct tegra_aes_ctx), .cra_ctxsize = sizeof(struct tegra_aes_ctx),
.cra_alignmask = 0xf, .cra_alignmask = 0xf,
@@ -594,6 +594,7 @@ static struct tegra_se_alg tegra_aes_algs[] = {
.cra_name = "xts(aes)", .cra_name = "xts(aes)",
.cra_driver_name = "xts-aes-tegra", .cra_driver_name = "xts-aes-tegra",
.cra_priority = 500, .cra_priority = 500,
.cra_flags = CRYPTO_ALG_ASYNC,
.cra_blocksize = AES_BLOCK_SIZE, .cra_blocksize = AES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct tegra_aes_ctx), .cra_ctxsize = sizeof(struct tegra_aes_ctx),
.cra_alignmask = (__alignof__(u64) - 1), .cra_alignmask = (__alignof__(u64) - 1),
@@ -1922,6 +1923,7 @@ static struct tegra_se_alg tegra_aead_algs[] = {
.cra_name = "gcm(aes)", .cra_name = "gcm(aes)",
.cra_driver_name = "gcm-aes-tegra", .cra_driver_name = "gcm-aes-tegra",
.cra_priority = 500, .cra_priority = 500,
.cra_flags = CRYPTO_ALG_ASYNC,
.cra_blocksize = 1, .cra_blocksize = 1,
.cra_ctxsize = sizeof(struct tegra_aead_ctx), .cra_ctxsize = sizeof(struct tegra_aead_ctx),
.cra_alignmask = 0xf, .cra_alignmask = 0xf,
@@ -1944,6 +1946,7 @@ static struct tegra_se_alg tegra_aead_algs[] = {
.cra_name = "ccm(aes)", .cra_name = "ccm(aes)",
.cra_driver_name = "ccm-aes-tegra", .cra_driver_name = "ccm-aes-tegra",
.cra_priority = 500, .cra_priority = 500,
.cra_flags = CRYPTO_ALG_ASYNC,
.cra_blocksize = 1, .cra_blocksize = 1,
.cra_ctxsize = sizeof(struct tegra_aead_ctx), .cra_ctxsize = sizeof(struct tegra_aead_ctx),
.cra_alignmask = 0xf, .cra_alignmask = 0xf,
@@ -1971,7 +1974,7 @@ static struct tegra_se_alg tegra_cmac_algs[] = {
.cra_name = "cmac(aes)", .cra_name = "cmac(aes)",
.cra_driver_name = "tegra-se-cmac", .cra_driver_name = "tegra-se-cmac",
.cra_priority = 300, .cra_priority = 300,
.cra_flags = CRYPTO_ALG_TYPE_AHASH, .cra_flags = CRYPTO_ALG_ASYNC,
.cra_blocksize = AES_BLOCK_SIZE, .cra_blocksize = AES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct tegra_cmac_ctx), .cra_ctxsize = sizeof(struct tegra_cmac_ctx),
.cra_alignmask = 0, .cra_alignmask = 0,

View File

@@ -761,7 +761,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_name = "sha1", .cra_name = "sha1",
.cra_driver_name = "tegra-se-sha1", .cra_driver_name = "tegra-se-sha1",
.cra_priority = 300, .cra_priority = 300,
.cra_flags = CRYPTO_ALG_TYPE_AHASH, .cra_flags = CRYPTO_ALG_ASYNC,
.cra_blocksize = SHA1_BLOCK_SIZE, .cra_blocksize = SHA1_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_ctxsize = sizeof(struct tegra_sha_ctx),
.cra_alignmask = 0, .cra_alignmask = 0,
@@ -786,7 +786,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_name = "sha224", .cra_name = "sha224",
.cra_driver_name = "tegra-se-sha224", .cra_driver_name = "tegra-se-sha224",
.cra_priority = 300, .cra_priority = 300,
.cra_flags = CRYPTO_ALG_TYPE_AHASH, .cra_flags = CRYPTO_ALG_ASYNC,
.cra_blocksize = SHA224_BLOCK_SIZE, .cra_blocksize = SHA224_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_ctxsize = sizeof(struct tegra_sha_ctx),
.cra_alignmask = 0, .cra_alignmask = 0,
@@ -811,7 +811,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_name = "sha256", .cra_name = "sha256",
.cra_driver_name = "tegra-se-sha256", .cra_driver_name = "tegra-se-sha256",
.cra_priority = 300, .cra_priority = 300,
.cra_flags = CRYPTO_ALG_TYPE_AHASH, .cra_flags = CRYPTO_ALG_ASYNC,
.cra_blocksize = SHA256_BLOCK_SIZE, .cra_blocksize = SHA256_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_ctxsize = sizeof(struct tegra_sha_ctx),
.cra_alignmask = 0, .cra_alignmask = 0,
@@ -836,7 +836,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_name = "sha384", .cra_name = "sha384",
.cra_driver_name = "tegra-se-sha384", .cra_driver_name = "tegra-se-sha384",
.cra_priority = 300, .cra_priority = 300,
.cra_flags = CRYPTO_ALG_TYPE_AHASH, .cra_flags = CRYPTO_ALG_ASYNC,
.cra_blocksize = SHA384_BLOCK_SIZE, .cra_blocksize = SHA384_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_ctxsize = sizeof(struct tegra_sha_ctx),
.cra_alignmask = 0, .cra_alignmask = 0,
@@ -861,7 +861,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_name = "sha512", .cra_name = "sha512",
.cra_driver_name = "tegra-se-sha512", .cra_driver_name = "tegra-se-sha512",
.cra_priority = 300, .cra_priority = 300,
.cra_flags = CRYPTO_ALG_TYPE_AHASH, .cra_flags = CRYPTO_ALG_ASYNC,
.cra_blocksize = SHA512_BLOCK_SIZE, .cra_blocksize = SHA512_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_ctxsize = sizeof(struct tegra_sha_ctx),
.cra_alignmask = 0, .cra_alignmask = 0,
@@ -886,7 +886,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_name = "sha3-224", .cra_name = "sha3-224",
.cra_driver_name = "tegra-se-sha3-224", .cra_driver_name = "tegra-se-sha3-224",
.cra_priority = 300, .cra_priority = 300,
.cra_flags = CRYPTO_ALG_TYPE_AHASH, .cra_flags = CRYPTO_ALG_ASYNC,
.cra_blocksize = SHA3_224_BLOCK_SIZE, .cra_blocksize = SHA3_224_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_ctxsize = sizeof(struct tegra_sha_ctx),
.cra_alignmask = 0, .cra_alignmask = 0,
@@ -911,7 +911,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_name = "sha3-256", .cra_name = "sha3-256",
.cra_driver_name = "tegra-se-sha3-256", .cra_driver_name = "tegra-se-sha3-256",
.cra_priority = 300, .cra_priority = 300,
.cra_flags = CRYPTO_ALG_TYPE_AHASH, .cra_flags = CRYPTO_ALG_ASYNC,
.cra_blocksize = SHA3_256_BLOCK_SIZE, .cra_blocksize = SHA3_256_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_ctxsize = sizeof(struct tegra_sha_ctx),
.cra_alignmask = 0, .cra_alignmask = 0,
@@ -936,7 +936,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_name = "sha3-384", .cra_name = "sha3-384",
.cra_driver_name = "tegra-se-sha3-384", .cra_driver_name = "tegra-se-sha3-384",
.cra_priority = 300, .cra_priority = 300,
.cra_flags = CRYPTO_ALG_TYPE_AHASH, .cra_flags = CRYPTO_ALG_ASYNC,
.cra_blocksize = SHA3_384_BLOCK_SIZE, .cra_blocksize = SHA3_384_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_ctxsize = sizeof(struct tegra_sha_ctx),
.cra_alignmask = 0, .cra_alignmask = 0,
@@ -961,7 +961,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_name = "sha3-512", .cra_name = "sha3-512",
.cra_driver_name = "tegra-se-sha3-512", .cra_driver_name = "tegra-se-sha3-512",
.cra_priority = 300, .cra_priority = 300,
.cra_flags = CRYPTO_ALG_TYPE_AHASH, .cra_flags = CRYPTO_ALG_ASYNC,
.cra_blocksize = SHA3_512_BLOCK_SIZE, .cra_blocksize = SHA3_512_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_ctxsize = sizeof(struct tegra_sha_ctx),
.cra_alignmask = 0, .cra_alignmask = 0,
@@ -988,7 +988,8 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_name = "hmac(sha224)", .cra_name = "hmac(sha224)",
.cra_driver_name = "tegra-se-hmac-sha224", .cra_driver_name = "tegra-se-hmac-sha224",
.cra_priority = 300, .cra_priority = 300,
.cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_NEED_FALLBACK, .cra_flags = CRYPTO_ALG_ASYNC |
CRYPTO_ALG_NEED_FALLBACK,
.cra_blocksize = SHA224_BLOCK_SIZE, .cra_blocksize = SHA224_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_ctxsize = sizeof(struct tegra_sha_ctx),
.cra_alignmask = 0, .cra_alignmask = 0,
@@ -1015,7 +1016,8 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_name = "hmac(sha256)", .cra_name = "hmac(sha256)",
.cra_driver_name = "tegra-se-hmac-sha256", .cra_driver_name = "tegra-se-hmac-sha256",
.cra_priority = 300, .cra_priority = 300,
.cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_NEED_FALLBACK, .cra_flags = CRYPTO_ALG_ASYNC |
CRYPTO_ALG_NEED_FALLBACK,
.cra_blocksize = SHA256_BLOCK_SIZE, .cra_blocksize = SHA256_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_ctxsize = sizeof(struct tegra_sha_ctx),
.cra_alignmask = 0, .cra_alignmask = 0,
@@ -1042,7 +1044,8 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_name = "hmac(sha384)", .cra_name = "hmac(sha384)",
.cra_driver_name = "tegra-se-hmac-sha384", .cra_driver_name = "tegra-se-hmac-sha384",
.cra_priority = 300, .cra_priority = 300,
.cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_NEED_FALLBACK, .cra_flags = CRYPTO_ALG_ASYNC |
CRYPTO_ALG_NEED_FALLBACK,
.cra_blocksize = SHA384_BLOCK_SIZE, .cra_blocksize = SHA384_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_ctxsize = sizeof(struct tegra_sha_ctx),
.cra_alignmask = 0, .cra_alignmask = 0,
@@ -1069,7 +1072,8 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_name = "hmac(sha512)", .cra_name = "hmac(sha512)",
.cra_driver_name = "tegra-se-hmac-sha512", .cra_driver_name = "tegra-se-hmac-sha512",
.cra_priority = 300, .cra_priority = 300,
.cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_NEED_FALLBACK, .cra_flags = CRYPTO_ALG_ASYNC |
CRYPTO_ALG_NEED_FALLBACK,
.cra_blocksize = SHA512_BLOCK_SIZE, .cra_blocksize = SHA512_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_ctxsize = sizeof(struct tegra_sha_ctx),
.cra_alignmask = 0, .cra_alignmask = 0,

View File

@@ -113,10 +113,6 @@ static enum fw_upload_err mpfs_auto_update_prepare(struct fw_upload *fw_uploader
* be added here. * be added here.
*/ */
priv->flash = mpfs_sys_controller_get_flash(priv->sys_controller);
if (!priv->flash)
return FW_UPLOAD_ERR_HW_ERROR;
erase_size = round_up(erase_size, (u64)priv->flash->erasesize); erase_size = round_up(erase_size, (u64)priv->flash->erasesize);
/* /*
@@ -427,6 +423,12 @@ static int mpfs_auto_update_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(priv->sys_controller), return dev_err_probe(dev, PTR_ERR(priv->sys_controller),
"Could not register as a sub device of the system controller\n"); "Could not register as a sub device of the system controller\n");
priv->flash = mpfs_sys_controller_get_flash(priv->sys_controller);
if (IS_ERR_OR_NULL(priv->flash)) {
dev_dbg(dev, "No flash connected to the system controller, auto-update not supported\n");
return -ENODEV;
}
priv->dev = dev; priv->dev = dev;
platform_set_drvdata(pdev, priv); platform_set_drvdata(pdev, priv);

View File

@@ -122,6 +122,7 @@ config GPIB_FLUKE
depends on OF depends on OF
select GPIB_COMMON select GPIB_COMMON
select GPIB_NEC7210 select GPIB_NEC7210
depends on HAS_IOMEM
help help
GPIB driver for Fluke based cda devices. GPIB driver for Fluke based cda devices.

View File

@@ -888,10 +888,6 @@ static int read_ioctl(struct gpib_file_private *file_priv, struct gpib_board *bo
if (read_cmd.completed_transfer_count > read_cmd.requested_transfer_count) if (read_cmd.completed_transfer_count > read_cmd.requested_transfer_count)
return -EINVAL; return -EINVAL;
desc = handle_to_descriptor(file_priv, read_cmd.handle);
if (!desc)
return -EINVAL;
if (WARN_ON_ONCE(sizeof(userbuf) > sizeof(read_cmd.buffer_ptr))) if (WARN_ON_ONCE(sizeof(userbuf) > sizeof(read_cmd.buffer_ptr)))
return -EFAULT; return -EFAULT;
@@ -904,6 +900,17 @@ static int read_ioctl(struct gpib_file_private *file_priv, struct gpib_board *bo
if (!access_ok(userbuf, remain)) if (!access_ok(userbuf, remain))
return -EFAULT; return -EFAULT;
/* Lock descriptors to prevent concurrent close from freeing descriptor */
if (mutex_lock_interruptible(&file_priv->descriptors_mutex))
return -ERESTARTSYS;
desc = handle_to_descriptor(file_priv, read_cmd.handle);
if (!desc) {
mutex_unlock(&file_priv->descriptors_mutex);
return -EINVAL;
}
atomic_inc(&desc->descriptor_busy);
mutex_unlock(&file_priv->descriptors_mutex);
atomic_set(&desc->io_in_progress, 1); atomic_set(&desc->io_in_progress, 1);
/* Read buffer loads till we fill the user supplied buffer */ /* Read buffer loads till we fill the user supplied buffer */
@@ -937,6 +944,7 @@ static int read_ioctl(struct gpib_file_private *file_priv, struct gpib_board *bo
retval = copy_to_user((void __user *)arg, &read_cmd, sizeof(read_cmd)); retval = copy_to_user((void __user *)arg, &read_cmd, sizeof(read_cmd));
atomic_set(&desc->io_in_progress, 0); atomic_set(&desc->io_in_progress, 0);
atomic_dec(&desc->descriptor_busy);
wake_up_interruptible(&board->wait); wake_up_interruptible(&board->wait);
if (retval) if (retval)
@@ -964,10 +972,6 @@ static int command_ioctl(struct gpib_file_private *file_priv,
if (cmd.completed_transfer_count > cmd.requested_transfer_count) if (cmd.completed_transfer_count > cmd.requested_transfer_count)
return -EINVAL; return -EINVAL;
desc = handle_to_descriptor(file_priv, cmd.handle);
if (!desc)
return -EINVAL;
userbuf = (u8 __user *)(unsigned long)cmd.buffer_ptr; userbuf = (u8 __user *)(unsigned long)cmd.buffer_ptr;
userbuf += cmd.completed_transfer_count; userbuf += cmd.completed_transfer_count;
@@ -980,6 +984,17 @@ static int command_ioctl(struct gpib_file_private *file_priv,
if (!access_ok(userbuf, remain)) if (!access_ok(userbuf, remain))
return -EFAULT; return -EFAULT;
/* Lock descriptors to prevent concurrent close from freeing descriptor */
if (mutex_lock_interruptible(&file_priv->descriptors_mutex))
return -ERESTARTSYS;
desc = handle_to_descriptor(file_priv, cmd.handle);
if (!desc) {
mutex_unlock(&file_priv->descriptors_mutex);
return -EINVAL;
}
atomic_inc(&desc->descriptor_busy);
mutex_unlock(&file_priv->descriptors_mutex);
/* /*
* Write buffer loads till we empty the user supplied buffer. * Write buffer loads till we empty the user supplied buffer.
* Call drivers at least once, even if remain is zero, in * Call drivers at least once, even if remain is zero, in
@@ -1003,6 +1018,7 @@ static int command_ioctl(struct gpib_file_private *file_priv,
userbuf += bytes_written; userbuf += bytes_written;
if (retval < 0) { if (retval < 0) {
atomic_set(&desc->io_in_progress, 0); atomic_set(&desc->io_in_progress, 0);
atomic_dec(&desc->descriptor_busy);
wake_up_interruptible(&board->wait); wake_up_interruptible(&board->wait);
break; break;
@@ -1022,6 +1038,7 @@ static int command_ioctl(struct gpib_file_private *file_priv,
*/ */
if (!no_clear_io_in_prog || fault) if (!no_clear_io_in_prog || fault)
atomic_set(&desc->io_in_progress, 0); atomic_set(&desc->io_in_progress, 0);
atomic_dec(&desc->descriptor_busy);
wake_up_interruptible(&board->wait); wake_up_interruptible(&board->wait);
if (fault) if (fault)
@@ -1047,10 +1064,6 @@ static int write_ioctl(struct gpib_file_private *file_priv, struct gpib_board *b
if (write_cmd.completed_transfer_count > write_cmd.requested_transfer_count) if (write_cmd.completed_transfer_count > write_cmd.requested_transfer_count)
return -EINVAL; return -EINVAL;
desc = handle_to_descriptor(file_priv, write_cmd.handle);
if (!desc)
return -EINVAL;
userbuf = (u8 __user *)(unsigned long)write_cmd.buffer_ptr; userbuf = (u8 __user *)(unsigned long)write_cmd.buffer_ptr;
userbuf += write_cmd.completed_transfer_count; userbuf += write_cmd.completed_transfer_count;
@@ -1060,6 +1073,17 @@ static int write_ioctl(struct gpib_file_private *file_priv, struct gpib_board *b
if (!access_ok(userbuf, remain)) if (!access_ok(userbuf, remain))
return -EFAULT; return -EFAULT;
/* Lock descriptors to prevent concurrent close from freeing descriptor */
if (mutex_lock_interruptible(&file_priv->descriptors_mutex))
return -ERESTARTSYS;
desc = handle_to_descriptor(file_priv, write_cmd.handle);
if (!desc) {
mutex_unlock(&file_priv->descriptors_mutex);
return -EINVAL;
}
atomic_inc(&desc->descriptor_busy);
mutex_unlock(&file_priv->descriptors_mutex);
atomic_set(&desc->io_in_progress, 1); atomic_set(&desc->io_in_progress, 1);
/* Write buffer loads till we empty the user supplied buffer */ /* Write buffer loads till we empty the user supplied buffer */
@@ -1094,6 +1118,7 @@ static int write_ioctl(struct gpib_file_private *file_priv, struct gpib_board *b
fault = copy_to_user((void __user *)arg, &write_cmd, sizeof(write_cmd)); fault = copy_to_user((void __user *)arg, &write_cmd, sizeof(write_cmd));
atomic_set(&desc->io_in_progress, 0); atomic_set(&desc->io_in_progress, 0);
atomic_dec(&desc->descriptor_busy);
wake_up_interruptible(&board->wait); wake_up_interruptible(&board->wait);
if (fault) if (fault)
@@ -1276,6 +1301,9 @@ static int close_dev_ioctl(struct file *filep, struct gpib_board *board, unsigne
{ {
struct gpib_close_dev_ioctl cmd; struct gpib_close_dev_ioctl cmd;
struct gpib_file_private *file_priv = filep->private_data; struct gpib_file_private *file_priv = filep->private_data;
struct gpib_descriptor *desc;
unsigned int pad;
int sad;
int retval; int retval;
retval = copy_from_user(&cmd, (void __user *)arg, sizeof(cmd)); retval = copy_from_user(&cmd, (void __user *)arg, sizeof(cmd));
@@ -1284,19 +1312,27 @@ static int close_dev_ioctl(struct file *filep, struct gpib_board *board, unsigne
if (cmd.handle >= GPIB_MAX_NUM_DESCRIPTORS) if (cmd.handle >= GPIB_MAX_NUM_DESCRIPTORS)
return -EINVAL; return -EINVAL;
if (!file_priv->descriptors[cmd.handle])
mutex_lock(&file_priv->descriptors_mutex);
desc = file_priv->descriptors[cmd.handle];
if (!desc) {
mutex_unlock(&file_priv->descriptors_mutex);
return -EINVAL; return -EINVAL;
}
retval = decrement_open_device_count(board, &board->device_list, if (atomic_read(&desc->descriptor_busy)) {
file_priv->descriptors[cmd.handle]->pad, mutex_unlock(&file_priv->descriptors_mutex);
file_priv->descriptors[cmd.handle]->sad); return -EBUSY;
if (retval < 0) }
return retval; /* Remove from table while holding lock to prevent new IO from starting */
kfree(file_priv->descriptors[cmd.handle]);
file_priv->descriptors[cmd.handle] = NULL; file_priv->descriptors[cmd.handle] = NULL;
pad = desc->pad;
sad = desc->sad;
mutex_unlock(&file_priv->descriptors_mutex);
return 0; retval = decrement_open_device_count(board, &board->device_list, pad, sad);
kfree(desc);
return retval;
} }
static int serial_poll_ioctl(struct gpib_board *board, unsigned long arg) static int serial_poll_ioctl(struct gpib_board *board, unsigned long arg)
@@ -1331,12 +1367,25 @@ static int wait_ioctl(struct gpib_file_private *file_priv, struct gpib_board *bo
if (retval) if (retval)
return -EFAULT; return -EFAULT;
/*
* Lock descriptors to prevent concurrent close from freeing
* descriptor. ibwait() releases big_gpib_mutex when wait_mask
* is non-zero, so desc must be pinned with descriptor_busy.
*/
mutex_lock(&file_priv->descriptors_mutex);
desc = handle_to_descriptor(file_priv, wait_cmd.handle); desc = handle_to_descriptor(file_priv, wait_cmd.handle);
if (!desc) if (!desc) {
mutex_unlock(&file_priv->descriptors_mutex);
return -EINVAL; return -EINVAL;
}
atomic_inc(&desc->descriptor_busy);
mutex_unlock(&file_priv->descriptors_mutex);
retval = ibwait(board, wait_cmd.wait_mask, wait_cmd.clear_mask, retval = ibwait(board, wait_cmd.wait_mask, wait_cmd.clear_mask,
wait_cmd.set_mask, &wait_cmd.ibsta, wait_cmd.usec_timeout, desc); wait_cmd.set_mask, &wait_cmd.ibsta, wait_cmd.usec_timeout, desc);
atomic_dec(&desc->descriptor_busy);
if (retval < 0) if (retval < 0)
return retval; return retval;
@@ -2035,6 +2084,7 @@ void init_gpib_descriptor(struct gpib_descriptor *desc)
desc->is_board = 0; desc->is_board = 0;
desc->autopoll_enabled = 0; desc->autopoll_enabled = 0;
atomic_set(&desc->io_in_progress, 0); atomic_set(&desc->io_in_progress, 0);
atomic_set(&desc->descriptor_busy, 0);
} }
int gpib_register_driver(struct gpib_interface *interface, struct module *provider_module) int gpib_register_driver(struct gpib_interface *interface, struct module *provider_module)

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