Compare commits

..

No commits in common. "master" and "v7.3-rc1" have entirely different histories.

1336 changed files with 7996 additions and 18836 deletions

View File

@ -19,8 +19,7 @@ Abhinav Kumar <quic_abhinavk@quicinc.com> <abhinavk@codeaurora.org>
Ahmad Masri <quic_amasri@quicinc.com> <amasri@codeaurora.org> Ahmad Masri <quic_amasri@quicinc.com> <amasri@codeaurora.org>
Adam Oldham <oldhamca@gmail.com> Adam Oldham <oldhamca@gmail.com>
Adam Radford <aradford@gmail.com> Adam Radford <aradford@gmail.com>
Aditya Garg <aditya.garg@linux.dev> <gargaditya08@live.com> Aditya Garg <gargaditya08@proton.me> <gargaditya08@live.com>
Aditya Garg <aditya.garg@linux.dev> <gargaditya08@proton.me>
Adriana Reus <adi.reus@gmail.com> <adriana.reus@intel.com> Adriana Reus <adi.reus@gmail.com> <adriana.reus@intel.com>
Adrian Bunk <bunk@stusta.de> Adrian Bunk <bunk@stusta.de>
Ajay Kaher <ajay.kaher@broadcom.com> <akaher@vmware.com> Ajay Kaher <ajay.kaher@broadcom.com> <akaher@vmware.com>
@ -421,7 +420,6 @@ Jens Axboe <axboe@kernel.dk> <axboe@suse.de>
Jens Axboe <axboe@kernel.dk> <jens.axboe@oracle.com> Jens Axboe <axboe@kernel.dk> <jens.axboe@oracle.com>
Jens Axboe <axboe@kernel.dk> <axboe@fb.com> Jens Axboe <axboe@kernel.dk> <axboe@fb.com>
Jens Axboe <axboe@kernel.dk> <axboe@meta.com> Jens Axboe <axboe@kernel.dk> <axboe@meta.com>
Jens Axboe <axboe@kernel.dk> <axboe@anthropic.com>
Jens Osterkamp <Jens.Osterkamp@de.ibm.com> Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
Jens Wiklander <jenswi@kernel.org> <jens.wiklander@linaro.org> Jens Wiklander <jenswi@kernel.org> <jens.wiklander@linaro.org>
Jernej Skrabec <jernej.skrabec@gmail.com> <jernej.skrabec@siol.net> Jernej Skrabec <jernej.skrabec@gmail.com> <jernej.skrabec@siol.net>
@ -552,9 +550,6 @@ Li Yang <leoyang.li@nxp.com> <leo@zh-kernel.org>
Lior David <quic_liord@quicinc.com> <liord@codeaurora.org> Lior David <quic_liord@quicinc.com> <liord@codeaurora.org>
Loic Poulain <loic.poulain@oss.qualcomm.com> <loic.poulain@linaro.org> Loic Poulain <loic.poulain@oss.qualcomm.com> <loic.poulain@linaro.org>
Loic Poulain <loic.poulain@oss.qualcomm.com> <loic.poulain@intel.com> Loic Poulain <loic.poulain@oss.qualcomm.com> <loic.poulain@intel.com>
Lorenzo Bianconi <lorenzo@kernel.org> <lorenzo.bianconi@redhat.com>
Lorenzo Bianconi <lorenzo@kernel.org> <lorenzo.bianconi@st.com>
Lorenzo Bianconi <lorenzo@kernel.org> <lorenzo.bianconi83@gmail.com>
Lorenzo Pieralisi <lpieralisi@kernel.org> <lorenzo.pieralisi@arm.com> Lorenzo Pieralisi <lpieralisi@kernel.org> <lorenzo.pieralisi@arm.com>
Lorenzo Stoakes <ljs@kernel.org> <lstoakes@gmail.com> Lorenzo Stoakes <ljs@kernel.org> <lstoakes@gmail.com>
Lorenzo Stoakes <ljs@kernel.org> <lorenzo.stoakes@oracle.com> Lorenzo Stoakes <ljs@kernel.org> <lorenzo.stoakes@oracle.com>
@ -704,7 +699,6 @@ Oliver Hartkopp <socketcan@hartkopp.net> <oliver.hartkopp@volkswagen.de>
Oliver Hartkopp <socketcan@hartkopp.net> <oliver@hartkopp.net> Oliver Hartkopp <socketcan@hartkopp.net> <oliver@hartkopp.net>
Oliver Upton <oupton@kernel.org> <oupton@google.com> Oliver Upton <oupton@kernel.org> <oupton@google.com>
Oliver Upton <oupton@kernel.org> <oliver.upton@linux.dev> Oliver Upton <oupton@kernel.org> <oliver.upton@linux.dev>
Ondrej Mosnáček <omosnacek@gmail.com> <omosnace@redhat.com>
Ondřej Jirman <megi@xff.cz> <megous@megous.com> Ondřej Jirman <megi@xff.cz> <megous@megous.com>
Oza Pawandeep <quic_poza@quicinc.com> <poza@codeaurora.org> Oza Pawandeep <quic_poza@quicinc.com> <poza@codeaurora.org>
Pali Rohár <pali@kernel.org> <pali.rohar@gmail.com> Pali Rohár <pali@kernel.org> <pali.rohar@gmail.com>
@ -904,8 +898,7 @@ Thomas Graf <tgraf@suug.ch>
Thomas Gleixner <tglx@kernel.org> <tglx@linutronix.de> Thomas Gleixner <tglx@kernel.org> <tglx@linutronix.de>
Thomas Körper <socketcan@esd.eu> <thomas.koerper@esd.eu> Thomas Körper <socketcan@esd.eu> <thomas.koerper@esd.eu>
Thomas Pedersen <twp@codeaurora.org> Thomas Pedersen <twp@codeaurora.org>
Thorsten Blum <blum@kernel.org> <thorsten.blum@toblux.com> Thorsten Blum <thorsten.blum@linux.dev> <thorsten.blum@toblux.com>
Thorsten Blum <blum@kernel.org> <thorsten.blum@linux.dev>
Tiezhu Yang <yangtiezhu@loongson.cn> <kernelpatch@126.com> Tiezhu Yang <yangtiezhu@loongson.cn> <kernelpatch@126.com>
Tingwei Zhang <quic_tingwei@quicinc.com> <tingwei@codeaurora.org> Tingwei Zhang <quic_tingwei@quicinc.com> <tingwei@codeaurora.org>
Tirupathi Reddy <quic_tirupath@quicinc.com> <tirupath@codeaurora.org> Tirupathi Reddy <quic_tirupath@quicinc.com> <tirupath@codeaurora.org>

View File

@ -1512,10 +1512,6 @@ N: Andy Gross
E: agross@kernel.org E: agross@kernel.org
D: Qualcomm SoC subsystem and drivers D: Qualcomm SoC subsystem and drivers
N: Mark Gross
E: markgross@kernel.org
D: x86/mellanox platform maintenance and various x86 specific drivers
N: Grant Grundler N: Grant Grundler
E: grantgrundler@gmail.com E: grantgrundler@gmail.com
W: http://obmouse.sourceforge.net/ W: http://obmouse.sourceforge.net/
@ -4309,10 +4305,6 @@ N: Juergen Weigert
E: jnweiger@immd4.informatik.uni-erlangen.de E: jnweiger@immd4.informatik.uni-erlangen.de
D: The Linux Support Team Erlangen D: The Linux Support Team Erlangen
N: Russ Weight
E: russ.weight@gmail.com
D: Added support for Firmware Upload to the Firmware Loader
N: David Weinehall N: David Weinehall
E: tao@acc.umu.se E: tao@acc.umu.se
P: 1024D/DC47CA16 7ACE 0FB0 7A74 F994 9B36 E1D1 D14E 8526 DC47 CA16 P: 1024D/DC47CA16 7ACE 0FB0 7A74 F994 9B36 E1D1 D14E 8526 DC47 CA16

View File

@ -108,9 +108,6 @@ Description:
# NSFS_MAGIC # NSFS_MAGIC
dont_measure fsmagic=0x6e736673 dont_measure fsmagic=0x6e736673
dont_appraise fsmagic=0x6e736673 dont_appraise fsmagic=0x6e736673
# CONFIGFS_MAGIC
dont_measure fsmagic=0x62656570
dont_appraise fsmagic=0x62656570
measure func=BPRM_CHECK measure func=BPRM_CHECK
measure func=FILE_MMAP mask=MAY_EXEC measure func=FILE_MMAP mask=MAY_EXEC

View File

@ -1,7 +1,7 @@
What: /sys/class/firmware/.../data What: /sys/class/firmware/.../data
Date: July 2022 Date: July 2022
KernelVersion: 5.19 KernelVersion: 5.19
Contact: driver-core@lists.linux.dev Contact: Russ Weight <russ.weight@linux.dev>
Description: The data sysfs file is used for firmware-fallback and for Description: The data sysfs file is used for firmware-fallback and for
firmware uploads. Cat a firmware image to this sysfs file firmware uploads. Cat a firmware image to this sysfs file
after you echo 1 to the loading sysfs file. When the firmware after you echo 1 to the loading sysfs file. When the firmware
@ -13,7 +13,7 @@ Description: The data sysfs file is used for firmware-fallback and for
What: /sys/class/firmware/.../cancel What: /sys/class/firmware/.../cancel
Date: July 2022 Date: July 2022
KernelVersion: 5.19 KernelVersion: 5.19
Contact: driver-core@lists.linux.dev Contact: Russ Weight <russ.weight@linux.dev>
Description: Write-only. For firmware uploads, write a "1" to this file to Description: Write-only. For firmware uploads, write a "1" to this file to
request that the transfer of firmware data to the lower-level request that the transfer of firmware data to the lower-level
device be canceled. This request will be rejected (EBUSY) if device be canceled. This request will be rejected (EBUSY) if
@ -23,7 +23,7 @@ Description: Write-only. For firmware uploads, write a "1" to this file to
What: /sys/class/firmware/.../error What: /sys/class/firmware/.../error
Date: July 2022 Date: July 2022
KernelVersion: 5.19 KernelVersion: 5.19
Contact: driver-core@lists.linux.dev Contact: Russ Weight <russ.weight@linux.dev>
Description: Read-only. Returns a string describing a failed firmware Description: Read-only. Returns a string describing a failed firmware
upload. This string will be in the form of <STATUS>:<ERROR>, upload. This string will be in the form of <STATUS>:<ERROR>,
where <STATUS> will be one of the status strings described where <STATUS> will be one of the status strings described
@ -37,7 +37,7 @@ Description: Read-only. Returns a string describing a failed firmware
What: /sys/class/firmware/.../loading What: /sys/class/firmware/.../loading
Date: July 2022 Date: July 2022
KernelVersion: 5.19 KernelVersion: 5.19
Contact: driver-core@lists.linux.dev Contact: Russ Weight <russ.weight@linux.dev>
Description: The loading sysfs file is used for both firmware-fallback and Description: The loading sysfs file is used for both firmware-fallback and
for firmware uploads. Echo 1 onto the loading file to indicate for firmware uploads. Echo 1 onto the loading file to indicate
you are writing a firmware file to the data sysfs node. Echo you are writing a firmware file to the data sysfs node. Echo
@ -49,7 +49,7 @@ Description: The loading sysfs file is used for both firmware-fallback and
What: /sys/class/firmware/.../remaining_size What: /sys/class/firmware/.../remaining_size
Date: July 2022 Date: July 2022
KernelVersion: 5.19 KernelVersion: 5.19
Contact: driver-core@lists.linux.dev Contact: Russ Weight <russ.weight@linux.dev>
Description: Read-only. For firmware upload, this file contains the size Description: Read-only. For firmware upload, this file contains the size
of the firmware data that remains to be transferred to the of the firmware data that remains to be transferred to the
lower-level device driver. The size value is initialized to lower-level device driver. The size value is initialized to
@ -62,7 +62,7 @@ Description: Read-only. For firmware upload, this file contains the size
What: /sys/class/firmware/.../status What: /sys/class/firmware/.../status
Date: July 2022 Date: July 2022
KernelVersion: 5.19 KernelVersion: 5.19
Contact: driver-core@lists.linux.dev Contact: Russ Weight <russ.weight@linux.dev>
Description: Read-only. Returns a string describing the current status of Description: Read-only. Returns a string describing the current status of
a firmware upload. The string will be one of the following: a firmware upload. The string will be one of the following:
idle, "receiving", "preparing", "transferring", "programming". idle, "receiving", "preparing", "transferring", "programming".
@ -70,7 +70,7 @@ Description: Read-only. Returns a string describing the current status of
What: /sys/class/firmware/.../timeout What: /sys/class/firmware/.../timeout
Date: July 2022 Date: July 2022
KernelVersion: 5.19 KernelVersion: 5.19
Contact: driver-core@lists.linux.dev Contact: Russ Weight <russ.weight@linux.dev>
Description: This file supports the timeout mechanism for firmware Description: This file supports the timeout mechanism for firmware
fallback. This file has no affect on firmware uploads. For fallback. This file has no affect on firmware uploads. For
more information on timeouts please see the documentation more information on timeouts please see the documentation

View File

@ -5,7 +5,7 @@ Description: Shows all enabled kernel features.
Supported features: Supported features:
compr_cfgs, big_pcluster, chunked_file, device_table, compr_cfgs, big_pcluster, chunked_file, device_table,
compr_head2, sb_chksum, ztailpacking, dedupe, fragments, compr_head2, sb_chksum, ztailpacking, dedupe, fragments,
xattr_prefixes, 48bit, metabox. 48bit, metabox.
What: /sys/fs/erofs/<disk>/sync_decompress What: /sys/fs/erofs/<disk>/sync_decompress
Date: November 2021 Date: November 2021

View File

@ -47,6 +47,7 @@ Features:
- pages are linked to per-memcg LRU exclusively, and there is no global LRU. - pages are linked to per-memcg LRU exclusively, and there is no global LRU.
- optionally, memory+swap usage can be accounted and limited. - optionally, memory+swap usage can be accounted and limited.
- hierarchical accounting - hierarchical accounting
- soft limit
- moving (recharging) account at moving a task is selectable. - moving (recharging) account at moving a task is selectable.
- usage threshold notifier - usage threshold notifier
- memory pressure notifier - memory pressure notifier
@ -75,9 +76,10 @@ Brief summary of control files.
memory.memsw.failcnt show the number of memory+Swap hits limits memory.memsw.failcnt show the number of memory+Swap hits limits
memory.max_usage_in_bytes show max memory usage recorded memory.max_usage_in_bytes show max memory usage recorded
memory.memsw.max_usage_in_bytes show max memory+Swap usage recorded memory.memsw.max_usage_in_bytes show max memory+Swap usage recorded
memory.soft_limit_in_bytes This knob is deprecated and has no effect. memory.soft_limit_in_bytes set/show soft limit of memory usage
Writes are ignored and reads always This knob is not available on CONFIG_PREEMPT_RT systems.
return the maximum value. This knob is deprecated and shouldn't be
used.
memory.stat show various statistics memory.stat show various statistics
memory.use_hierarchy set/show hierarchical account enabled memory.use_hierarchy set/show hierarchical account enabled
This knob is deprecated and shouldn't be This knob is deprecated and shouldn't be
@ -338,6 +340,9 @@ memory.kmem.usage_in_bytes, or in a separate counter when it makes sense.
The main "kmem" counter is fed into the main counter, so kmem charges will The main "kmem" counter is fed into the main counter, so kmem charges will
also be visible from the user counter. also be visible from the user counter.
Currently no soft limit is implemented for kernel memory. It is future work
to trigger slab reclaim when those limits are reached.
2.7.1 Current Kernel Memory resources accounted 2.7.1 Current Kernel Memory resources accounted
----------------------------------------------- -----------------------------------------------
@ -705,10 +710,42 @@ For compatibility reasons writing 1 to memory.use_hierarchy will always pass::
THIS IS DEPRECATED! THIS IS DEPRECATED!
Writing to memory.soft_limit_in_bytes has no effect and reading it will Soft limits allow for greater sharing of memory. The idea behind soft limits
always return the maximum value. is to allow control groups to use as much of the memory as needed, provided
Use memory.low and memory.min in cgroup v2 instead. a. There is no memory contention
b. They do not exceed their hard limit
When the system detects memory contention or low memory, control groups
are pushed back to their soft limits. If the soft limit of each control
group is very high, they are pushed back as much as possible to make
sure that one control group does not starve the others of memory.
Please note that soft limits is a best-effort feature; it comes with
no guarantees, but it does its best to make sure that when memory is
heavily contended for, memory is allocated based on the soft limit
hints/setup. Currently soft limit based reclaim is set up such that
it gets invoked from balance_pgdat (kswapd).
7.1 Interface
-------------
Soft limits can be setup by using the following commands (in this example we
assume a soft limit of 256 MiB)::
# echo 256M > memory.soft_limit_in_bytes
If we want to change this to 1G, we can at any time use::
# echo 1G > memory.soft_limit_in_bytes
.. note::
Soft limits take effect over a long period of time, since they involve
reclaiming memory for balancing between memory cgroups
.. note::
It is recommended to set the soft limit always below the hard limit,
otherwise the hard limit will take precedence.
.. _cgroup-v1-memory-move-charges: .. _cgroup-v1-memory-move-charges:

View File

@ -1130,9 +1130,9 @@ policy and the underlying scheduler. From the point of view of the cpu controlle
processes can be categorized as follows: processes can be categorized as follows:
* Processes under the fair-class scheduler * Processes under the fair-class scheduler
* Processes under a BPF scheduler with the corresponding ``cgroup_set_*`` callback * Processes under a BPF scheduler with the ``cgroup_set_weight`` callback
* Everything else: ``SCHED_{FIFO,RR,DEADLINE}`` and processes under a BPF scheduler * Everything else: ``SCHED_{FIFO,RR,DEADLINE}`` and processes under a BPF scheduler
without the corresponding ``cgroup_set_*`` callback without the ``cgroup_set_weight`` callback
For details on when a process is under the fair-class scheduler or a BPF scheduler, For details on when a process is under the fair-class scheduler or a BPF scheduler,
check out :ref:`Documentation/scheduler/sched-ext.rst <sched-ext>`. check out :ref:`Documentation/scheduler/sched-ext.rst <sched-ext>`.
@ -1223,9 +1223,7 @@ will be referred to. All time durations are in microseconds.
$PERIOD duration. "max" for $MAX indicates no limit. If only $PERIOD duration. "max" for $MAX indicates no limit. If only
one number is written, $MAX is updated. one number is written, $MAX is updated.
This file affects only processes under the fair-class scheduler and a BPF This file affects only processes under the fair-class scheduler.
scheduler with the ``cgroup_set_bandwidth`` callback depending on what
the callback actually does.
cpu.max.burst cpu.max.burst
A read-write single value file which exists on non-root A read-write single value file which exists on non-root
@ -1233,9 +1231,7 @@ will be referred to. All time durations are in microseconds.
The burst in the range [0, $MAX]. The burst in the range [0, $MAX].
This file affects only processes under the fair-class scheduler and a BPF This file affects only processes under the fair-class scheduler.
scheduler with the ``cgroup_set_bandwidth`` callback depending on what
the callback actually does.
cpu.pressure cpu.pressure
A read-write nested-keyed file. A read-write nested-keyed file.
@ -1287,9 +1283,7 @@ will be referred to. All time durations are in microseconds.
own relative priorities, but the cgroup itself will be treated as own relative priorities, but the cgroup itself will be treated as
very low priority relative to its peers. very low priority relative to its peers.
This file affects only processes under the fair-class scheduler and a BPF This file affects only processes under the fair-class scheduler.
scheduler with the ``cgroup_set_idle`` callback depending on what the
callback actually does.
Memory Memory
------ ------
@ -3070,7 +3064,7 @@ resources (res_a and res_b) are registered then:
change in this file generates a file modified event. All fields in change in this file generates a file modified event. All fields in
this file are hierarchical. this file are hierarchical.
<res>.max max
The number of times the cgroup's resource usage was The number of times the cgroup's resource usage was
about to go over the max boundary. about to go over the max boundary.

View File

@ -4987,6 +4987,18 @@ Kernel parameters
Set to non-zero if a chip is present that snoops speed Set to non-zero if a chip is present that snoops speed
changes. Disabled by default. changes. Disabled by default.
pata_legacy.ht6560a= [HW,LIBATA]
Format: <int>
Set to 1, 2, or 3 for HT 6560A on the primary channel,
the secondary channel, or both channels respectively.
Disabled by default.
pata_legacy.ht6560b= [HW,LIBATA]
Format: <int>
Set to 1, 2, or 3 for HT 6560B on the primary channel,
the secondary channel, or both channels respectively.
Disabled by default.
pata_legacy.iordy_mask= [HW,LIBATA] pata_legacy.iordy_mask= [HW,LIBATA]
Format: <int> Format: <int>
IORDY enable mask. Set individual bits to allow IORDY IORDY enable mask. Set individual bits to allow IORDY
@ -4999,6 +5011,18 @@ Kernel parameters
with the sequence. By default IORDY is allowed across with the sequence. By default IORDY is allowed across
all channels. all channels.
pata_legacy.opti82c46x= [HW,LIBATA]
Format: <int>
Set to 1, 2, or 3 for Opti 82c611A on the primary
channel, the secondary channel, or both channels
respectively. Disabled by default.
pata_legacy.opti82c611a= [HW,LIBATA]
Format: <int>
Set to 1, 2, or 3 for Opti 82c465MV on the primary
channel, the secondary channel, or both channels
respectively. Disabled by default.
pata_legacy.pio_mask= [HW,LIBATA] pata_legacy.pio_mask= [HW,LIBATA]
Format: <int> Format: <int>
PIO mode mask for autospeed devices. Set individual PIO mode mask for autospeed devices. Set individual
@ -5022,6 +5046,19 @@ Kernel parameters
the first port in the list above (0x1f0), and so on. the first port in the list above (0x1f0), and so on.
By default all supported ports are probed. By default all supported ports are probed.
pata_legacy.qdi= [HW,LIBATA]
Format: <int>
Set to non-zero to probe QDI controllers. By default
set to 1 if CONFIG_PATA_QDI_MODULE, 0 otherwise.
pata_legacy.winbond= [HW,LIBATA]
Format: <int>
Set to non-zero to probe Winbond controllers. Use
the standard I/O port (0x130) if 1, otherwise the
value given is the I/O port to use (typically 0x1b0).
By default set to 1 if CONFIG_PATA_WINBOND_VLB_MODULE,
0 otherwise.
pata_platform.pio_mask= [HW,LIBATA] pata_platform.pio_mask= [HW,LIBATA]
Format: <int> Format: <int>
Supported PIO mode mask. Set individual bits to allow Supported PIO mode mask. Set individual bits to allow

View File

@ -1416,7 +1416,7 @@ Controls whether userspace may arm Syscall User Dispatch via
== =================================================================== == ===================================================================
Only present when the kernel is built with ``CONFIG_SYSCALL_USER_DISPATCH`` Only present when the kernel is built with ``CONFIG_SYSCALL_USER_DISPATCH``
and ``CONFIG_SYSCTL``. and ``CONFIG_PROC_SYSCTL``.
sysctl_writes_strict sysctl_writes_strict

View File

@ -155,8 +155,7 @@ The following keys are defined:
defined in version 1.0 of the RISC-V Cryptography Extensions Volume II. defined in version 1.0 of the RISC-V Cryptography Extensions Volume II.
* :c:macro:`RISCV_HWPROBE_EXT_ZFH`: The Zfh extension version 1.0 is supported * :c:macro:`RISCV_HWPROBE_EXT_ZFH`: The Zfh extension version 1.0 is supported
as defined in the RISC-V ISA manual. Zfh is a superset of Zfhmin, so as defined in the RISC-V ISA manual.
RISCV_HWPROBE_EXT_ZFHMIN is reported whenever RISCV_HWPROBE_EXT_ZFH is.
* :c:macro:`RISCV_HWPROBE_EXT_ZFHMIN`: The Zfhmin extension version 1.0 is * :c:macro:`RISCV_HWPROBE_EXT_ZFHMIN`: The Zfhmin extension version 1.0 is
supported as defined in the RISC-V ISA manual. supported as defined in the RISC-V ISA manual.
@ -165,9 +164,8 @@ The following keys are defined:
is supported as defined in the RISC-V ISA manual. is supported as defined in the RISC-V ISA manual.
* :c:macro:`RISCV_HWPROBE_EXT_ZVFH`: The Zvfh extension is supported as * :c:macro:`RISCV_HWPROBE_EXT_ZVFH`: The Zvfh extension is supported as
defined in the RISC-V Vector manual starting from commit e2ccd0548d6c defined in the RISC-V Vector manual starting from commit e2ccd0548d6c
("Remove draft warnings from Zvfh[min]"). Zvfh is a superset of Zvfhmin, ("Remove draft warnings from Zvfh[min]").
so RISCV_HWPROBE_EXT_ZVFHMIN is reported whenever RISCV_HWPROBE_EXT_ZVFH is.
* :c:macro:`RISCV_HWPROBE_EXT_ZVFHMIN`: The Zvfhmin extension is supported as * :c:macro:`RISCV_HWPROBE_EXT_ZVFHMIN`: The Zvfhmin extension is supported as
defined in the RISC-V Vector manual starting from commit e2ccd0548d6c defined in the RISC-V Vector manual starting from commit e2ccd0548d6c

View File

@ -23,7 +23,6 @@ properties:
- silergy,syr827 - silergy,syr827
- silergy,syr828 - silergy,syr828
- tcs,tcs4525 - tcs,tcs4525
- tcs,tcs4526
- items: - items:
- const: rockchip,rk8601 - const: rockchip,rk8601
- const: rockchip,rk8600 - const: rockchip,rk8600

View File

@ -117,8 +117,8 @@ properties:
$ref: /schemas/types.yaml#/definitions/uint32 $ref: /schemas/types.yaml#/definitions/uint32
description: description:
VLEN/8, the vector register length in bytes. This property is required on VLEN/8, the vector register length in bytes. This property is required on
thead systems where the vector register length is not identical on all thead systems where the vector register length is not identical on all harts, or
harts, or the vlenb CSR is not available. the vlenb CSR is not available.
# RISC-V has multiple properties for cache op block sizes as the sizes # RISC-V has multiple properties for cache op block sizes as the sizes
# differ between individual CBO extensions # differ between individual CBO extensions
@ -151,8 +151,8 @@ anyOf:
- riscv,isa-base - riscv,isa-base
dependencies: dependencies:
riscv,isa-base: ["riscv,isa-extensions"] riscv,isa-base: [ "riscv,isa-extensions" ]
riscv,isa-extensions: ["riscv,isa-base"] riscv,isa-extensions: [ "riscv,isa-base" ]
required: required:
- interrupt-controller - interrupt-controller

View File

@ -44,21 +44,6 @@ allOf:
else: else:
properties: properties:
starfive,sfc-filter-syscon: false starfive,sfc-filter-syscon: false
- if:
properties:
compatible:
contains:
const: ultrarisc,dp1000-spi
then:
properties:
reg:
maxItems: 1
clocks:
minItems: 2
clock-names:
minItems: 2
required:
- clock-names
properties: properties:
compatible: compatible:
@ -78,7 +63,6 @@ properties:
- mscc,jaguar2-spi - mscc,jaguar2-spi
- sophgo,sg2042-spi - sophgo,sg2042-spi
- thead,th1520-spi - thead,th1520-spi
- ultrarisc,dp1000-spi
- const: snps,dw-apb-ssi - const: snps,dw-apb-ssi
- description: Vendor controllers compatible with v1.01a - description: Vendor controllers compatible with v1.01a
items: items:

View File

@ -176,68 +176,3 @@ Message from dmesg::
secondary_startup_64+0xa4/0xb0 secondary_startup_64+0xa4/0xb0
nvme nvme0: Could not set queue count (16385) nvme nvme0: Could not set queue count (16385)
nvme nvme0: IO queues not created nvme nvme0: IO queues not created
Example 4: Inject an error into the first write command
-------------------------------------------------------
::
echo 0x01 > /sys/kernel/debug/nvme0n1/fault_inject/opcode
echo 1 > /sys/kernel/debug/nvme0n1/fault_inject/times
echo 100 > /sys/kernel/debug/nvme0n1/fault_inject/probability
dd if=/dev/zero of=/dev/nvme0n1 oflag=direct bs=512 count=1
Expected Result::
The first write command sent to nvme0n1 fails
Message from dmesg::
FAULT_INJECTION: forcing a failure.
name fault_inject, interval 1, probability 100, space 0, times 1
CPU: 4 UID: 0 PID: 0 Comm: swapper/4 Not tainted 7.1.0+ #5 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-20240910_120124-localhost 04/01/2014
Call Trace:
<IRQ>
dump_stack_lvl+0x6e/0xa0
dump_stack+0x10/0x16
should_fail_ex+0x461/0x510
should_fail+0xb/0x20
nvme_should_fail+0x11b/0x240 [nvme_core]
nvme_poll_cq+0x6ad/0xb30 [nvme]
nvme_irq+0x84/0xe0 [nvme]
? __pfx_nvme_irq+0x10/0x10 [nvme]
? rcu_core+0xa40/0xa90
? __pfx_sched_balance_softirq+0x10/0x10
? debug_smp_processor_id+0x17/0x20
? rcu_is_watching+0x13/0xa0
__handle_irq_event_percpu+0x396/0x610
handle_irq_event_percpu+0xf/0x90
handle_irq_event+0xab/0x110
handle_edge_irq+0x1a3/0x210
__common_interrupt+0xff/0x170
common_interrupt+0x90/0xc0
</IRQ>
<TASK>
asm_common_interrupt+0x27/0x40
RIP: 0010:pv_native_safe_halt+0x13/0x20
Code: 1f 84 00 00 00 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 8b 05 0a 2a 58 01 85 c0 7e 07 0f 00 2d ff cc 0d 00 fb f4 <c3> cc 0
RSP: 0018:ffff888100a67e40 EFLAGS: 00000242
RAX: 0000000000000001 RBX: ffff888100a49c40 RCX: ffffed102b6c645b
RDX: ffffed102b6c645b RSI: ffffffff82a0d3c0 RDI: ffffffff81428b9b
RBP: ffff888100a67e48 R08: ffffed102b6c645b R09: 0000000000000004
R10: ffffed102b6c645a R11: 0000000000000001 R12: 0000000000000000
R13: 0000000000000000 R14: ffffed1020149388 R15: dffffc0000000000
? do_idle+0x19b/0x2c0
? default_idle+0x9/0x20
arch_cpu_idle+0x9/0x10
default_idle_call+0x6b/0xa0
do_idle+0x19b/0x2c0
? __pfx_do_idle+0x10/0x10
? complete_with_flags+0x63/0x70
cpu_startup_entry+0x55/0x60
start_secondary+0x1df/0x1e0
common_startup_64+0x13e/0x158
</TASK>
nvme0n1: Write(0x1) @ LBA 0, 1 blocks, Invalid Command Opcode (sct 0x0 / sc 0x1) DNR
operation not supported error, dev nvme0n1, sector 0 op 0x1:(WRITE) flags 0x8800 phys_seg 1 prio class 2

View File

@ -67,7 +67,7 @@ pwm1_enable
at full speed. Write "1" to set to manual, write "2" to let the EC control at full speed. Write "1" to set to manual, write "2" to let the EC control
decide fan speed. Read this attribute to see current status. decide fan speed. Read this attribute to see current status.
NB: In consideration of the safety of the device, when setting to manual mode, NBIn consideration of the safety of the device, when setting to manual mode,
the pwm speed will be set to the maximum value (255) by default. You can set the pwm speed will be set to the maximum value (255) by default. You can set
a different value by writing pwm1 later. a different value by writing pwm1 later.

View File

@ -42,9 +42,6 @@ register/unregister functions::
char *devm_hwmon_sanitize_name(struct device *dev, const char *name); char *devm_hwmon_sanitize_name(struct device *dev, const char *name);
int hwmon_notify_event(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel);
void hwmon_lock(struct device *dev); void hwmon_lock(struct device *dev);
void hwmon_unlock(struct device *dev); void hwmon_unlock(struct device *dev);
@ -93,18 +90,6 @@ implemented in the driver, or debugfs functions, hwmon_lock() and hwmon_unlock()
can be used to ensure that calls to those functions are serialized. Those can be used to ensure that calls to those functions are serialized. Those
functions also support guard() and scoped_guard() variants. functions also support guard() and scoped_guard() variants.
Drivers can call hwmon_notify_event() to notify userspace and the thermal
subsystem when a hardware monitoring event (such as an alarm or a fault
condition) occurs or clears. The parameters are the hwmon device, the sensor
type, the attribute identifier associated with the event (such as
hwmon_temp_max_alarm or hwmon_fan_fault), and the sensor channel number.
hwmon_notify_event() generates a sysfs event (calling sysfs_notify()) and a
udev event with the attribute name passed in the NAME environment property
(e.g., "NAME=temp1_max_alarm"). If the event is for a temperature sensor and
the sensor is attached to a thermal zone, it also notifies the thermal
subsystem to update the thermal zone. hwmon_notify_event() returns 0 on
success or a negative error code on failure.
Using devm_hwmon_device_register_with_info() Using devm_hwmon_device_register_with_info()
-------------------------------------------- --------------------------------------------

View File

@ -360,17 +360,6 @@ attribute-sets:
name: tsoff name: tsoff
type: u32 type: u32
byte-order: big-endian byte-order: big-endian
-
name: filter-attrs
attributes:
-
name: orig-flags
type: u32
doc: bitmask of tuple fields to filter on, original direction
-
name: reply-flags
type: u32
doc: bitmask of tuple fields to filter on, reply direction
- -
name: conntrack-attrs name: conntrack-attrs
attributes: attributes:
@ -477,7 +466,7 @@ attribute-sets:
- -
name: filter name: filter
type: nest type: nest
nested-attributes: filter-attrs nested-attributes: tuple-attrs
- -
name: status-mask name: status-mask
type: u32 type: u32
@ -602,14 +591,10 @@ operations:
request: request:
value: 0x101 value: 0x101
attributes: attributes:
- tuple-orig
- tuple-reply
- status
- mark - mark
- zone
- mark-mask
- filter - filter
- status-mask - status
- zone
reply: reply:
value: 0x100 value: 0x100
attributes: attributes:

View File

@ -898,8 +898,6 @@ attribute-sets:
- -
name: txqlen name: txqlen
type: u32 type: u32
checks:
max: 32767
- -
name: map name: map
type: binary type: binary

View File

@ -230,7 +230,7 @@ optional. The following modified excerpt is from
void BPF_STRUCT_OPS(simple_exit, struct scx_exit_info *ei) void BPF_STRUCT_OPS(simple_exit, struct scx_exit_info *ei)
{ {
exit_type = ei->kind; exit_type = ei->type;
} }
SEC(".struct_ops") SEC(".struct_ops")
@ -242,21 +242,6 @@ optional. The following modified excerpt is from
.name = "simple", .name = "simple",
}; };
Scheduler-Dependent Knobs
-------------------------
The fair-class scheduler enforces CPU controller settings such as
``cpu.max``, ``cpu.weight`` and ``cpu.idle``. For sched_ext tasks, the
scheduler core communicates these settings to the BPF scheduler
through ``ops.cgroup_init()`` and reports subsequent changes through
the corresponding ``ops.cgroup_set_*()`` callbacks. Similarly, per-task
nice changes are converted to weights and reported through
``ops.set_weight()``.
Each BPF scheduler is responsible for implementing the scheduling
semantics of these settings and may choose to ignore them. Consult the
loaded scheduler's documentation before relying on these controls.
Dispatch Queues Dispatch Queues
--------------- ---------------

View File

@ -15,41 +15,19 @@ arch/riscv 开发者维护指南
概述 概述
---- ----
RISC-V 指令集体系结构是公开开发的: RISC-V指令集体系结构是公开开发的
正在进行的草案可供所有人查看和测试实现。新模块或者扩展草案可能会在开发过程中发 正在进行的草案可供所有人查看和测试实现。新模块或者扩展草案可能会在开发过程中发
生更改 --- 有时以不兼容的方式对以前的草案进行更改。这种灵活性可能会给 RISC-V 生更改---有时以不兼容的方式对以前的草案进行更改。这种灵活性可能会给RISC-V Linux
Linux 维护者带来挑战。Linux 维护者不赞成频繁的变更,且 Linux 开发过程更喜欢经过 维护者带来挑战。Linux开发过程更喜欢经过良好检查和测试的代码而不是试验代码。我
良好检查和测试的代码,而不是试验代码。我们希望推广同样的规则到即将被内核合并的 们希望推广同样的规则到即将被内核合并的RISC-V相关代码。
RISC-V 相关代码。
Patchwork
---------
RISC-V 有一个 patchwork 实例,可以在那里查看补丁的状态:
https://patchwork.kernel.org/project/linux-riscv/list/
如果你的补丁不在默认视图中出现,那么 RISC-V 维护者很有可能已要求修改,或者希望
将其应用到另一个代码树上。
自动化流程会在该 patchwork 实例上运行,在每个补丁到达时立刻对其进行构建/测试。
自动化流程会根据补丁是否被识别为修复,选用 RISC-V `for-next``fixes` 分支
当前的 HEAD若上述均应用失败则使用 RISC-V `master` 分支。补丁系列被应用到的具
体提交将标注在 patchwork 上。任何检查未通过的补丁通常不会被应用,并且在大多数情
况下将需要重新提交。
附加的提交检查单 附加的提交检查单
---------------- ----------------
我们仅接受针对新模块或扩展的补丁,前提是这些模块或扩展的规范被列为未来不太可能发 我们仅接受相关标准已经被RISC-V基金会标准为“已批准”或“已冻结”的扩展或模块的补丁。
生不兼容的变更。对于来自 RISC-V 基金会的规范,这意味着“已冻结”或“已批准”,对于 开发者当然可以维护自己的Linux内核树其中包含所需代码扩展草案的代码。
UEFI 论坛的规范,这意味着已发布的 ECR。开发者当然可以维护自己的 Linux 内核树,
其中包含他们所需的任何扩展草案的代码。)
此外RISC-V 规范允许实现者创建自己的自定义扩展。这些自定义扩展不需要通过 RISC-V 此外RISC-V规范允许爱好者创建自己的自定义扩展。这些自定义拓展不需要通过RISC-V
基金会的任何审核或批准流程。为了避免因添加实现者特定的 RISC-V 扩展带来的维护复杂 基金会的任何审核或批准。为了避免将爱好者一些特别的RISC-V拓展添加进内核代码带来
性和对性能的潜在影响,我们将只考虑符合以下任一条件的扩展补丁: 的维护复杂性和对性能的潜在影响我们将只接受RISC-V基金会正式冻结或批准的的扩展
补丁。开发者当然可以维护自己的Linux内核树其中包含他们想要的任何自定义扩展
- 已由 RISC-V 基金会正式冻结或批准 的代码。)
- 已按照标准 Linux 惯例,在广泛可用的硬件中实现
(实现者当然可以维护自己的 Linux 内核树,其中包含他们所需的任何自定义扩展的代码。)

View File

@ -90,6 +90,10 @@ irq_domain映射的类型
映射的优点是固定时间查找IRQ号而且irq_descs只分配给在用的IRQ。 缺点是该表 映射的优点是固定时间查找IRQ号而且irq_descs只分配给在用的IRQ。 缺点是该表
必须尽可能大的hwirq号。 必须尽可能大的hwirq号。
irq_domain_add_linear()和irq_domain_create_linear()在功能上是等价的,
除了第一个参数不同--前者接受一个Open Firmware特定的 'struct device_node' 而
后者接受一个更通用的抽象 'struct fwnode_handle' 。
大多数驱动应该使用线性映射 大多数驱动应该使用线性映射
树状映射 树状映射

View File

@ -4512,7 +4512,7 @@ AYANEO PLATFORM EC DRIVER
M: Antheas Kapenekakis <lkml@antheas.dev> M: Antheas Kapenekakis <lkml@antheas.dev>
L: platform-driver-x86@vger.kernel.org L: platform-driver-x86@vger.kernel.org
S: Maintained S: Maintained
F: Documentation/ABI/testing/sysfs-platform-ayaneo-ec F: Documentation/ABI/testing/sysfs-platform-ayaneo
F: drivers/platform/x86/ayaneo-ec.c F: drivers/platform/x86/ayaneo-ec.c
AZ6007 DVB DRIVER AZ6007 DVB DRIVER
@ -5671,8 +5671,8 @@ W: http://bu3sch.de/btgpio.php
F: drivers/gpio/gpio-bt8xx.c F: drivers/gpio/gpio-bt8xx.c
BTRFS FILE SYSTEM BTRFS FILE SYSTEM
M: Chris Mason <clm@fb.com>
M: David Sterba <dsterba@suse.com> M: David Sterba <dsterba@suse.com>
R: Chris Mason <mason@kernel.org>
L: linux-btrfs@vger.kernel.org L: linux-btrfs@vger.kernel.org
S: Maintained S: Maintained
W: https://btrfs.readthedocs.io W: https://btrfs.readthedocs.io
@ -8039,7 +8039,7 @@ F: drivers/gpu/drm/sun4i/sun8i*
DRM DRIVER FOR APPLE TOUCH BARS DRM DRIVER FOR APPLE TOUCH BARS
M: Aun-Ali Zaidi <admin@kodeit.net> M: Aun-Ali Zaidi <admin@kodeit.net>
M: Aditya Garg <aditya.garg@linux.dev> M: Aditya Garg <gargaditya08@proton.me>
L: dri-devel@lists.freedesktop.org L: dri-devel@lists.freedesktop.org
S: Maintained S: Maintained
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
@ -9387,8 +9387,9 @@ S: Maintained
F: drivers/edac/octeon_edac* F: drivers/edac/octeon_edac*
EDAC-CAVIUM THUNDERX EDAC-CAVIUM THUNDERX
M: Robert Richter <rric@kernel.org>
L: linux-edac@vger.kernel.org L: linux-edac@vger.kernel.org
S: Orphan S: Odd Fixes
F: drivers/edac/thunderx_edac* F: drivers/edac/thunderx_edac*
EDAC-CORE EDAC-CORE
@ -9415,8 +9416,9 @@ S: Supported
F: drivers/edac/dmc520_edac.c F: drivers/edac/dmc520_edac.c
EDAC-E752X EDAC-E752X
M: Mark Gross <markgross@kernel.org>
L: linux-edac@vger.kernel.org L: linux-edac@vger.kernel.org
S: Orphan S: Maintained
F: drivers/edac/e752x_edac.c F: drivers/edac/e752x_edac.c
EDAC-E7XXX EDAC-E7XXX
@ -9491,8 +9493,9 @@ S: Maintained
F: drivers/edac/igen6_edac.c F: drivers/edac/igen6_edac.c
EDAC-MPC85XX EDAC-MPC85XX
M: Johannes Thumshirn <morbidrsa@gmail.com>
L: linux-edac@vger.kernel.org L: linux-edac@vger.kernel.org
S: Orphan S: Maintained
F: drivers/edac/mpc85xx_edac.[ch] F: drivers/edac/mpc85xx_edac.[ch]
EDAC-NPCM EDAC-NPCM
@ -10190,6 +10193,7 @@ F: include/linux/arm_ffa.h
FIRMWARE LOADER (request_firmware) FIRMWARE LOADER (request_firmware)
M: Luis Chamberlain <mcgrof@kernel.org> M: Luis Chamberlain <mcgrof@kernel.org>
M: Russ Weight <russ.weight@linux.dev>
M: Danilo Krummrich <dakr@kernel.org> M: Danilo Krummrich <dakr@kernel.org>
L: driver-core@lists.linux.dev L: driver-core@lists.linux.dev
S: Maintained S: Maintained
@ -12220,7 +12224,7 @@ F: drivers/tty/hvc/
HUNG TASK DETECTOR HUNG TASK DETECTOR
M: Andrew Morton <akpm@linux-foundation.org> M: Andrew Morton <akpm@linux-foundation.org>
M: Lance Yang <lance.yang@linux.dev> R: Lance Yang <lance.yang@linux.dev>
R: Masami Hiramatsu <mhiramat@kernel.org> R: Masami Hiramatsu <mhiramat@kernel.org>
R: Petr Mladek <pmladek@suse.com> R: Petr Mladek <pmladek@suse.com>
L: linux-kernel@vger.kernel.org L: linux-kernel@vger.kernel.org
@ -13279,6 +13283,7 @@ F: drivers/crypto/intel/keembay/ocs-aes.h
INTEL KEEM BAY OCS ECC CRYPTO DRIVER INTEL KEEM BAY OCS ECC CRYPTO DRIVER
M: Prabhjot Khurana <prabhjot.khurana@intel.com> M: Prabhjot Khurana <prabhjot.khurana@intel.com>
M: Mark Gross <mgross@linux.intel.com>
S: Maintained S: Maintained
F: Documentation/devicetree/bindings/crypto/intel,keembay-ocs-ecc.yaml F: Documentation/devicetree/bindings/crypto/intel,keembay-ocs-ecc.yaml
F: drivers/crypto/intel/keembay/Kconfig F: drivers/crypto/intel/keembay/Kconfig
@ -14235,6 +14240,8 @@ F: tools/testing/selftests/
KERNEL SMB3 SERVER (KSMBD) KERNEL SMB3 SERVER (KSMBD)
M: Namjae Jeon <linkinjeon@kernel.org> M: Namjae Jeon <linkinjeon@kernel.org>
M: Namjae Jeon <linkinjeon@samba.org> M: Namjae Jeon <linkinjeon@samba.org>
M: Steve French <smfrench@gmail.com>
M: Steve French <sfrench@samba.org>
R: Sergey Senozhatsky <senozhatsky@chromium.org> R: Sergey Senozhatsky <senozhatsky@chromium.org>
R: Tom Talpey <tom@talpey.com> R: Tom Talpey <tom@talpey.com>
R: ChenXiaoSong <chenxiaosong@chenxiaosong.com> R: ChenXiaoSong <chenxiaosong@chenxiaosong.com>
@ -15020,8 +15027,6 @@ M: Madhavan Srinivasan <maddy@linux.ibm.com>
R: Michael Ellerman <mpe@ellerman.id.au> R: Michael Ellerman <mpe@ellerman.id.au>
R: Nicholas Piggin <npiggin@gmail.com> R: Nicholas Piggin <npiggin@gmail.com>
R: Christophe Leroy (CS GROUP) <chleroy@kernel.org> R: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
R: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
R: Shrikanth Hegde <sshegde@linux.ibm.com>
L: linuxppc-dev@lists.ozlabs.org L: linuxppc-dev@lists.ozlabs.org
S: Supported S: Supported
W: https://github.com/linuxppc/wiki/wiki W: https://github.com/linuxppc/wiki/wiki
@ -17411,6 +17416,7 @@ F: mm/swapfile.c
MEMORY MANAGEMENT - THP (TRANSPARENT HUGE PAGE) MEMORY MANAGEMENT - THP (TRANSPARENT HUGE PAGE)
M: Andrew Morton <akpm@linux-foundation.org> M: Andrew Morton <akpm@linux-foundation.org>
M: David Hildenbrand <david@kernel.org> M: David Hildenbrand <david@kernel.org>
M: Lorenzo Stoakes <ljs@kernel.org>
R: Zi Yan <ziy@nvidia.com> R: Zi Yan <ziy@nvidia.com>
R: Baolin Wang <baolin.wang@linux.alibaba.com> R: Baolin Wang <baolin.wang@linux.alibaba.com>
R: Liam R. Howlett <liam@infradead.org> R: Liam R. Howlett <liam@infradead.org>
@ -17420,7 +17426,6 @@ R: Dev Jain <dev.jain@arm.com>
R: Barry Song <baohua@kernel.org> R: Barry Song <baohua@kernel.org>
R: Lance Yang <lance.yang@linux.dev> R: Lance Yang <lance.yang@linux.dev>
R: Usama Arif <usama.arif@linux.dev> R: Usama Arif <usama.arif@linux.dev>
R: Kiryl Shutsemau <kas@kernel.org>
L: linux-mm@kvack.org L: linux-mm@kvack.org
S: Maintained S: Maintained
W: http://www.linux-mm.org W: http://www.linux-mm.org
@ -17693,7 +17698,7 @@ F: Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml
F: drivers/spi/spi-at91-usart.c F: drivers/spi/spi-at91-usart.c
MICROCHIP ATSHA204A DRIVER MICROCHIP ATSHA204A DRIVER
M: Thorsten Blum <blum@kernel.org> M: Thorsten Blum <thorsten.blum@linux.dev>
L: linux-crypto@vger.kernel.org L: linux-crypto@vger.kernel.org
S: Maintained S: Maintained
F: drivers/crypto/atmel-sha204a.c F: drivers/crypto/atmel-sha204a.c
@ -17717,7 +17722,7 @@ F: Documentation/devicetree/bindings/media/microchip,csi2dc.yaml
F: drivers/media/platform/microchip/microchip-csi2dc.c F: drivers/media/platform/microchip/microchip-csi2dc.c
MICROCHIP ECC DRIVER MICROCHIP ECC DRIVER
M: Thorsten Blum <blum@kernel.org> M: Thorsten Blum <thorsten.blum@linux.dev>
L: linux-crypto@vger.kernel.org L: linux-crypto@vger.kernel.org
S: Maintained S: Maintained
F: drivers/crypto/atmel-ecc.c F: drivers/crypto/atmel-ecc.c
@ -19564,7 +19569,7 @@ F: include/linux/platform_data/x86/nvidia-wmi-ec-backlight.h
NVM EXPRESS DRIVER NVM EXPRESS DRIVER
M: Keith Busch <kbusch@kernel.org> M: Keith Busch <kbusch@kernel.org>
M: Jens Axboe <axboe@kernel.dk> M: Jens Axboe <axboe@fb.com>
M: Christoph Hellwig <hch@lst.de> M: Christoph Hellwig <hch@lst.de>
M: Sagi Grimberg <sagi@grimberg.me> M: Sagi Grimberg <sagi@grimberg.me>
L: linux-nvme@lists.infradead.org L: linux-nvme@lists.infradead.org
@ -24773,7 +24778,7 @@ K: \bsecurity_[a-z_0-9]\+\b
SELINUX SECURITY MODULE SELINUX SECURITY MODULE
M: Paul Moore <paul@paul-moore.com> M: Paul Moore <paul@paul-moore.com>
M: Stephen Smalley <stephen.smalley.work@gmail.com> M: Stephen Smalley <stephen.smalley.work@gmail.com>
R: Ondrej Mosnáček <omosnacek@gmail.com> R: Ondrej Mosnacek <omosnace@redhat.com>
L: selinux@vger.kernel.org L: selinux@vger.kernel.org
S: Supported S: Supported
W: https://github.com/SELinuxProject W: https://github.com/SELinuxProject
@ -25231,9 +25236,10 @@ F: Documentation/admin-guide/LSM/Smack.rst
F: security/smack/ F: security/smack/
SMBDIRECT (RDMA Stream Transport with Read/Write-Offload, MS-SMBD) SMBDIRECT (RDMA Stream Transport with Read/Write-Offload, MS-SMBD)
M: Steve French <smfrench@gmail.com>
M: Steve French <sfrench@samba.org>
M: Namjae Jeon <linkinjeon@kernel.org> M: Namjae Jeon <linkinjeon@kernel.org>
M: Namjae Jeon <linkinjeon@samba.org> M: Namjae Jeon <linkinjeon@samba.org>
M: Paulo Alcantara <pc@manguebit.org>
R: Stefan Metzmacher <metze@samba.org> R: Stefan Metzmacher <metze@samba.org>
R: Tom Talpey <tom@talpey.com> R: Tom Talpey <tom@talpey.com>
L: linux-cifs@vger.kernel.org L: linux-cifs@vger.kernel.org
@ -25336,8 +25342,8 @@ F: Documentation/networking/timestamping.rst
F: include/linux/net_tstamp.h F: include/linux/net_tstamp.h
F: include/uapi/linux/net_tstamp.h F: include/uapi/linux/net_tstamp.h
F: tools/testing/selftests/bpf/*/net_timestamping* F: tools/testing/selftests/bpf/*/net_timestamping*
F: tools/testing/selftests/drivers/net/so_txtime.*
F: tools/testing/selftests/net/*timestamp* F: tools/testing/selftests/net/*timestamp*
F: tools/testing/selftests/net/so_txtime.c
SOEKRIS NET48XX LED SUPPORT SOEKRIS NET48XX LED SUPPORT
M: Chris Boot <bootc@bootc.net> M: Chris Boot <bootc@bootc.net>
@ -25404,7 +25410,7 @@ F: drivers/md/md*
F: drivers/md/raid* F: drivers/md/raid*
F: include/linux/raid/ F: include/linux/raid/
F: include/uapi/linux/raid/ F: include/uapi/linux/raid/
F: lib/raid/ F: lib/raid/raid6/
SOLIDRUN CLEARFOG SUPPORT SOLIDRUN CLEARFOG SUPPORT
M: Russell King <linux@armlinux.org.uk> M: Russell King <linux@armlinux.org.uk>
@ -26948,7 +26954,8 @@ S: Maintained
F: drivers/net/ethernet/tehuti/tn40* F: drivers/net/ethernet/tehuti/tn40*
TELECOM CLOCK DRIVER FOR MCPL0010 TELECOM CLOCK DRIVER FOR MCPL0010
S: Orphan M: Mark Gross <markgross@kernel.org>
S: Supported
F: drivers/char/tlclk.c F: drivers/char/tlclk.c
TEMPO SEMICONDUCTOR DRIVERS TEMPO SEMICONDUCTOR DRIVERS
@ -28609,6 +28616,7 @@ L: iommu@lists.linux.dev
S: Maintained S: Maintained
F: Documentation/devicetree/bindings/iommu/verisilicon,iommu.yaml F: Documentation/devicetree/bindings/iommu/verisilicon,iommu.yaml
F: drivers/iommu/vsi-iommu.c F: drivers/iommu/vsi-iommu.c
F: include/linux/vsi-iommu.h
VF610 NAND DRIVER VF610 NAND DRIVER
M: Stefan Agner <stefan@agner.ch> M: Stefan Agner <stefan@agner.ch>
@ -28868,8 +28876,8 @@ F: include/uapi/linux/virtio_console.h
VIRTIO CORE VIRTIO CORE
M: "Michael S. Tsirkin" <mst@redhat.com> M: "Michael S. Tsirkin" <mst@redhat.com>
M: Jason Wang <jasowangio@gmail.com> M: Jason Wang <jasowangio@gmail.com>
M: Eugenio Pérez <eperezma@redhat.com>
R: Xuan Zhuo <xuanzhuo@linux.alibaba.com> R: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
R: Eugenio Pérez <eperezma@redhat.com>
L: virtualization@lists.linux.dev L: virtualization@lists.linux.dev
S: Maintained S: Maintained
F: Documentation/ABI/testing/sysfs-bus-vdpa F: Documentation/ABI/testing/sysfs-bus-vdpa
@ -28946,7 +28954,7 @@ F: include/uapi/linux/virtio_gpu.h
VIRTIO HOST (VHOST) VIRTIO HOST (VHOST)
M: "Michael S. Tsirkin" <mst@redhat.com> M: "Michael S. Tsirkin" <mst@redhat.com>
M: Jason Wang <jasowangio@gmail.com> M: Jason Wang <jasowangio@gmail.com>
M: Eugenio Pérez <eperezma@redhat.com> R: Eugenio Pérez <eperezma@redhat.com>
L: kvm@vger.kernel.org L: kvm@vger.kernel.org
L: virtualization@lists.linux.dev L: virtualization@lists.linux.dev
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
@ -29001,8 +29009,8 @@ F: include/uapi/linux/virtio_mem.h
VIRTIO NET DRIVER VIRTIO NET DRIVER
M: "Michael S. Tsirkin" <mst@redhat.com> M: "Michael S. Tsirkin" <mst@redhat.com>
M: Jason Wang <jasowangio@gmail.com> M: Jason Wang <jasowangio@gmail.com>
M: Eugenio Pérez <eperezma@redhat.com>
R: Xuan Zhuo <xuanzhuo@linux.alibaba.com> R: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
R: Eugenio Pérez <eperezma@redhat.com>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
L: virtualization@lists.linux.dev L: virtualization@lists.linux.dev
S: Maintained S: Maintained
@ -29018,13 +29026,6 @@ S: Maintained
F: drivers/nvdimm/nd_virtio.c F: drivers/nvdimm/nd_virtio.c
F: drivers/nvdimm/virtio_pmem.c F: drivers/nvdimm/virtio_pmem.c
VIRTIO RNG DRIVER
M: Laurent Vivier <lvivier@redhat.com>
L: virtualization@lists.linux.dev
S: Maintained
F: drivers/char/hw_random/virtio-rng.c
F: include/uapi/linux/virtio_rng.h
VIRTIO RTC DRIVER VIRTIO RTC DRIVER
M: Peter Hilber <peter.hilber@oss.qualcomm.com> M: Peter Hilber <peter.hilber@oss.qualcomm.com>
L: virtualization@lists.linux.dev L: virtualization@lists.linux.dev
@ -29356,7 +29357,7 @@ M: Guenter Roeck <linux@roeck-us.net>
L: linux-watchdog@vger.kernel.org L: linux-watchdog@vger.kernel.org
S: Maintained S: Maintained
W: http://www.linux-watchdog.org/ W: http://www.linux-watchdog.org/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git T: git git://www.linux-watchdog.org/linux-watchdog.git
F: Documentation/devicetree/bindings/watchdog/ F: Documentation/devicetree/bindings/watchdog/
F: Documentation/watchdog/ F: Documentation/watchdog/
F: drivers/watchdog/ F: drivers/watchdog/
@ -29936,14 +29937,12 @@ F: include/uapi/linux/xilinx-v4l2-controls.h
XILINX VERSAL EDAC DRIVER XILINX VERSAL EDAC DRIVER
M: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com> M: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
M: Sai Krishna Potthuri <sai.krishna.potthuri@amd.com> M: Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>
R: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
S: Maintained S: Maintained
F: Documentation/devicetree/bindings/memory-controllers/xlnx,versal-ddrmc-edac.yaml F: Documentation/devicetree/bindings/memory-controllers/xlnx,versal-ddrmc-edac.yaml
F: drivers/edac/versal_edac.c F: drivers/edac/versal_edac.c
XILINX VERSALNET EDAC DRIVER XILINX VERSALNET EDAC DRIVER
M: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com> M: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
R: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
S: Maintained S: Maintained
F: Documentation/devicetree/bindings/memory-controllers/xlnx,versal-net-ddrmc5.yaml F: Documentation/devicetree/bindings/memory-controllers/xlnx,versal-net-ddrmc5.yaml
F: drivers/edac/versalnet_edac.c F: drivers/edac/versalnet_edac.c
@ -29989,7 +29988,6 @@ F: include/dt-bindings/dma/xlnx-zynqmp-dpdma.h
XILINX ZYNQMP OCM EDAC DRIVER XILINX ZYNQMP OCM EDAC DRIVER
M: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com> M: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
M: Sai Krishna Potthuri <sai.krishna.potthuri@amd.com> M: Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>
R: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
S: Maintained S: Maintained
F: Documentation/devicetree/bindings/memory-controllers/xlnx,zynqmp-ocmc-1.0.yaml F: Documentation/devicetree/bindings/memory-controllers/xlnx,zynqmp-ocmc-1.0.yaml
F: drivers/edac/zynqmp_edac.c F: drivers/edac/zynqmp_edac.c

View File

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

View File

@ -66,7 +66,7 @@ static int aesbs_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
struct crypto_aes_ctx *rk; struct crypto_aes_ctx *rk;
int err; int err;
rk = kmalloc_obj(*rk); rk = kmalloc(sizeof(*rk), GFP_KERNEL);
if (!rk) if (!rk)
return -ENOMEM; return -ENOMEM;
@ -128,7 +128,7 @@ static int aesbs_cbc_ctr_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
struct crypto_aes_ctx *rk; struct crypto_aes_ctx *rk;
int err; int err;
rk = kmalloc_obj(*rk); rk = kmalloc(sizeof(*rk), GFP_KERNEL);
if (!rk) if (!rk)
return -ENOMEM; return -ENOMEM;

View File

@ -78,6 +78,5 @@ void __init cpuinfo_store_boot_cpu(void);
void __init init_cpu_features(struct cpuinfo_arm64 *info); void __init init_cpu_features(struct cpuinfo_arm64 *info);
void update_cpu_features(int cpu, struct cpuinfo_arm64 *info, void update_cpu_features(int cpu, struct cpuinfo_arm64 *info,
struct cpuinfo_arm64 *boot); struct cpuinfo_arm64 *boot);
bool gmid_el1_accessible(const struct cpuinfo_arm64 *info);
#endif /* __ASM_CPU_H */ #endif /* __ASM_CPU_H */

View File

@ -627,6 +627,13 @@ static inline bool id_aa64pfr1_mpamfrac(u64 pfr1)
return val > 0; return val > 0;
} }
static inline bool id_aa64pfr1_mte(u64 pfr1)
{
u32 val = cpuid_feature_extract_unsigned_field(pfr1, ID_AA64PFR1_EL1_MTE_SHIFT);
return val >= ID_AA64PFR1_EL1_MTE_MTE2;
}
void __init setup_boot_cpu_features(void); void __init setup_boot_cpu_features(void);
void __init setup_system_features(void); void __init setup_system_features(void);
void __init setup_user_features(void); void __init setup_user_features(void);

View File

@ -82,7 +82,7 @@ is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope)
for (i = 0; i < target_impl_cpu_num; i++) { for (i = 0; i < target_impl_cpu_num; i++) {
if (__is_affected_midr_range(entry, target_impl_cpus[i].midr, if (__is_affected_midr_range(entry, target_impl_cpus[i].midr,
target_impl_cpus[i].revidr)) target_impl_cpus[i].midr))
return true; return true;
} }
return false; return false;

View File

@ -1178,33 +1178,6 @@ static bool detect_ftr_has_mpam(void)
return id_aa64pfr0_mpam(pfr0) || id_aa64pfr1_mpamfrac(pfr1); return id_aa64pfr0_mpam(pfr0) || id_aa64pfr1_mpamfrac(pfr1);
} }
bool gmid_el1_accessible(const struct cpuinfo_arm64 *info)
{
const struct arm64_ftr_bits *ftrp;
s64 mte, ovr;
u64 ftr_mask;
/* No ID register reflects CONFIG_ARM64_MTE. */
if (!IS_ENABLED(CONFIG_ARM64_MTE))
return false;
for (ftrp = ftr_id_aa64pfr1; ftrp->width; ftrp++) {
if (ftrp->shift == ID_AA64PFR1_EL1_MTE_SHIFT)
break;
}
ftr_mask = arm64_ftr_mask(ftrp);
mte = arm64_ftr_value(ftrp, info->reg_id_aa64pfr1);
/* The boot CPU runs before init_cpu_ftr_reg() strips unsafe overrides. */
if ((id_aa64pfr1_override.mask & ftr_mask) == ftr_mask) {
ovr = arm64_ftr_value(ftrp, id_aa64pfr1_override.val);
mte = arm64_ftr_safe_value(ftrp, ovr, mte);
}
return mte >= ID_AA64PFR1_EL1_MTE_MTE2;
}
void __init init_cpu_features(struct cpuinfo_arm64 *info) void __init init_cpu_features(struct cpuinfo_arm64 *info)
{ {
/* Before we start using the tables, make sure it is sorted */ /* Before we start using the tables, make sure it is sorted */
@ -1257,7 +1230,7 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
init_cpu_ftr_reg(SYS_MPAMIDR_EL1, info->reg_mpamidr); init_cpu_ftr_reg(SYS_MPAMIDR_EL1, info->reg_mpamidr);
} }
if (gmid_el1_accessible(info)) if (id_aa64pfr1_mte(info->reg_id_aa64pfr1))
init_cpu_ftr_reg(SYS_GMID_EL1, info->reg_gmid); init_cpu_ftr_reg(SYS_GMID_EL1, info->reg_gmid);
} }
@ -1519,9 +1492,11 @@ void update_cpu_features(int cpu,
* they read/write depends on the GMID_EL1.BS field. Check that the * they read/write depends on the GMID_EL1.BS field. Check that the
* value is the same on all CPUs. * value is the same on all CPUs.
*/ */
if (gmid_el1_accessible(info)) if (IS_ENABLED(CONFIG_ARM64_MTE) &&
id_aa64pfr1_mte(info->reg_id_aa64pfr1)) {
taint |= check_update_ftr_reg(SYS_GMID_EL1, cpu, taint |= check_update_ftr_reg(SYS_GMID_EL1, cpu,
info->reg_gmid, boot->reg_gmid); info->reg_gmid, boot->reg_gmid);
}
/* /*
* If we don't have AArch32 at all then skip the checks entirely * If we don't have AArch32 at all then skip the checks entirely

View File

@ -502,7 +502,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
info->reg_id_aa64smfr0 = read_cpuid(ID_AA64SMFR0_EL1); info->reg_id_aa64smfr0 = read_cpuid(ID_AA64SMFR0_EL1);
info->reg_id_aa64fpfr0 = read_cpuid(ID_AA64FPFR0_EL1); info->reg_id_aa64fpfr0 = read_cpuid(ID_AA64FPFR0_EL1);
if (gmid_el1_accessible(info)) if (id_aa64pfr1_mte(info->reg_id_aa64pfr1))
info->reg_gmid = read_cpuid(GMID_EL1); info->reg_gmid = read_cpuid(GMID_EL1);
if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0)) if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0))

View File

@ -129,8 +129,7 @@ int machine_kexec_post_load(struct kimage *kimage)
} }
/* Create a copy of the linear map */ /* Create a copy of the linear map */
rc = trans_pgd_create_copy(&info, &trans_pgd, rc = trans_pgd_create_copy(&info, &trans_pgd, PAGE_OFFSET, PAGE_END);
_PAGE_OFFSET(vabits_actual), PAGE_END);
if (rc) if (rc)
return rc; return rc;
kimage->arch.ttbr1 = __pa(trans_pgd); kimage->arch.ttbr1 = __pa(trans_pgd);

View File

@ -93,7 +93,7 @@ int kvm_vcpu_init_nested(struct kvm_vcpu *vcpu)
num_mmus = atomic_read(&kvm->online_vcpus) * S2_MMU_PER_VCPU; num_mmus = atomic_read(&kvm->online_vcpus) * S2_MMU_PER_VCPU;
if (num_mmus > kvm->arch.nested_mmus_size) { if (num_mmus > kvm->arch.nested_mmus_size) {
tmp = kvzalloc_objs(*tmp, num_mmus, GFP_KERNEL_ACCOUNT); tmp = kvcalloc(num_mmus, sizeof(*tmp), GFP_KERNEL_ACCOUNT);
if (!tmp) if (!tmp)
return -ENOMEM; return -ENOMEM;

View File

@ -16,7 +16,6 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/hardirq.h> #include <linux/hardirq.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/irqflags.h>
#include <linux/kasan.h> #include <linux/kasan.h>
#include <linux/kprobes.h> #include <linux/kprobes.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
@ -155,9 +154,6 @@ static void show_pte(unsigned long addr)
pr_alert("%s pgtable: %luk pages, %llu-bit VAs, pgdp=%016lx\n", pr_alert("%s pgtable: %luk pages, %llu-bit VAs, pgdp=%016lx\n",
mm == &init_mm ? "swapper" : "user", PAGE_SIZE / SZ_1K, mm == &init_mm ? "swapper" : "user", PAGE_SIZE / SZ_1K,
vabits_actual, mm_to_pgd_phys(mm)); vabits_actual, mm_to_pgd_phys(mm));
guard(irqsave)();
pgdp = pgd_offset(mm, addr); pgdp = pgd_offset(mm, addr);
pgd = READ_ONCE(*pgdp); pgd = READ_ONCE(*pgdp);
pr_alert("[%016lx] pgd=%016llx", addr, pgd_val(pgd)); pr_alert("[%016lx] pgd=%016llx", addr, pgd_val(pgd));
@ -171,25 +167,25 @@ static void show_pte(unsigned long addr)
if (pgd_none(pgd) || pgd_bad(pgd)) if (pgd_none(pgd) || pgd_bad(pgd))
break; break;
p4dp = p4d_offset_lockless(pgdp, pgd, addr); p4dp = p4d_offset(pgdp, addr);
p4d = READ_ONCE(*p4dp); p4d = READ_ONCE(*p4dp);
pr_cont(", p4d=%016llx", p4d_val(p4d)); pr_cont(", p4d=%016llx", p4d_val(p4d));
if (p4d_none(p4d) || p4d_bad(p4d)) if (p4d_none(p4d) || p4d_bad(p4d))
break; break;
pudp = pud_offset_lockless(p4dp, p4d, addr); pudp = pud_offset(p4dp, addr);
pud = READ_ONCE(*pudp); pud = READ_ONCE(*pudp);
pr_cont(", pud=%016llx", pud_val(pud)); pr_cont(", pud=%016llx", pud_val(pud));
if (pud_none(pud) || pud_bad(pud)) if (pud_none(pud) || pud_bad(pud))
break; break;
pmdp = pmd_offset_lockless(pudp, pud, addr); pmdp = pmd_offset(pudp, addr);
pmd = READ_ONCE(*pmdp); pmd = READ_ONCE(*pmdp);
pr_cont(", pmd=%016llx", pmd_val(pmd)); pr_cont(", pmd=%016llx", pmd_val(pmd));
if (pmd_none(pmd) || pmd_bad(pmd)) if (pmd_none(pmd) || pmd_bad(pmd))
break; break;
ptep = pte_offset_map(&pmd, addr); ptep = pte_offset_map(pmdp, addr);
if (!ptep) if (!ptep)
break; break;

View File

@ -175,7 +175,7 @@ config LOONGARCH
select HAVE_RELIABLE_STACKTRACE if UNWINDER_ORC select HAVE_RELIABLE_STACKTRACE if UNWINDER_ORC
select HAVE_RETHOOK select HAVE_RETHOOK
select HAVE_RSEQ select HAVE_RSEQ
select HAVE_RUST if !KASAN select HAVE_RUST
select HAVE_SAMPLE_FTRACE_DIRECT select HAVE_SAMPLE_FTRACE_DIRECT
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
select HAVE_SETUP_PER_CPU_AREA if NUMA select HAVE_SETUP_PER_CPU_AREA if NUMA

View File

@ -20,7 +20,6 @@ struct dmsintc_state {
}; };
int kvm_loongarch_register_dmsintc_device(void); int kvm_loongarch_register_dmsintc_device(void);
void kvm_loongarch_unregister_dmsintc_device(void);
void dmsintc_inject_irq(struct kvm_vcpu *vcpu); void dmsintc_inject_irq(struct kvm_vcpu *vcpu);
int dmsintc_set_irq(struct kvm *kvm, u64 addr, int data, int level); int dmsintc_set_irq(struct kvm *kvm, u64 addr, int data, int level);
int dmsintc_deliver_msi_to_vcpu(struct kvm *kvm, struct kvm_vcpu *vcpu, u32 vector, int level); int dmsintc_deliver_msi_to_vcpu(struct kvm *kvm, struct kvm_vcpu *vcpu, u32 vector, int level);

View File

@ -79,7 +79,6 @@ struct loongarch_eiointc {
}; };
int kvm_loongarch_register_eiointc_device(void); int kvm_loongarch_register_eiointc_device(void);
void kvm_loongarch_unregister_eiointc_device(void);
void eiointc_set_irq(struct loongarch_eiointc *s, int irq, int level); void eiointc_set_irq(struct loongarch_eiointc *s, int irq, int level);
#endif /* __ASM_KVM_EIOINTC_H */ #endif /* __ASM_KVM_EIOINTC_H */

View File

@ -125,7 +125,6 @@ struct kvm_arch {
unsigned int pte_shifts[MAX_PGTABLE_LEVELS]; unsigned int pte_shifts[MAX_PGTABLE_LEVELS];
unsigned int root_level; unsigned int root_level;
spinlock_t phyid_map_lock; spinlock_t phyid_map_lock;
spinlock_t pv_setting_lock;
struct kvm_phyid_map *phyid_map; struct kvm_phyid_map *phyid_map;
/* Enabled PV features */ /* Enabled PV features */
unsigned long pv_features; unsigned long pv_features;
@ -351,6 +350,7 @@ static inline void kvm_arch_vcpu_block_finish(struct kvm_vcpu *vcpu) {}
static inline void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *slot) {} static inline void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *slot) {}
void kvm_check_vpid(struct kvm_vcpu *vcpu); void kvm_check_vpid(struct kvm_vcpu *vcpu);
enum hrtimer_restart kvm_swtimer_wakeup(struct hrtimer *timer); enum hrtimer_restart kvm_swtimer_wakeup(struct hrtimer *timer);
void kvm_arch_flush_remote_tlbs_memslot(struct kvm *kvm, const struct kvm_memory_slot *memslot);
void kvm_init_vmcs(struct kvm *kvm); void kvm_init_vmcs(struct kvm *kvm);
void kvm_exc_entry(void); void kvm_exc_entry(void);
int kvm_enter_guest(struct kvm_run *run, struct kvm_vcpu *vcpu); int kvm_enter_guest(struct kvm_run *run, struct kvm_vcpu *vcpu);

View File

@ -41,6 +41,5 @@ struct ipi_state {
#define IOCSR_ANY_SEND 0x158 #define IOCSR_ANY_SEND 0x158
int kvm_loongarch_register_ipi_device(void); int kvm_loongarch_register_ipi_device(void);
void kvm_loongarch_unregister_ipi_device(void);
#endif #endif

View File

@ -70,7 +70,6 @@ struct loongarch_pch_pic {
struct kvm_kernel_irq_routing_entry; struct kvm_kernel_irq_routing_entry;
int kvm_loongarch_register_pch_pic_device(void); int kvm_loongarch_register_pch_pic_device(void);
void kvm_loongarch_unregister_pch_pic_device(void);
void pch_pic_set_irq(struct loongarch_pch_pic *s, int irq, int level); void pch_pic_set_irq(struct loongarch_pch_pic *s, int irq, int level);
int pch_msi_set_irq(struct kvm *kvm, struct kvm_kernel_irq_routing_entry *e, int level); int pch_msi_set_irq(struct kvm *kvm, struct kvm_kernel_irq_routing_entry *e, int level);

View File

@ -275,9 +275,6 @@ bool kprobe_singlestep_handler(struct pt_regs *regs)
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
unsigned long addr = instruction_pointer(regs); unsigned long addr = instruction_pointer(regs);
if (!cur)
return false;
if (cur && (kcb->kprobe_status & (KPROBE_HIT_SS | KPROBE_REENTER)) && if (cur && (kcb->kprobe_status & (KPROBE_HIT_SS | KPROBE_REENTER)) &&
((unsigned long)&cur->ainsn.insn[1] == addr)) { ((unsigned long)&cur->ainsn.insn[1] == addr)) {
restore_local_irqflag(kcb, regs); restore_local_irqflag(kcb, regs);

View File

@ -24,6 +24,7 @@
cfi_st t6, PT_R18 cfi_st t6, PT_R18
cfi_st t7, PT_R19 cfi_st t7, PT_R19
cfi_st t8, PT_R20 cfi_st t8, PT_R20
cfi_st u0, PT_R21
cfi_st fp, PT_R22 cfi_st fp, PT_R22
cfi_st s0, PT_R23 cfi_st s0, PT_R23
cfi_st s1, PT_R24 cfi_st s1, PT_R24
@ -58,6 +59,7 @@
cfi_ld t6, PT_R18 cfi_ld t6, PT_R18
cfi_ld t7, PT_R19 cfi_ld t7, PT_R19
cfi_ld t8, PT_R20 cfi_ld t8, PT_R20
cfi_ld u0, PT_R21
cfi_ld fp, PT_R22 cfi_ld fp, PT_R22
cfi_ld s0, PT_R23 cfi_ld s0, PT_R23
cfi_ld s1, PT_R24 cfi_ld s1, PT_R24

View File

@ -14,6 +14,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irq_work.h> #include <linux/irq_work.h>
#include <linux/profile.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/threads.h> #include <linux/threads.h>
@ -715,6 +716,13 @@ void smp_send_stop(void)
smp_call_function(stop_this_cpu, NULL, 0); smp_call_function(stop_this_cpu, NULL, 0);
} }
#ifdef CONFIG_PROFILING
int setup_profiling_timer(unsigned int multiplier)
{
return 0;
}
#endif
static void flush_tlb_all_ipi(void *info) static void flush_tlb_all_ipi(void *info)
{ {
local_flush_tlb_all(); local_flush_tlb_all();

View File

@ -23,7 +23,7 @@
#include "image-vars.h" #include "image-vars.h"
/* /*
* Max available Page Size is 64K, so we set SectionAlignment * Max avaliable Page Size is 64K, so we set SectionAlignment
* field of EFI application to 64K. * field of EFI application to 64K.
*/ */
PECOFF_FILE_ALIGN = 0x200; PECOFF_FILE_ALIGN = 0x200;

View File

@ -149,7 +149,7 @@ static int kvm_dmsintc_create(struct kvm_device *dev, u32 type)
return -EINVAL; return -EINVAL;
} }
s = kzalloc_obj(struct loongarch_dmsintc); s = kzalloc(sizeof(struct loongarch_dmsintc), GFP_KERNEL);
if (!s) if (!s)
return -ENOMEM; return -ENOMEM;
@ -180,8 +180,3 @@ int kvm_loongarch_register_dmsintc_device(void)
{ {
return kvm_register_device_ops(&kvm_dmsintc_dev_ops, KVM_DEV_TYPE_LOONGARCH_DMSINTC); return kvm_register_device_ops(&kvm_dmsintc_dev_ops, KVM_DEV_TYPE_LOONGARCH_DMSINTC);
} }
void kvm_loongarch_unregister_dmsintc_device(void)
{
kvm_unregister_device_ops(KVM_DEV_TYPE_LOONGARCH_DMSINTC);
}

View File

@ -695,8 +695,3 @@ int kvm_loongarch_register_eiointc_device(void)
{ {
return kvm_register_device_ops(&kvm_eiointc_dev_ops, KVM_DEV_TYPE_LOONGARCH_EIOINTC); return kvm_register_device_ops(&kvm_eiointc_dev_ops, KVM_DEV_TYPE_LOONGARCH_EIOINTC);
} }
void kvm_loongarch_unregister_eiointc_device(void)
{
kvm_unregister_device_ops(KVM_DEV_TYPE_LOONGARCH_EIOINTC);
}

View File

@ -463,8 +463,3 @@ int kvm_loongarch_register_ipi_device(void)
{ {
return kvm_register_device_ops(&kvm_ipi_dev_ops, KVM_DEV_TYPE_LOONGARCH_IPI); return kvm_register_device_ops(&kvm_ipi_dev_ops, KVM_DEV_TYPE_LOONGARCH_IPI);
} }
void kvm_loongarch_unregister_ipi_device(void)
{
kvm_unregister_device_ops(KVM_DEV_TYPE_LOONGARCH_IPI);
}

View File

@ -78,9 +78,6 @@ int pch_msi_set_irq(struct kvm *kvm, struct kvm_kernel_irq_routing_entry *e, int
return dmsintc_set_irq(kvm, msg_addr, e->msi.data, level); return dmsintc_set_irq(kvm, msg_addr, e->msi.data, level);
} }
if (e->msi.data >= EIOINTC_IRQS)
return -EINVAL;
eiointc_set_irq(kvm->arch.eiointc, e->msi.data, level); eiointc_set_irq(kvm->arch.eiointc, e->msi.data, level);
return 0; return 0;
@ -503,8 +500,3 @@ int kvm_loongarch_register_pch_pic_device(void)
{ {
return kvm_register_device_ops(&kvm_pch_pic_dev_ops, KVM_DEV_TYPE_LOONGARCH_PCHPIC); return kvm_register_device_ops(&kvm_pch_pic_dev_ops, KVM_DEV_TYPE_LOONGARCH_PCHPIC);
} }
void kvm_loongarch_unregister_pch_pic_device(void)
{
kvm_unregister_device_ops(KVM_DEV_TYPE_LOONGARCH_PCHPIC);
}

View File

@ -385,52 +385,27 @@ static int kvm_loongarch_env_init(void)
/* Register LoongArch IPI interrupt controller interface. */ /* Register LoongArch IPI interrupt controller interface. */
ret = kvm_loongarch_register_ipi_device(); ret = kvm_loongarch_register_ipi_device();
if (ret) if (ret)
goto err_env; return ret;
/* Register LoongArch EIOINTC interrupt controller interface. */ /* Register LoongArch EIOINTC interrupt controller interface. */
ret = kvm_loongarch_register_eiointc_device(); ret = kvm_loongarch_register_eiointc_device();
if (ret) if (ret)
goto err_ipi; return ret;
/* Register LoongArch PCH-PIC interrupt controller interface. */ /* Register LoongArch PCH-PIC interrupt controller interface. */
ret = kvm_loongarch_register_pch_pic_device(); ret = kvm_loongarch_register_pch_pic_device();
if (ret) if (ret)
goto err_eiointc; return ret;
/* Register LoongArch DMSINTC interrupt contrroller interface */ /* Register LoongArch DMSINTC interrupt contrroller interface */
if (cpu_has_msgint) { if (cpu_has_msgint)
ret = kvm_loongarch_register_dmsintc_device(); ret = kvm_loongarch_register_dmsintc_device();
if (ret)
goto err_pch_pic;
}
return 0;
err_pch_pic:
kvm_loongarch_unregister_pch_pic_device();
err_eiointc:
kvm_loongarch_unregister_eiointc_device();
err_ipi:
kvm_loongarch_unregister_ipi_device();
err_env:
kvm_unregister_perf_callbacks();
kfree(kvm_loongarch_ops);
kvm_loongarch_ops = NULL;
free_percpu(vmcs);
vmcs = NULL;
return ret; return ret;
} }
static void kvm_loongarch_env_exit(void) static void kvm_loongarch_env_exit(void)
{ {
if (cpu_has_msgint)
kvm_loongarch_unregister_dmsintc_device();
kvm_loongarch_unregister_pch_pic_device();
kvm_loongarch_unregister_eiointc_device();
kvm_loongarch_unregister_ipi_device();
if (vmcs) if (vmcs)
free_percpu(vmcs); free_percpu(vmcs);
@ -453,11 +428,7 @@ static int kvm_loongarch_init(void)
if (r) if (r)
return r; return r;
r = kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE); return kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE);
if (r)
kvm_loongarch_env_exit();
return r;
} }
static void kvm_loongarch_exit(void) static void kvm_loongarch_exit(void)

View File

@ -383,16 +383,6 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, const struct kvm_memory_slot
hva_t hva_start; hva_t hva_start;
size_t size, gpa_offset, hva_offset; size_t size, gpa_offset, hva_offset;
/*
* The generic code allocates a fresh, zeroed memslot for every change,
* so the arch flags computed below must be carried over when only the
* userspace flags change, e.g. when dirty logging is toggled.
*/
if (change == KVM_MR_FLAGS_ONLY) {
new->arch = old->arch;
return 0;
}
if ((change != KVM_MR_MOVE) && (change != KVM_MR_CREATE)) if ((change != KVM_MR_MOVE) && (change != KVM_MR_CREATE))
return 0; return 0;
/* /*
@ -949,3 +939,9 @@ int kvm_handle_mm_fault(struct kvm_vcpu *vcpu, unsigned long gpa, bool write, in
void kvm_arch_sync_dirty_log(struct kvm *kvm, struct kvm_memory_slot *memslot) void kvm_arch_sync_dirty_log(struct kvm *kvm, struct kvm_memory_slot *memslot)
{ {
} }
void kvm_arch_flush_remote_tlbs_memslot(struct kvm *kvm,
const struct kvm_memory_slot *memslot)
{
kvm_flush_remote_tlbs(kvm);
}

View File

@ -1165,14 +1165,10 @@ static int kvm_loongarch_cpucfg_set_attr(struct kvm_vcpu *vcpu,
return -EINVAL; return -EINVAL;
/* All vCPUs need set the same PV features */ /* All vCPUs need set the same PV features */
spin_lock(&kvm->arch.pv_setting_lock);
if ((kvm->arch.pv_features & LOONGARCH_PV_FEAT_UPDATED) if ((kvm->arch.pv_features & LOONGARCH_PV_FEAT_UPDATED)
&& ((kvm->arch.pv_features & valid) != val)) { && ((kvm->arch.pv_features & valid) != val))
spin_unlock(&kvm->arch.pv_setting_lock);
return -EINVAL; return -EINVAL;
}
kvm->arch.pv_features = val | LOONGARCH_PV_FEAT_UPDATED; kvm->arch.pv_features = val | LOONGARCH_PV_FEAT_UPDATED;
spin_unlock(&kvm->arch.pv_setting_lock);
return 0; return 0;
default: default:
return -ENXIO; return -ENXIO;

View File

@ -76,7 +76,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
return -ENOMEM; return -ENOMEM;
} }
spin_lock_init(&kvm->arch.phyid_map_lock); spin_lock_init(&kvm->arch.phyid_map_lock);
spin_lock_init(&kvm->arch.pv_setting_lock);
kvm_init_vmcs(kvm); kvm_init_vmcs(kvm);
kvm_vm_init_features(kvm); kvm_vm_init_features(kvm);

View File

@ -717,7 +717,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
move_reg(ctx, t1, src); move_reg(ctx, t1, src);
emit_zext_32(ctx, t1, true); emit_zext_32(ctx, t1, true);
move_imm(ctx, dst, (ctx->user_vm_start >> 32) << 32, false); move_imm(ctx, dst, (ctx->user_vm_start >> 32) << 32, false);
emit_insn(ctx, beq, t1, LOONGARCH_GPR_ZERO, 2); emit_insn(ctx, beq, t1, LOONGARCH_GPR_ZERO, 1);
emit_insn(ctx, or, t1, dst, t1); emit_insn(ctx, or, t1, dst, t1);
move_reg(ctx, dst, t1); move_reg(ctx, dst, t1);
break; break;

View File

@ -523,24 +523,24 @@ bcm47xx_buttons_add(const struct bcm47xx_gpio_key *buttons, int nbuttons)
/* 1 node for gpio-keys device, 1 node for each button, 1 terminator */ /* 1 node for gpio-keys device, 1 node for each button, 1 terminator */
const struct software_node **node_group __free(kfree) = const struct software_node **node_group __free(kfree) =
kzalloc_objs(*node_group, 1 + nbuttons + 1); kcalloc(1 + nbuttons + 1, sizeof(*node_group), GFP_KERNEL);
if (!node_group) if (!node_group)
return -ENOMEM; return -ENOMEM;
/* 1 code property, 1 gpio property, 1 terminator */ /* 1 code property, 1 gpio property, 1 terminator */
struct property_entry *props __free(kfree) = struct property_entry *props __free(kfree) =
kzalloc_objs(*props, nbuttons * 3); kcalloc(nbuttons * 3, sizeof(*props), GFP_KERNEL);
if (!props) if (!props)
return -ENOMEM; return -ENOMEM;
/* 1 node for gpio-keys device, 1 node for each button */ /* 1 node for gpio-keys device, 1 node for each button */
struct software_node *nodes __free(kfree) = struct software_node *nodes __free(kfree) =
kzalloc_objs(*nodes, 1 + nbuttons); kcalloc(1 + nbuttons, sizeof(*nodes), GFP_KERNEL);
if (!nodes) if (!nodes)
return -ENOMEM; return -ENOMEM;
struct software_node_ref_args *ref_args __free(kfree) = struct software_node_ref_args *ref_args __free(kfree) =
kzalloc_objs(*ref_args, nbuttons); kcalloc(nbuttons, sizeof(*ref_args), GFP_KERNEL);
if (!ref_args) if (!ref_args)
return -ENOMEM; return -ENOMEM;

View File

@ -222,6 +222,8 @@ static inline void arch_interrupt_enter_prepare(struct pt_regs *regs)
if (user_mode(regs)) { if (user_mode(regs)) {
kuap_lock(); kuap_lock();
account_cpu_user_entry();
account_stolen_time();
} else { } else {
kuap_save_and_lock(regs); kuap_save_and_lock(regs);
/* /*
@ -268,7 +270,7 @@ static inline void arch_interrupt_exit_prepare(struct pt_regs *regs)
} }
/* irqentry_exit expects to be called with interrupts disabled */ /* irqentry_exit expects to be called with interrupts disabled */
hard_irq_disable(); local_irq_disable();
} }
static inline void arch_interrupt_async_enter_prepare(struct pt_regs *regs) static inline void arch_interrupt_async_enter_prepare(struct pt_regs *regs)
@ -513,14 +515,8 @@ static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs,
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
local_paca->tm_scratch = regs->msr; local_paca->tm_scratch = regs->msr;
#endif #endif
/* /* Restore user access locks last */
* Do not restore KUAP here. Generic entry might treat this as the last kuap_user_restore(regs);
* arch step before userspace but PowerPC still has kernel work after
* irqentry_exit()/syscall_exit_to_user_mode() i.e. in
* interrupt_exit_user_prepare() / syscall_exit_prepare() may enable
* IRQs and retry. Those functions restore KUAP immediately before rfi,
* which is where it should belong.
*/
} }
#define arch_exit_to_user_mode_prepare arch_exit_to_user_mode_prepare #define arch_exit_to_user_mode_prepare arch_exit_to_user_mode_prepare

View File

@ -533,7 +533,9 @@ static void eeh_rmv_device(struct eeh_dev *edev, void *userdata)
if (rmv_data) if (rmv_data)
list_add(&edev->rmv_entry, &rmv_data->removed_vf_list); list_add(&edev->rmv_entry, &rmv_data->removed_vf_list);
} else { } else {
pci_lock_rescan_remove();
pci_stop_and_remove_bus_device(dev); pci_stop_and_remove_bus_device(dev);
pci_unlock_rescan_remove();
} }
} }

View File

@ -175,7 +175,7 @@ notrace unsigned long syscall_exit_restart(unsigned long r3, struct pt_regs *reg
current_thread_info()->exit_flags &= ~_TIF_RESTOREALL; current_thread_info()->exit_flags &= ~_TIF_RESTOREALL;
regs->exit_result |= ret; regs->exit_result |= ret;
return regs->exit_result; return ret;
} }
#endif #endif

View File

@ -824,6 +824,7 @@ void __init early_init_devtree(void *params)
fadump_append_bootargs(); fadump_append_bootargs();
/* Scan memory nodes and rebuild MEMBLOCKs */ /* Scan memory nodes and rebuild MEMBLOCKs */
early_init_dt_scan_root();
early_init_dt_scan_memory_ppc(); early_init_dt_scan_memory_ppc();
/* /*

View File

@ -54,10 +54,6 @@ int rtas_pci_dn_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
if (!config_access_valid(pdn, where)) if (!config_access_valid(pdn, where))
return PCIBIOS_BAD_REGISTER_NUMBER; return PCIBIOS_BAD_REGISTER_NUMBER;
#ifdef CONFIG_EEH #ifdef CONFIG_EEH
if (pdn->edev &&
(pdn->edev->mode & EEH_DEV_REMOVED))
return PCIBIOS_DEVICE_NOT_FOUND;
if (pdn->edev && pdn->edev->pe && if (pdn->edev && pdn->edev->pe &&
(pdn->edev->pe->state & EEH_PE_CFG_BLOCKED)) (pdn->edev->pe->state & EEH_PE_CFG_BLOCKED))
return PCIBIOS_SET_FAILED; return PCIBIOS_SET_FAILED;
@ -109,10 +105,6 @@ int rtas_pci_dn_write_config(struct pci_dn *pdn, int where, int size, u32 val)
if (!config_access_valid(pdn, where)) if (!config_access_valid(pdn, where))
return PCIBIOS_BAD_REGISTER_NUMBER; return PCIBIOS_BAD_REGISTER_NUMBER;
#ifdef CONFIG_EEH #ifdef CONFIG_EEH
if (pdn->edev &&
(pdn->edev->mode & EEH_DEV_REMOVED))
return PCIBIOS_DEVICE_NOT_FOUND;
if (pdn->edev && pdn->edev->pe && if (pdn->edev && pdn->edev->pe &&
(pdn->edev->pe->state & EEH_PE_CFG_BLOCKED)) (pdn->edev->pe->state & EEH_PE_CFG_BLOCKED))
return PCIBIOS_SET_FAILED; return PCIBIOS_SET_FAILED;

View File

@ -18,10 +18,8 @@ notrace long system_call_exception(struct pt_regs *regs, unsigned long r0)
long ret; long ret;
syscall_fn f; syscall_fn f;
if (unlikely(!syscall_enter_from_user_mode_randomize_stack(regs, &r0))) { if (unlikely(!syscall_enter_from_user_mode_randomize_stack(regs, &r0)))
clear_thread_flag(TIF_SYSCALL_RET);
return syscall_get_error(current, regs); return syscall_get_error(current, regs);
}
if (unlikely(test_and_clear_thread_flag(TIF_SYSCALL_RET))) if (unlikely(test_and_clear_thread_flag(TIF_SYSCALL_RET)))
return syscall_get_error(current, regs); return syscall_get_error(current, regs);

View File

@ -94,8 +94,6 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
cmdline = modified_cmdline; cmdline = modified_cmdline;
} }
kexec_dprintk("Command line: %s", cmdline ? cmdline : "");
if (initrd != NULL) { if (initrd != NULL) {
kbuf.buffer = initrd; kbuf.buffer = initrd;
kbuf.bufsz = kbuf.memsz = initrd_len; kbuf.bufsz = kbuf.memsz = initrd_len;

View File

@ -57,7 +57,7 @@ int arch_check_excluded_range(struct kimage *image, unsigned long start,
emem = image->arch.exclude_ranges; emem = image->arch.exclude_ranges;
for (i = 0; i < emem->nr_ranges; i++) for (i = 0; i < emem->nr_ranges; i++)
if (start <= emem->ranges[i].end && end >= emem->ranges[i].start) if (start < emem->ranges[i].end && end > emem->ranges[i].start)
return 1; return 1;
return 0; return 0;
@ -113,7 +113,7 @@ static int add_usable_mem(struct umem_info *um_info, u64 base, u64 end)
loc_end = um_info->ranges[i].end; loc_end = um_info->ranges[i].end;
if (loc_base >= base && loc_end <= end) if (loc_base >= base && loc_end <= end)
add = true; add = true;
else if (base <= loc_end && end >= loc_base) { else if (base < loc_end && end > loc_base) {
if (loc_base < base) if (loc_base < base)
loc_base = base; loc_base = base;
if (loc_end > end) if (loc_end > end)
@ -377,12 +377,16 @@ static int load_backup_segment(struct kimage *image, struct kexec_buf *kbuf)
static unsigned int kdump_extra_elfcorehdr_size(struct crash_mem *cmem) static unsigned int kdump_extra_elfcorehdr_size(struct crash_mem *cmem)
{ {
#if defined(CONFIG_CRASH_HOTPLUG) && defined(CONFIG_MEMORY_HOTPLUG) #if defined(CONFIG_CRASH_HOTPLUG) && defined(CONFIG_MEMORY_HOTPLUG)
unsigned int extra_sz = 0;
if (CONFIG_CRASH_MAX_MEMORY_RANGES > (unsigned int)PN_XNUM) if (CONFIG_CRASH_MAX_MEMORY_RANGES > (unsigned int)PN_XNUM)
pr_warn("Number of Phdrs %u exceeds max\n", CONFIG_CRASH_MAX_MEMORY_RANGES); pr_warn("Number of Phdrs %u exceeds max\n", CONFIG_CRASH_MAX_MEMORY_RANGES);
else if (cmem->nr_ranges >= CONFIG_CRASH_MAX_MEMORY_RANGES) else if (cmem->nr_ranges >= CONFIG_CRASH_MAX_MEMORY_RANGES)
pr_warn("Configured crash mem ranges may not be enough\n"); pr_warn("Configured crash mem ranges may not be enough\n");
else else
return (CONFIG_CRASH_MAX_MEMORY_RANGES - cmem->nr_ranges) * sizeof(Elf64_Phdr); extra_sz = (CONFIG_CRASH_MAX_MEMORY_RANGES - cmem->nr_ranges) * sizeof(Elf64_Phdr);
return extra_sz;
#endif #endif
return 0; return 0;
} }

View File

@ -6140,12 +6140,12 @@ static int kvmppc_irq_bypass_add_producer_hv(struct irq_bypass_consumer *cons,
struct kvm_kernel_irqfd *irqfd = struct kvm_kernel_irqfd *irqfd =
container_of(cons, struct kvm_kernel_irqfd, consumer); container_of(cons, struct kvm_kernel_irqfd, consumer);
irqfd->producer = prod;
ret = kvmppc_set_passthru_irq(irqfd->kvm, prod->irq, irqfd->gsi); ret = kvmppc_set_passthru_irq(irqfd->kvm, prod->irq, irqfd->gsi);
if (ret) if (ret)
pr_info("kvmppc_set_passthru_irq (irq %d, gsi %d) fails: %d\n", pr_info("kvmppc_set_passthru_irq (irq %d, gsi %d) fails: %d\n",
prod->irq, irqfd->gsi, ret); prod->irq, irqfd->gsi, ret);
else
irqfd->producer = prod;
return ret; return ret;
} }

View File

@ -165,8 +165,6 @@ static int __init pas_setup_mce_regs(void)
while (dev && reg < MAX_MCE_REGS) { while (dev && reg < MAX_MCE_REGS) {
mce_regs[reg].name = kasprintf(GFP_KERNEL, mce_regs[reg].name = kasprintf(GFP_KERNEL,
"mc%d_mcdebug_errsta", reg); "mc%d_mcdebug_errsta", reg);
if (!mce_regs[reg].name)
return -ENOMEM;
mce_regs[reg].addr = pasemi_pci_getcfgaddr(dev, 0x730); mce_regs[reg].addr = pasemi_pci_getcfgaddr(dev, 0x730);
dev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa00a, dev); dev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa00a, dev);
reg++; reg++;

View File

@ -1623,13 +1623,15 @@ int64_t pnv_opal_pci_msi_eoi(struct irq_data *d)
return opal_pci_msi_eoi(phb->opal_id, d->parent_data->hwirq); return opal_pci_msi_eoi(phb->opal_id, d->parent_data->hwirq);
} }
static struct irq_chip pnv_pci_msi_irq_chip;
/* /*
* Returns true iff chip is something that we could call * Returns true iff chip is something that we could call
* pnv_opal_pci_msi_eoi for. * pnv_opal_pci_msi_eoi for.
*/ */
bool is_pnv_opal_msi(struct irq_chip *chip) bool is_pnv_opal_msi(struct irq_chip *chip)
{ {
return chip && chip->name && str_has_prefix(chip->name, "PNV-"); return chip == &pnv_pci_msi_irq_chip;
} }
EXPORT_SYMBOL_GPL(is_pnv_opal_msi); EXPORT_SYMBOL_GPL(is_pnv_opal_msi);
@ -1726,7 +1728,7 @@ static const struct msi_parent_ops pnv_msi_parent_ops = {
.chip_flags = MSI_CHIP_FLAG_SET_EOI, .chip_flags = MSI_CHIP_FLAG_SET_EOI,
.bus_select_token = DOMAIN_BUS_NEXUS, .bus_select_token = DOMAIN_BUS_NEXUS,
.bus_select_mask = MATCH_PCI_MSI, .bus_select_mask = MATCH_PCI_MSI,
.prefix = "PNV-", /* Note: is_pnv_opal_msi() uses this */ .prefix = "PNV-",
.init_dev_msi_info = pnv_init_dev_msi_info, .init_dev_msi_info = pnv_init_dev_msi_info,
}; };

View File

@ -6,8 +6,6 @@
* Copyright 2006 Sony Corp. * Copyright 2006 Sony Corp.
*/ */
#include <linux/minmax.h>
#include <asm/lv1call.h> #include <asm/lv1call.h>
#include "platform.h" #include "platform.h"
@ -76,9 +74,8 @@ static void _dump_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
static u64 make_first_field(const char *text, u64 index) static u64 make_first_field(const char *text, u64 index)
{ {
u64 n = 0; u64 n = 0;
size_t len = min(strlen(text), sizeof(n));
memcpy(&n, text, len); memcpy((char *)&n, text, strnlen(text, sizeof(n)));
return PS3_VENDOR_ID_NONE + (n >> 32) + index; return PS3_VENDOR_ID_NONE + (n >> 32) + index;
} }

View File

@ -527,28 +527,28 @@ static int htmdump_init_debugfs(void)
htm_status_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); htm_status_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!htm_status_buf) { if (!htm_status_buf) {
pr_err("Failed to allocate htmstatus buf\n"); pr_err("Failed to allocate htmstatus buf\n");
goto htm_status_buf_err; return -ENOMEM;
} }
/* Debugfs interface file to present System Processor Configuration */ /* Debugfs interface file to present System Processor Configuration */
htm_info_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); htm_info_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!htm_info_buf) { if (!htm_info_buf) {
pr_err("Failed to allocate htm info buf\n"); pr_err("Failed to allocate htm info buf\n");
goto htm_info_buf_err; return -ENOMEM;
} }
/* Debugfs interface file to present HTM capabilities */ /* Debugfs interface file to present HTM capabilities */
htm_caps_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); htm_caps_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!htm_caps_buf) { if (!htm_caps_buf) {
pr_err("Failed to allocate htm caps buf\n"); pr_err("Failed to allocate htm caps buf\n");
goto htm_caps_buf_err; return -ENOMEM;
} }
/* Memory to present HTM system memory configuration */ /* Memory to present HTM system memory configuration */
htm_mem_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); htm_mem_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!htm_mem_buf) { if (!htm_mem_buf) {
pr_err("Failed to allocate htm mem buf\n"); pr_err("Failed to allocate htm mem buf\n");
goto htm_mem_buf_err; return -ENOMEM;
} }
debugfs_create_file("htmstatus", 0400, htmdump_debugfs_dir, htm_status_buf, &htmstatus_fops); debugfs_create_file("htmstatus", 0400, htmdump_debugfs_dir, htm_status_buf, &htmstatus_fops);
@ -557,17 +557,6 @@ static int htmdump_init_debugfs(void)
debugfs_create_file("htmsystem_mem", 0400, htmdump_debugfs_dir, htm_mem_buf, &htmsystem_mem_fops); debugfs_create_file("htmsystem_mem", 0400, htmdump_debugfs_dir, htm_mem_buf, &htmsystem_mem_fops);
return 0; return 0;
htm_mem_buf_err:
kfree(htm_caps_buf);
htm_caps_buf_err:
kfree(htm_info_buf);
htm_info_buf_err:
kfree(htm_status_buf);
htm_status_buf_err:
debugfs_remove_recursive(htmdump_debugfs_dir);
kfree(htm_buf);
return -ENOMEM;
} }
static int __init htmdump_init(void) static int __init htmdump_init(void)

View File

@ -132,14 +132,11 @@ static int pseries_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
/* First integer stores max config */ /* First integer stores max config */
max_config_vfs = of_read_number(&max_vfs[0], 1); max_config_vfs = of_read_number(&max_vfs[0], 1);
if (max_config_vfs < num_vfs) { if (max_config_vfs < num_vfs || num_vfs > MAX_VFS_FOR_MAP_PE) {
dev_err(&pdev->dev, "Num VFs %x > %x Configurable VFs\n", dev_err(&pdev->dev,
num_vfs, max_config_vfs); "Num VFs %x > %x Configurable VFs\n",
return -EINVAL; num_vfs, (num_vfs > MAX_VFS_FOR_MAP_PE) ?
} MAX_VFS_FOR_MAP_PE : max_config_vfs);
if (num_vfs > MAX_VFS_FOR_MAP_PE) {
dev_err(&pdev->dev, "Num VFs %x > %x PE mapping limit\n",
num_vfs, MAX_VFS_FOR_MAP_PE);
return -EINVAL; return -EINVAL;
} }

View File

@ -1134,7 +1134,7 @@ static int __init xive_init_ipis(void)
if (!ipi_domain) if (!ipi_domain)
goto out_free_fwnode; goto out_free_fwnode;
xive_ipis = kzalloc_objs(*xive_ipis, nr_node_ids); xive_ipis = kzalloc_objs(*xive_ipis, nr_node_ids, GFP_KERNEL);
if (!xive_ipis) if (!xive_ipis)
goto out_free_domain; goto out_free_domain;

View File

@ -326,7 +326,7 @@ config STACKTRACE_SUPPORT
config GENERIC_BUG config GENERIC_BUG
def_bool y def_bool y
depends on BUG depends on BUG
select GENERIC_BUG_RELATIVE_POINTERS select GENERIC_BUG_RELATIVE_POINTERS if 64BIT
config GENERIC_BUG_RELATIVE_POINTERS config GENERIC_BUG_RELATIVE_POINTERS
bool bool

View File

@ -29,8 +29,13 @@
typedef u32 bug_insn_t; typedef u32 bug_insn_t;
#ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
#define __BUG_ENTRY_ADDR RISCV_INT " 1b - ." #define __BUG_ENTRY_ADDR RISCV_INT " 1b - ."
#define __BUG_ENTRY_FILE(file) RISCV_INT " " file " - ." #define __BUG_ENTRY_FILE(file) RISCV_INT " " file " - ."
#else
#define __BUG_ENTRY_ADDR RISCV_PTR " 1b"
#define __BUG_ENTRY_FILE(file) RISCV_PTR " " file
#endif
#ifdef CONFIG_DEBUG_BUGVERBOSE #ifdef CONFIG_DEBUG_BUGVERBOSE
#define __BUG_ENTRY(file, line, flags) \ #define __BUG_ENTRY(file, line, flags) \

View File

@ -61,8 +61,8 @@ static inline void __switch_to_fpu(struct task_struct *prev,
static __always_inline bool has_fpu(void) static __always_inline bool has_fpu(void)
{ {
/* D extension depends on F, so checking D alone is sufficient. */ return riscv_has_extension_likely(RISCV_ISA_EXT_F) ||
return riscv_has_extension_likely(RISCV_ISA_EXT_D); riscv_has_extension_likely(RISCV_ISA_EXT_D);
} }
#else #else
static __always_inline bool has_fpu(void) { return false; } static __always_inline bool has_fpu(void) { return false; }

View File

@ -412,19 +412,6 @@ static const unsigned int riscv_zvbb_exts[] = {
RISCV_ISA_EXT_ZVKB RISCV_ISA_EXT_ZVKB
}; };
/*
* The RISC-V ISA manual specifies that Zfh implies Zfhmin and Zvfh implies
* Zvfhmin. Report the implied subset extensions whenever the supersets are
* detected (see https://github.com/riscv/riscv-isa-manual/pull/3070).
*/
static const unsigned int riscv_zfh_exts[] = {
RISCV_ISA_EXT_ZFHMIN
};
static const unsigned int riscv_zvfh_exts[] = {
RISCV_ISA_EXT_ZVFHMIN
};
#define RISCV_ISA_EXT_ZVE64F_IMPLY_LIST \ #define RISCV_ISA_EXT_ZVE64F_IMPLY_LIST \
RISCV_ISA_EXT_ZVE64X, \ RISCV_ISA_EXT_ZVE64X, \
RISCV_ISA_EXT_ZVE32F, \ RISCV_ISA_EXT_ZVE32F, \
@ -563,8 +550,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
__RISCV_ISA_EXT_DATA(zawrs, RISCV_ISA_EXT_ZAWRS), __RISCV_ISA_EXT_DATA(zawrs, RISCV_ISA_EXT_ZAWRS),
__RISCV_ISA_EXT_DATA_VALIDATE(zfa, RISCV_ISA_EXT_ZFA, riscv_ext_f_depends), __RISCV_ISA_EXT_DATA_VALIDATE(zfa, RISCV_ISA_EXT_ZFA, riscv_ext_f_depends),
__RISCV_ISA_EXT_DATA_VALIDATE(zfbfmin, RISCV_ISA_EXT_ZFBFMIN, riscv_ext_f_depends), __RISCV_ISA_EXT_DATA_VALIDATE(zfbfmin, RISCV_ISA_EXT_ZFBFMIN, riscv_ext_f_depends),
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zfh, RISCV_ISA_EXT_ZFH, __RISCV_ISA_EXT_DATA_VALIDATE(zfh, RISCV_ISA_EXT_ZFH, riscv_ext_f_depends),
riscv_zfh_exts, riscv_ext_f_depends),
__RISCV_ISA_EXT_DATA_VALIDATE(zfhmin, RISCV_ISA_EXT_ZFHMIN, riscv_ext_f_depends), __RISCV_ISA_EXT_DATA_VALIDATE(zfhmin, RISCV_ISA_EXT_ZFHMIN, riscv_ext_f_depends),
__RISCV_ISA_EXT_DATA(zca, RISCV_ISA_EXT_ZCA), __RISCV_ISA_EXT_DATA(zca, RISCV_ISA_EXT_ZCA),
__RISCV_ISA_EXT_DATA_VALIDATE(zcb, RISCV_ISA_EXT_ZCB, riscv_ext_zca_depends), __RISCV_ISA_EXT_DATA_VALIDATE(zcb, RISCV_ISA_EXT_ZCB, riscv_ext_zca_depends),
@ -600,9 +586,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zve64x, RISCV_ISA_EXT_ZVE64X, riscv_zve64x_exts, riscv_ext_vector_x_validate), __RISCV_ISA_EXT_SUPERSET_VALIDATE(zve64x, RISCV_ISA_EXT_ZVE64X, riscv_zve64x_exts, riscv_ext_vector_x_validate),
__RISCV_ISA_EXT_DATA_VALIDATE(zvfbfmin, RISCV_ISA_EXT_ZVFBFMIN, riscv_vector_f_validate), __RISCV_ISA_EXT_DATA_VALIDATE(zvfbfmin, RISCV_ISA_EXT_ZVFBFMIN, riscv_vector_f_validate),
__RISCV_ISA_EXT_DATA_VALIDATE(zvfbfwma, RISCV_ISA_EXT_ZVFBFWMA, riscv_ext_zvfbfwma_validate), __RISCV_ISA_EXT_DATA_VALIDATE(zvfbfwma, RISCV_ISA_EXT_ZVFBFWMA, riscv_ext_zvfbfwma_validate),
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zvfh, RISCV_ISA_EXT_ZVFH, __RISCV_ISA_EXT_DATA(zvfh, RISCV_ISA_EXT_ZVFH),
riscv_zvfh_exts,
riscv_ext_vector_float_validate),
__RISCV_ISA_EXT_DATA(zvfhmin, RISCV_ISA_EXT_ZVFHMIN), __RISCV_ISA_EXT_DATA(zvfhmin, RISCV_ISA_EXT_ZVFHMIN),
__RISCV_ISA_EXT_DATA_VALIDATE(zvkb, RISCV_ISA_EXT_ZVKB, riscv_ext_vector_crypto_validate), __RISCV_ISA_EXT_DATA_VALIDATE(zvkb, RISCV_ISA_EXT_ZVKB, riscv_ext_vector_crypto_validate),
__RISCV_ISA_EXT_DATA_VALIDATE(zvkg, RISCV_ISA_EXT_ZVKG, riscv_ext_vector_crypto_validate), __RISCV_ISA_EXT_DATA_VALIDATE(zvkg, RISCV_ISA_EXT_ZVKG, riscv_ext_vector_crypto_validate),

View File

@ -45,8 +45,6 @@ static __always_inline void *patch_map(void *addr, const unsigned int fixmap)
phys_addr_t phys; phys_addr_t phys;
if (core_kernel_text(uintaddr) || is_kernel_exittext(uintaddr)) { if (core_kernel_text(uintaddr) || is_kernel_exittext(uintaddr)) {
if (!IS_ENABLED(CONFIG_STRICT_KERNEL_RWX))
return addr;
phys = __pa_symbol(addr); phys = __pa_symbol(addr);
} else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) { } else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) {
struct page *page = vmalloc_to_page(addr); struct page *page = vmalloc_to_page(addr);

View File

@ -349,8 +349,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

@ -297,8 +297,6 @@ static u64 hwprobe_vec_misaligned(const struct cpumask *cpus)
static void hwprobe_one_pair(struct riscv_hwprobe *pair, static void hwprobe_one_pair(struct riscv_hwprobe *pair,
const struct cpumask *cpus) const struct cpumask *cpus)
{ {
pair->value = 0;
switch (pair->key) { switch (pair->key) {
case RISCV_HWPROBE_KEY_MVENDORID: case RISCV_HWPROBE_KEY_MVENDORID:
case RISCV_HWPROBE_KEY_MARCHID: case RISCV_HWPROBE_KEY_MARCHID:
@ -333,14 +331,17 @@ static void hwprobe_one_pair(struct riscv_hwprobe *pair,
break; break;
case RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE: case RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE:
pair->value = 0;
if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOZ)) if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOZ))
pair->value = riscv_cboz_block_size; pair->value = riscv_cboz_block_size;
break; break;
case RISCV_HWPROBE_KEY_ZICBOM_BLOCK_SIZE: case RISCV_HWPROBE_KEY_ZICBOM_BLOCK_SIZE:
pair->value = 0;
if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOM)) if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOM))
pair->value = riscv_cbom_block_size; pair->value = riscv_cbom_block_size;
break; break;
case RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE: case RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE:
pair->value = 0;
if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOP)) if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOP))
pair->value = riscv_cbop_block_size; pair->value = riscv_cbop_block_size;
break; break;

View File

@ -525,8 +525,9 @@ static int __init setup_global_riscv_enable(char *str)
if (riscv_nousercfi) if (riscv_nousercfi)
pr_info("RISC-V user CFI disabled via cmdline - shadow stack status : %s, landing pad status : %s\n", pr_info("RISC-V user CFI disabled via cmdline - shadow stack status : %s, landing pad status : %s\n",
str_disabled_enabled(riscv_nousercfi & CMDLINE_DISABLE_RISCV_USERCFI_BCFI), (riscv_nousercfi & CMDLINE_DISABLE_RISCV_USERCFI_BCFI) ? "disabled" :
str_disabled_enabled(riscv_nousercfi & CMDLINE_DISABLE_RISCV_USERCFI_FCFI)); "enabled", (riscv_nousercfi & CMDLINE_DISABLE_RISCV_USERCFI_FCFI) ?
"disabled" : "enabled");
return 1; return 1;
} }

View File

@ -503,8 +503,8 @@ int kvm_riscv_vcpu_pmu_event_info(struct kvm_vcpu *vcpu, unsigned long saddr_low
} }
} }
einfo = kvzalloc_objs(*einfo, num_events, einfo = kvcalloc(num_events, sizeof(*einfo),
GFP_KERNEL_ACCOUNT | __GFP_NOWARN); GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
if (!einfo) { if (!einfo) {
ret = SBI_ERR_FAILURE; ret = SBI_ERR_FAILURE;
goto out; goto out;

View File

@ -76,7 +76,6 @@ SYM_FUNC_START(fallback_scalar_usercopy_sum_enabled)
li a3, 9*SZREG-1 /* size must >= (word_copy stride + SZREG-1) */ li a3, 9*SZREG-1 /* size must >= (word_copy stride + SZREG-1) */
bltu a2, a3, .Lbyte_copy_tail bltu a2, a3, .Lbyte_copy_tail
#if !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
/* /*
* Copy first bytes until dst is aligned to word boundary. * Copy first bytes until dst is aligned to word boundary.
* a0 - start of dst * a0 - start of dst
@ -104,7 +103,7 @@ SYM_FUNC_START(fallback_scalar_usercopy_sum_enabled)
/* a1 - start of src */ /* a1 - start of src */
andi a3, a1, SZREG-1 andi a3, a1, SZREG-1
bnez a3, .Lshift_copy bnez a3, .Lshift_copy
#endif
.Lword_copy: .Lword_copy:
/* /*
* Both src and dst are aligned, unrolled word copy * Both src and dst are aligned, unrolled word copy
@ -138,7 +137,6 @@ SYM_FUNC_START(fallback_scalar_usercopy_sum_enabled)
addi t0, t0, 8*SZREG /* revert to original value */ addi t0, t0, 8*SZREG /* revert to original value */
j .Lbyte_copy_tail j .Lbyte_copy_tail
#if !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
.Lshift_copy: .Lshift_copy:
/* /*
@ -191,7 +189,6 @@ SYM_FUNC_START(fallback_scalar_usercopy_sum_enabled)
/* Revert src to original unaligned value */ /* Revert src to original unaligned value */
add a1, a1, a3 add a1, a1, a3
#endif
.Lbyte_copy_tail: .Lbyte_copy_tail:
/* /*

View File

@ -1465,9 +1465,7 @@ struct execmem_info __init *execmem_arch_setup(void)
[EXECMEM_KPROBES] = { [EXECMEM_KPROBES] = {
.start = VMALLOC_START, .start = VMALLOC_START,
.end = VMALLOC_END, .end = VMALLOC_END,
.pgprot = IS_ENABLED(CONFIG_STRICT_MODULE_RWX) ? .pgprot = PAGE_KERNEL_READ_EXEC,
PAGE_KERNEL_READ_EXEC :
PAGE_KERNEL_EXEC,
.alignment = 1, .alignment = 1,
}, },
[EXECMEM_BPF] = { [EXECMEM_BPF] = {

View File

@ -2128,15 +2128,7 @@ bool bpf_jit_supports_ptr_xchg(void)
bool bpf_jit_supports_arena(void) bool bpf_jit_supports_arena(void)
{ {
/* return true;
* The arena range tree uses kmalloc_nolock(), which needs
* cmpxchg128, provided by ZACAS on riscv.
*/
#ifdef system_has_cmpxchg128
return system_has_cmpxchg128();
#else
return false;
#endif
} }
bool bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena) bool bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena)

View File

@ -45,12 +45,11 @@ static void alt_debug_modify(int type, unsigned int nr, bool clear)
static char *alt_debug_parse(int type, char *str) static char *alt_debug_parse(int type, char *str)
{ {
unsigned long val, endval, limit; unsigned long val, endval;
char *endp; char *endp;
bool clear; bool clear;
int i; int i;
limit = type == ALT_TYPE_FACILITY ? MAX_FACILITY_BIT : MAX_MFEATURE_BIT;
if (*str == ':') { if (*str == ':') {
str++; str++;
} else { } else {
@ -74,7 +73,7 @@ static char *alt_debug_parse(int type, char *str)
if (str == endp) if (str == endp)
break; break;
str = endp; str = endp;
while (val <= endval && val < limit) { while (val <= endval) {
alt_debug_modify(type, val, clear); alt_debug_modify(type, val, clear);
val++; val++;
} }

View File

@ -23,7 +23,6 @@ struct parmarea parmarea __section(".parmarea") = {
}; };
char __bootdata(early_command_line)[COMMAND_LINE_SIZE]; char __bootdata(early_command_line)[COMMAND_LINE_SIZE];
static char command_line_buf[COMMAND_LINE_SIZE];
unsigned int __bootdata_preserved(zlib_dfltcc_support) = ZLIB_DFLTCC_FULL; unsigned int __bootdata_preserved(zlib_dfltcc_support) = ZLIB_DFLTCC_FULL;
struct ipl_parameter_block __bootdata_preserved(ipl_block); struct ipl_parameter_block __bootdata_preserved(ipl_block);
@ -136,29 +135,31 @@ static size_t ipl_block_get_ascii_scpdata(char *dest, size_t size,
static void append_ipl_block_parm(void) static void append_ipl_block_parm(void)
{ {
size_t len, extra = 0; char *parm, *delim;
char *delim; size_t len, rc = 0;
len = strlen(early_command_line); len = strlen(early_command_line);
delim = early_command_line + len; /* '\0' character position */
delim = early_command_line + len; /* '\0' character position */
parm = early_command_line + len + 1; /* append right after '\0' */
switch (ipl_block.pb0_hdr.pbt) { switch (ipl_block.pb0_hdr.pbt) {
case IPL_PBT_CCW: case IPL_PBT_CCW:
extra = ipl_block_get_ascii_vmparm(command_line_buf, sizeof(command_line_buf), &ipl_block); rc = ipl_block_get_ascii_vmparm(
parm, COMMAND_LINE_SIZE - len - 1, &ipl_block);
break; break;
case IPL_PBT_FCP: case IPL_PBT_FCP:
case IPL_PBT_NVME: case IPL_PBT_NVME:
case IPL_PBT_ECKD: case IPL_PBT_ECKD:
extra = ipl_block_get_ascii_scpdata(command_line_buf, sizeof(command_line_buf), &ipl_block); rc = ipl_block_get_ascii_scpdata(
parm, COMMAND_LINE_SIZE - len - 1, &ipl_block);
break; break;
} }
if (extra) { if (rc) {
if (command_line_buf[0] == '=') { if (*parm == '=')
memmove(early_command_line, command_line_buf + 1, extra); memmove(early_command_line, parm + 1, rc);
} else if (len < COMMAND_LINE_SIZE - 2) { else
*delim = ' '; /* replace '\0' with space */ *delim = ' '; /* replace '\0' with space */
sized_strscpy(delim + 1, command_line_buf, COMMAND_LINE_SIZE - len - 1);
}
} }
} }
@ -230,7 +231,7 @@ static void modify_fac_list(char *str)
if (str == endp) if (str == endp)
break; break;
str = endp; str = endp;
while (val <= endval && val < MAX_FACILITY_BIT) { while (val <= endval) {
modify_facility(val, clear); modify_facility(val, clear);
val++; val++;
} }
@ -244,6 +245,7 @@ static void modify_fac_list(char *str)
check_cleared_facilities(); check_cleared_facilities();
} }
static char command_line_buf[COMMAND_LINE_SIZE];
void parse_boot_command_line(void) void parse_boot_command_line(void)
{ {
char *param, *val; char *param, *val;

View File

@ -141,7 +141,7 @@ static int tprot(unsigned long addr)
static unsigned long search_mem_end(void) static unsigned long search_mem_end(void)
{ {
unsigned long range = 1UL << (MAX_PHYSMEM_BITS - 20); /* in 1MB blocks */ unsigned long range = 1 << (MAX_PHYSMEM_BITS - 20); /* in 1MB blocks */
unsigned long offset = 0; unsigned long offset = 0;
unsigned long pivot; unsigned long pivot;

View File

@ -3,8 +3,6 @@
# Cryptographic API # Cryptographic API
# #
CONTEXT_ANALYSIS := y
obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o
obj-$(CONFIG_CRYPTO_PAES_S390) += paes_s390.o obj-$(CONFIG_CRYPTO_PAES_S390) += paes_s390.o
obj-$(CONFIG_S390_PRNG) += prng.o obj-$(CONFIG_S390_PRNG) += prng.o

View File

@ -26,14 +26,14 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/cpufeature.h> #include <linux/cpufeature.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/mutex.h>
#include <linux/fips.h> #include <linux/fips.h>
#include <linux/semaphore.h>
#include <linux/string.h> #include <linux/string.h>
#include <crypto/xts.h> #include <crypto/xts.h>
#include <asm/cpacf.h> #include <asm/cpacf.h>
static u8 *ctrblk; static u8 *ctrblk;
static DEFINE_SEMAPHORE(ctrblk_sem, 1); static DEFINE_MUTEX(ctrblk_lock);
static cpacf_mask_t km_functions, kmc_functions, kmctr_functions, static cpacf_mask_t km_functions, kmc_functions, kmctr_functions,
kma_functions; kma_functions;
@ -129,7 +129,7 @@ static int ecb_aes_crypt(struct skcipher_request *req, unsigned long modifier)
return fallback_skcipher_crypt(sctx, req, modifier); return fallback_skcipher_crypt(sctx, req, modifier);
ret = skcipher_walk_virt(&walk, req, false); ret = skcipher_walk_virt(&walk, req, false);
while (!ret && ((nbytes = walk.nbytes) != 0)) { while ((nbytes = walk.nbytes) != 0) {
/* only use complete blocks */ /* only use complete blocks */
n = nbytes & ~(AES_BLOCK_SIZE - 1); n = nbytes & ~(AES_BLOCK_SIZE - 1);
cpacf_km(sctx->fc | modifier, sctx->key, cpacf_km(sctx->fc | modifier, sctx->key,
@ -233,7 +233,7 @@ static int cbc_aes_crypt(struct skcipher_request *req, unsigned long modifier)
return ret; return ret;
memcpy(param.iv, walk.iv, AES_BLOCK_SIZE); memcpy(param.iv, walk.iv, AES_BLOCK_SIZE);
memcpy(param.key, sctx->key, sctx->key_len); memcpy(param.key, sctx->key, sctx->key_len);
while (!ret && ((nbytes = walk.nbytes) != 0)) { while ((nbytes = walk.nbytes) != 0) {
/* only use complete blocks */ /* only use complete blocks */
n = nbytes & ~(AES_BLOCK_SIZE - 1); n = nbytes & ~(AES_BLOCK_SIZE - 1);
cpacf_kmc(sctx->fc | modifier, &param, cpacf_kmc(sctx->fc | modifier, &param,
@ -359,7 +359,7 @@ static int xts_aes_crypt(struct skcipher_request *req, unsigned long modifier)
memcpy(xts_param.key + offset, xts_ctx->key, xts_ctx->key_len); memcpy(xts_param.key + offset, xts_ctx->key, xts_ctx->key_len);
memcpy(xts_param.init, pcc_param.xts, 16); memcpy(xts_param.init, pcc_param.xts, 16);
while (!ret && ((nbytes = walk.nbytes) != 0)) { while ((nbytes = walk.nbytes) != 0) {
/* only use complete blocks */ /* only use complete blocks */
n = nbytes & ~(AES_BLOCK_SIZE - 1); n = nbytes & ~(AES_BLOCK_SIZE - 1);
cpacf_km(xts_ctx->fc | modifier, xts_param.key + offset, cpacf_km(xts_ctx->fc | modifier, xts_param.key + offset,
@ -487,7 +487,7 @@ static int fullxts_aes_crypt(struct skcipher_request *req, unsigned long modifi
memcpy(fxts_param.tweak, req->iv, AES_BLOCK_SIZE); memcpy(fxts_param.tweak, req->iv, AES_BLOCK_SIZE);
fxts_param.nap[0] = 0x01; /* initial alpha power (1, little-endian) */ fxts_param.nap[0] = 0x01; /* initial alpha power (1, little-endian) */
while (!ret && ((nbytes = walk.nbytes) != 0)) { while ((nbytes = walk.nbytes) != 0) {
/* only use complete blocks */ /* only use complete blocks */
n = nbytes & ~(AES_BLOCK_SIZE - 1); n = nbytes & ~(AES_BLOCK_SIZE - 1);
cpacf_km(xts_ctx->fc | modifier, fxts_param.key + offset, cpacf_km(xts_ctx->fc | modifier, fxts_param.key + offset,
@ -562,64 +562,48 @@ static unsigned int __ctrblk_init(u8 *ctrptr, u8 *iv, unsigned int nbytes)
return n; return n;
} }
static int __ctr_aes_crypt(struct s390_aes_ctx *sctx,
struct skcipher_walk *walk, bool locked)
{
unsigned int n, nbytes;
int ret = 0;
u8 *ctrptr;
while (!ret && ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE)) {
n = AES_BLOCK_SIZE;
if (nbytes >= 2 * AES_BLOCK_SIZE && locked)
n = __ctrblk_init(ctrblk, walk->iv, nbytes);
ctrptr = (n > AES_BLOCK_SIZE) ? ctrblk : walk->iv;
cpacf_kmctr(sctx->fc, sctx->key, walk->dst.virt.addr,
walk->src.virt.addr, n, ctrptr);
if (ctrptr == ctrblk)
memcpy(walk->iv, ctrptr + n - AES_BLOCK_SIZE,
AES_BLOCK_SIZE);
crypto_inc(walk->iv, AES_BLOCK_SIZE);
ret = skcipher_walk_done(walk, nbytes - n);
}
return ret;
}
static int ctr_aes_crypt(struct skcipher_request *req) static int ctr_aes_crypt(struct skcipher_request *req)
{ {
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct s390_aes_ctx *sctx = crypto_skcipher_ctx(tfm); struct s390_aes_ctx *sctx = crypto_skcipher_ctx(tfm);
u8 buf[AES_BLOCK_SIZE], *ctrptr;
struct skcipher_walk walk; struct skcipher_walk walk;
u8 buf[AES_BLOCK_SIZE]; unsigned int n, nbytes;
int ret; int ret, locked;
if (unlikely(!sctx->fc)) if (unlikely(!sctx->fc))
return fallback_skcipher_crypt(sctx, req, 0); return fallback_skcipher_crypt(sctx, req, 0);
locked = mutex_trylock(&ctrblk_lock);
ret = skcipher_walk_virt(&walk, req, false); ret = skcipher_walk_virt(&walk, req, false);
if (ret) while ((nbytes = walk.nbytes) >= AES_BLOCK_SIZE) {
return ret; n = AES_BLOCK_SIZE;
if (down_trylock(&ctrblk_sem) == 0) { if (nbytes >= 2*AES_BLOCK_SIZE && locked)
ret = __ctr_aes_crypt(sctx, &walk, true); n = __ctrblk_init(ctrblk, walk.iv, nbytes);
up(&ctrblk_sem); ctrptr = (n > AES_BLOCK_SIZE) ? ctrblk : walk.iv;
} else { cpacf_kmctr(sctx->fc, sctx->key, walk.dst.virt.addr,
ret = __ctr_aes_crypt(sctx, &walk, false); walk.src.virt.addr, n, ctrptr);
if (ctrptr == ctrblk)
memcpy(walk.iv, ctrptr + n - AES_BLOCK_SIZE,
AES_BLOCK_SIZE);
crypto_inc(walk.iv, AES_BLOCK_SIZE);
ret = skcipher_walk_done(&walk, nbytes - n);
} }
if (locked)
mutex_unlock(&ctrblk_lock);
/* /*
* final block may be < AES_BLOCK_SIZE, copy only nbytes * final block may be < AES_BLOCK_SIZE, copy only nbytes
*/ */
if (!ret && walk.nbytes > 0) { if (nbytes) {
memset(buf, 0, AES_BLOCK_SIZE); memset(buf, 0, AES_BLOCK_SIZE);
memcpy(buf, walk.src.virt.addr, walk.nbytes); memcpy(buf, walk.src.virt.addr, nbytes);
cpacf_kmctr(sctx->fc, sctx->key, buf, buf, cpacf_kmctr(sctx->fc, sctx->key, buf, buf,
AES_BLOCK_SIZE, walk.iv); AES_BLOCK_SIZE, walk.iv);
memcpy(walk.dst.virt.addr, buf, walk.nbytes); memcpy(walk.dst.virt.addr, buf, nbytes);
crypto_inc(walk.iv, AES_BLOCK_SIZE); crypto_inc(walk.iv, AES_BLOCK_SIZE);
ret = skcipher_walk_done(&walk, 0); ret = skcipher_walk_done(&walk, 0);
memzero_explicit(buf, sizeof(buf));
} }
return ret; return ret;
@ -911,14 +895,10 @@ static int gcm_aes_crypt(struct aead_request *req, unsigned int flags)
gw_in.ptr, aad_bytes); gw_in.ptr, aad_bytes);
n = aad_bytes + pc_bytes; n = aad_bytes + pc_bytes;
if (gcm_in_walk_done(&gw_in, n) != n) { if (gcm_in_walk_done(&gw_in, n) != n)
ret = -ENOMEM; return -ENOMEM;
goto out; if (gcm_out_walk_done(&gw_out, n) != n)
} return -ENOMEM;
if (gcm_out_walk_done(&gw_out, n) != n) {
ret = -ENOMEM;
goto out;
}
aadlen -= aad_bytes; aadlen -= aad_bytes;
pclen -= pc_bytes; pclen -= pc_bytes;
} while (aadlen + pclen > 0); } while (aadlen + pclen > 0);
@ -930,10 +910,7 @@ static int gcm_aes_crypt(struct aead_request *req, unsigned int flags)
} else } else
scatterwalk_map_and_copy(param.t, req->dst, len, taglen, 1); scatterwalk_map_and_copy(param.t, req->dst, len, taglen, 1);
out:
memzero_explicit(&param, sizeof(param)); memzero_explicit(&param, sizeof(param));
memzero_explicit(gw_in.buf, sizeof(gw_in.buf));
memzero_explicit(gw_out.buf, sizeof(gw_out.buf));
return ret; return ret;
} }

View File

@ -19,7 +19,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/miscdevice.h> #include <linux/miscdevice.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/semaphore.h> #include <linux/mutex.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <crypto/aes.h> #include <crypto/aes.h>
#include <crypto/algapi.h> #include <crypto/algapi.h>
@ -45,7 +45,7 @@ module_param_named(clrkey, pkey_clrkey_allowed, bool, 0444);
MODULE_PARM_DESC(clrkey, "Allow clear key material (default N)"); MODULE_PARM_DESC(clrkey, "Allow clear key material (default N)");
static u8 *ctrblk; static u8 *ctrblk;
static DEFINE_SEMAPHORE(ctrblk_sem, 1); static DEFINE_MUTEX(ctrblk_lock);
static cpacf_mask_t km_functions, kmc_functions, kmctr_functions; static cpacf_mask_t km_functions, kmc_functions, kmctr_functions;
@ -220,10 +220,6 @@ static inline int convert_key(const u8 *key, unsigned int keylen,
xflags); xflags);
} }
/* But finally map -EBUSY to -EIO to indicate an IO failure */
if (rc == -EBUSY)
rc = -EIO;
out: out:
pr_debug("rc=%d\n", rc); pr_debug("rc=%d\n", rc);
return rc; return rc;
@ -436,11 +432,8 @@ static int ecb_paes_do_crypt(struct s390_paes_ctx *ctx,
n = nbytes & ~(AES_BLOCK_SIZE - 1); n = nbytes & ~(AES_BLOCK_SIZE - 1);
k = cpacf_km(ctx->fc | req_ctx->modifier, param, k = cpacf_km(ctx->fc | req_ctx->modifier, param,
walk->dst.virt.addr, walk->src.virt.addr, n); walk->dst.virt.addr, walk->src.virt.addr, n);
if (k) { if (k)
rc = skcipher_walk_done(walk, nbytes - k); rc = skcipher_walk_done(walk, nbytes - k);
if (rc)
goto out;
}
if (k < n) { if (k < n) {
if (!maysleep) { if (!maysleep) {
rc = -EKEYEXPIRED; rc = -EKEYEXPIRED;
@ -467,7 +460,6 @@ static int ecb_paes_crypt(struct skcipher_request *req, unsigned long modifier)
struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm); struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm);
struct skcipher_walk *walk = &req_ctx->walk; struct skcipher_walk *walk = &req_ctx->walk;
bool tested = crypto_skcipher_tested(tfm); bool tested = crypto_skcipher_tested(tfm);
bool cleanup = true;
int rc; int rc;
/* /*
@ -499,17 +491,15 @@ static int ecb_paes_crypt(struct skcipher_request *req, unsigned long modifier)
if (rc == 0 || rc == -EKEYEXPIRED) { if (rc == 0 || rc == -EKEYEXPIRED) {
atomic_inc(&ctx->via_engine_ctr); atomic_inc(&ctx->via_engine_ctr);
rc = crypto_transfer_skcipher_request_to_engine(paes_crypto_engine, req); rc = crypto_transfer_skcipher_request_to_engine(paes_crypto_engine, req);
if (rc == -EINPROGRESS || rc == -EBUSY) if (rc != -EINPROGRESS)
cleanup = false;
else
atomic_dec(&ctx->via_engine_ctr); atomic_dec(&ctx->via_engine_ctr);
} }
if (cleanup && walk->nbytes) if (rc != -EINPROGRESS)
skcipher_walk_done(walk, rc); skcipher_walk_done(walk, rc);
out: out:
if (cleanup) if (rc != -EINPROGRESS)
memzero_explicit(&req_ctx->param, sizeof(req_ctx->param)); memzero_explicit(&req_ctx->param, sizeof(req_ctx->param));
pr_debug("rc=%d\n", rc); pr_debug("rc=%d\n", rc);
return rc; return rc;
@ -559,7 +549,7 @@ static int ecb_paes_do_one_request(struct crypto_engine *engine, void *areq)
rc = ecb_paes_do_crypt(ctx, req_ctx, tested, true); rc = ecb_paes_do_crypt(ctx, req_ctx, tested, true);
if (rc == -EKEYEXPIRED) { if (rc == -EKEYEXPIRED) {
return pkey_handle_expired(); return pkey_handle_expired();
} else if (rc && walk->nbytes) { } else if (rc) {
skcipher_walk_done(walk, rc); skcipher_walk_done(walk, rc);
} }
@ -569,7 +559,7 @@ static int ecb_paes_do_one_request(struct crypto_engine *engine, void *areq)
atomic_dec(&ctx->via_engine_ctr); atomic_dec(&ctx->via_engine_ctr);
crypto_finalize_skcipher_request(engine, req, rc); crypto_finalize_skcipher_request(engine, req, rc);
local_bh_enable(); local_bh_enable();
return 0; return rc;
} }
static struct skcipher_engine_alg ecb_paes_alg = { static struct skcipher_engine_alg ecb_paes_alg = {
@ -577,7 +567,6 @@ static struct skcipher_engine_alg ecb_paes_alg = {
.base.cra_name = "ecb(paes)", .base.cra_name = "ecb(paes)",
.base.cra_driver_name = "ecb-paes-s390", .base.cra_driver_name = "ecb-paes-s390",
.base.cra_priority = 401, /* combo: aes + ecb + 1 */ .base.cra_priority = 401, /* combo: aes + ecb + 1 */
.base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NO_FALLBACK,
.base.cra_blocksize = AES_BLOCK_SIZE, .base.cra_blocksize = AES_BLOCK_SIZE,
.base.cra_ctxsize = sizeof(struct s390_paes_ctx), .base.cra_ctxsize = sizeof(struct s390_paes_ctx),
.base.cra_module = THIS_MODULE, .base.cra_module = THIS_MODULE,
@ -701,8 +690,6 @@ static int cbc_paes_do_crypt(struct s390_paes_ctx *ctx,
if (k) { if (k) {
memcpy(walk->iv, param->iv, AES_BLOCK_SIZE); memcpy(walk->iv, param->iv, AES_BLOCK_SIZE);
rc = skcipher_walk_done(walk, nbytes - k); rc = skcipher_walk_done(walk, nbytes - k);
if (rc)
goto out;
} }
if (k < n) { if (k < n) {
if (!maysleep) { if (!maysleep) {
@ -730,7 +717,6 @@ static int cbc_paes_crypt(struct skcipher_request *req, unsigned long modifier)
struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm); struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm);
struct skcipher_walk *walk = &req_ctx->walk; struct skcipher_walk *walk = &req_ctx->walk;
bool tested = crypto_skcipher_tested(tfm); bool tested = crypto_skcipher_tested(tfm);
bool cleanup = true;
int rc; int rc;
/* /*
@ -762,17 +748,15 @@ static int cbc_paes_crypt(struct skcipher_request *req, unsigned long modifier)
if (rc == 0 || rc == -EKEYEXPIRED) { if (rc == 0 || rc == -EKEYEXPIRED) {
atomic_inc(&ctx->via_engine_ctr); atomic_inc(&ctx->via_engine_ctr);
rc = crypto_transfer_skcipher_request_to_engine(paes_crypto_engine, req); rc = crypto_transfer_skcipher_request_to_engine(paes_crypto_engine, req);
if (rc == -EINPROGRESS || rc == -EBUSY) if (rc != -EINPROGRESS)
cleanup = false;
else
atomic_dec(&ctx->via_engine_ctr); atomic_dec(&ctx->via_engine_ctr);
} }
if (cleanup && walk->nbytes) if (rc != -EINPROGRESS)
skcipher_walk_done(walk, rc); skcipher_walk_done(walk, rc);
out: out:
if (cleanup) if (rc != -EINPROGRESS)
memzero_explicit(&req_ctx->param, sizeof(req_ctx->param)); memzero_explicit(&req_ctx->param, sizeof(req_ctx->param));
pr_debug("rc=%d\n", rc); pr_debug("rc=%d\n", rc);
return rc; return rc;
@ -822,7 +806,7 @@ static int cbc_paes_do_one_request(struct crypto_engine *engine, void *areq)
rc = cbc_paes_do_crypt(ctx, req_ctx, tested, true); rc = cbc_paes_do_crypt(ctx, req_ctx, tested, true);
if (rc == -EKEYEXPIRED) { if (rc == -EKEYEXPIRED) {
return pkey_handle_expired(); return pkey_handle_expired();
} else if (rc && walk->nbytes) { } else if (rc) {
skcipher_walk_done(walk, rc); skcipher_walk_done(walk, rc);
} }
@ -832,7 +816,7 @@ static int cbc_paes_do_one_request(struct crypto_engine *engine, void *areq)
atomic_dec(&ctx->via_engine_ctr); atomic_dec(&ctx->via_engine_ctr);
crypto_finalize_skcipher_request(engine, req, rc); crypto_finalize_skcipher_request(engine, req, rc);
local_bh_enable(); local_bh_enable();
return 0; return rc;
} }
static struct skcipher_engine_alg cbc_paes_alg = { static struct skcipher_engine_alg cbc_paes_alg = {
@ -840,7 +824,6 @@ static struct skcipher_engine_alg cbc_paes_alg = {
.base.cra_name = "cbc(paes)", .base.cra_name = "cbc(paes)",
.base.cra_driver_name = "cbc-paes-s390", .base.cra_driver_name = "cbc-paes-s390",
.base.cra_priority = 402, /* cbc-paes-s390 + 1 */ .base.cra_priority = 402, /* cbc-paes-s390 + 1 */
.base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NO_FALLBACK,
.base.cra_blocksize = AES_BLOCK_SIZE, .base.cra_blocksize = AES_BLOCK_SIZE,
.base.cra_ctxsize = sizeof(struct s390_paes_ctx), .base.cra_ctxsize = sizeof(struct s390_paes_ctx),
.base.cra_module = THIS_MODULE, .base.cra_module = THIS_MODULE,
@ -931,62 +914,15 @@ static inline unsigned int __ctrblk_init(u8 *ctrptr, u8 *iv, unsigned int nbytes
return n; return n;
} }
static int __ctr_paes_do_crypt(struct s390_paes_ctx *ctx,
struct ctr_param *param,
struct skcipher_walk *walk,
bool tested, bool maysleep, bool locked)
{
unsigned int nbytes, n, k;
u8 *ctrptr;
int rc = 0;
/*
* Note that in case of partial processing or failure the walk
* is NOT unmapped here. So a follow up task may reuse the walk
* or in case of unrecoverable failure needs to unmap it.
*/
while ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE) {
n = AES_BLOCK_SIZE;
if (nbytes >= 2 * AES_BLOCK_SIZE && locked)
n = __ctrblk_init(ctrblk, walk->iv, nbytes);
ctrptr = (n > AES_BLOCK_SIZE) ? ctrblk : walk->iv;
k = cpacf_kmctr(ctx->fc, param, walk->dst.virt.addr,
walk->src.virt.addr, n, ctrptr);
if (k) {
if (ctrptr == ctrblk)
memcpy(walk->iv, ctrptr + k - AES_BLOCK_SIZE,
AES_BLOCK_SIZE);
crypto_inc(walk->iv, AES_BLOCK_SIZE);
rc = skcipher_walk_done(walk, nbytes - k);
if (rc)
goto out;
}
if (k < n) {
if (!maysleep) {
rc = -EKEYEXPIRED;
goto out;
}
rc = paes_convert_key(ctx, tested);
if (rc)
goto out;
spin_lock_bh(&ctx->pk_lock);
memcpy(param->key, ctx->pk.protkey, sizeof(param->key));
spin_unlock_bh(&ctx->pk_lock);
}
}
out:
return rc;
}
static int ctr_paes_do_crypt(struct s390_paes_ctx *ctx, static int ctr_paes_do_crypt(struct s390_paes_ctx *ctx,
struct s390_pctr_req_ctx *req_ctx, struct s390_pctr_req_ctx *req_ctx,
bool tested, bool maysleep) bool tested, bool maysleep)
{ {
struct ctr_param *param = &req_ctx->param; struct ctr_param *param = &req_ctx->param;
struct skcipher_walk *walk = &req_ctx->walk; struct skcipher_walk *walk = &req_ctx->walk;
u8 buf[AES_BLOCK_SIZE]; u8 buf[AES_BLOCK_SIZE], *ctrptr;
int pk_state, rc = 0; unsigned int nbytes, n, k;
int pk_state, locked, rc = 0;
if (!req_ctx->param_init_done) { if (!req_ctx->param_init_done) {
/* fetch and check protected key state */ /* fetch and check protected key state */
@ -1012,17 +948,52 @@ static int ctr_paes_do_crypt(struct s390_paes_ctx *ctx,
if (rc) if (rc)
goto out; goto out;
if (down_trylock(&ctrblk_sem) == 0) { locked = mutex_trylock(&ctrblk_lock);
rc = __ctr_paes_do_crypt(ctx, param, walk, tested, maysleep, true);
up(&ctrblk_sem); /*
} else { * Note that in case of partial processing or failure the walk
rc = __ctr_paes_do_crypt(ctx, param, walk, tested, maysleep, false); * is NOT unmapped here. So a follow up task may reuse the walk
* or in case of unrecoverable failure needs to unmap it.
*/
while ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE) {
n = AES_BLOCK_SIZE;
if (nbytes >= 2 * AES_BLOCK_SIZE && locked)
n = __ctrblk_init(ctrblk, walk->iv, nbytes);
ctrptr = (n > AES_BLOCK_SIZE) ? ctrblk : walk->iv;
k = cpacf_kmctr(ctx->fc, param, walk->dst.virt.addr,
walk->src.virt.addr, n, ctrptr);
if (k) {
if (ctrptr == ctrblk)
memcpy(walk->iv, ctrptr + k - AES_BLOCK_SIZE,
AES_BLOCK_SIZE);
crypto_inc(walk->iv, AES_BLOCK_SIZE);
rc = skcipher_walk_done(walk, nbytes - k);
}
if (k < n) {
if (!maysleep) {
if (locked)
mutex_unlock(&ctrblk_lock);
rc = -EKEYEXPIRED;
goto out;
}
rc = paes_convert_key(ctx, tested);
if (rc) {
if (locked)
mutex_unlock(&ctrblk_lock);
goto out;
}
spin_lock_bh(&ctx->pk_lock);
memcpy(param->key, ctx->pk.protkey, sizeof(param->key));
spin_unlock_bh(&ctx->pk_lock);
}
} }
if (locked)
mutex_unlock(&ctrblk_lock);
/* final block may be < AES_BLOCK_SIZE, copy only nbytes */ /* final block may be < AES_BLOCK_SIZE, copy only nbytes */
if (!rc && walk->nbytes > 0) { if (nbytes) {
memset(buf, 0, AES_BLOCK_SIZE); memset(buf, 0, AES_BLOCK_SIZE);
memcpy(buf, walk->src.virt.addr, walk->nbytes); memcpy(buf, walk->src.virt.addr, nbytes);
while (1) { while (1) {
if (cpacf_kmctr(ctx->fc, param, buf, if (cpacf_kmctr(ctx->fc, param, buf,
buf, AES_BLOCK_SIZE, buf, AES_BLOCK_SIZE,
@ -1039,13 +1010,12 @@ static int ctr_paes_do_crypt(struct s390_paes_ctx *ctx,
memcpy(param->key, ctx->pk.protkey, sizeof(param->key)); memcpy(param->key, ctx->pk.protkey, sizeof(param->key));
spin_unlock_bh(&ctx->pk_lock); spin_unlock_bh(&ctx->pk_lock);
} }
memcpy(walk->dst.virt.addr, buf, walk->nbytes); memcpy(walk->dst.virt.addr, buf, nbytes);
crypto_inc(walk->iv, AES_BLOCK_SIZE); crypto_inc(walk->iv, AES_BLOCK_SIZE);
rc = skcipher_walk_done(walk, 0); rc = skcipher_walk_done(walk, 0);
} }
out: out:
memzero_explicit(buf, sizeof(buf));
pr_debug("rc=%d\n", rc); pr_debug("rc=%d\n", rc);
return rc; return rc;
} }
@ -1057,7 +1027,6 @@ static int ctr_paes_crypt(struct skcipher_request *req)
struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm); struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm);
struct skcipher_walk *walk = &req_ctx->walk; struct skcipher_walk *walk = &req_ctx->walk;
bool tested = crypto_skcipher_tested(tfm); bool tested = crypto_skcipher_tested(tfm);
bool cleanup = true;
int rc; int rc;
/* /*
@ -1088,17 +1057,15 @@ static int ctr_paes_crypt(struct skcipher_request *req)
if (rc == 0 || rc == -EKEYEXPIRED) { if (rc == 0 || rc == -EKEYEXPIRED) {
atomic_inc(&ctx->via_engine_ctr); atomic_inc(&ctx->via_engine_ctr);
rc = crypto_transfer_skcipher_request_to_engine(paes_crypto_engine, req); rc = crypto_transfer_skcipher_request_to_engine(paes_crypto_engine, req);
if (rc == -EINPROGRESS || rc == -EBUSY) if (rc != -EINPROGRESS)
cleanup = false;
else
atomic_dec(&ctx->via_engine_ctr); atomic_dec(&ctx->via_engine_ctr);
} }
if (cleanup && walk->nbytes) if (rc != -EINPROGRESS)
skcipher_walk_done(walk, rc); skcipher_walk_done(walk, rc);
out: out:
if (cleanup) if (rc != -EINPROGRESS)
memzero_explicit(&req_ctx->param, sizeof(req_ctx->param)); memzero_explicit(&req_ctx->param, sizeof(req_ctx->param));
pr_debug("rc=%d\n", rc); pr_debug("rc=%d\n", rc);
return rc; return rc;
@ -1138,7 +1105,7 @@ static int ctr_paes_do_one_request(struct crypto_engine *engine, void *areq)
rc = ctr_paes_do_crypt(ctx, req_ctx, tested, true); rc = ctr_paes_do_crypt(ctx, req_ctx, tested, true);
if (rc == -EKEYEXPIRED) { if (rc == -EKEYEXPIRED) {
return pkey_handle_expired(); return pkey_handle_expired();
} else if (rc && walk->nbytes) { } else if (rc) {
skcipher_walk_done(walk, rc); skcipher_walk_done(walk, rc);
} }
@ -1148,7 +1115,7 @@ static int ctr_paes_do_one_request(struct crypto_engine *engine, void *areq)
atomic_dec(&ctx->via_engine_ctr); atomic_dec(&ctx->via_engine_ctr);
crypto_finalize_skcipher_request(engine, req, rc); crypto_finalize_skcipher_request(engine, req, rc);
local_bh_enable(); local_bh_enable();
return 0; return rc;
} }
static struct skcipher_engine_alg ctr_paes_alg = { static struct skcipher_engine_alg ctr_paes_alg = {
@ -1156,7 +1123,6 @@ static struct skcipher_engine_alg ctr_paes_alg = {
.base.cra_name = "ctr(paes)", .base.cra_name = "ctr(paes)",
.base.cra_driver_name = "ctr-paes-s390", .base.cra_driver_name = "ctr-paes-s390",
.base.cra_priority = 402, /* ecb-paes-s390 + 1 */ .base.cra_priority = 402, /* ecb-paes-s390 + 1 */
.base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NO_FALLBACK,
.base.cra_blocksize = 1, .base.cra_blocksize = 1,
.base.cra_ctxsize = sizeof(struct s390_paes_ctx), .base.cra_ctxsize = sizeof(struct s390_paes_ctx),
.base.cra_module = THIS_MODULE, .base.cra_module = THIS_MODULE,
@ -1317,11 +1283,8 @@ static int xts_paes_do_crypt_fullkey(struct s390_pxts_ctx *ctx,
n = nbytes & ~(AES_BLOCK_SIZE - 1); n = nbytes & ~(AES_BLOCK_SIZE - 1);
k = cpacf_km(ctx->fc | req_ctx->modifier, param->key + offset, k = cpacf_km(ctx->fc | req_ctx->modifier, param->key + offset,
walk->dst.virt.addr, walk->src.virt.addr, n); walk->dst.virt.addr, walk->src.virt.addr, n);
if (k) { if (k)
rc = skcipher_walk_done(walk, nbytes - k); rc = skcipher_walk_done(walk, nbytes - k);
if (rc)
goto out;
}
if (k < n) { if (k < n) {
if (!maysleep) { if (!maysleep) {
rc = -EKEYEXPIRED; rc = -EKEYEXPIRED;
@ -1374,7 +1337,7 @@ static inline int __xts_2keys_prep_param(struct s390_pxts_ctx *ctx,
memcpy(param->init, pcc_param.xts, 16); memcpy(param->init, pcc_param.xts, 16);
} }
memzero_explicit(&pcc_param, sizeof(pcc_param)); memzero_explicit(pcc_param.key, sizeof(pcc_param.key));
return rc; return rc;
} }
@ -1414,11 +1377,8 @@ static int xts_paes_do_crypt_2keys(struct s390_pxts_ctx *ctx,
n = nbytes & ~(AES_BLOCK_SIZE - 1); n = nbytes & ~(AES_BLOCK_SIZE - 1);
k = cpacf_km(ctx->fc | req_ctx->modifier, param->key + offset, k = cpacf_km(ctx->fc | req_ctx->modifier, param->key + offset,
walk->dst.virt.addr, walk->src.virt.addr, n); walk->dst.virt.addr, walk->src.virt.addr, n);
if (k) { if (k)
rc = skcipher_walk_done(walk, nbytes - k); rc = skcipher_walk_done(walk, nbytes - k);
if (rc)
goto out;
}
if (k < n) { if (k < n) {
if (!maysleep) { if (!maysleep) {
rc = -EKEYEXPIRED; rc = -EKEYEXPIRED;
@ -1490,7 +1450,6 @@ static inline int xts_paes_crypt(struct skcipher_request *req, unsigned long mod
struct s390_pxts_ctx *ctx = crypto_skcipher_ctx(tfm); struct s390_pxts_ctx *ctx = crypto_skcipher_ctx(tfm);
struct skcipher_walk *walk = &req_ctx->walk; struct skcipher_walk *walk = &req_ctx->walk;
bool tested = crypto_skcipher_tested(tfm); bool tested = crypto_skcipher_tested(tfm);
bool cleanup = true;
int rc; int rc;
/* /*
@ -1522,17 +1481,15 @@ static inline int xts_paes_crypt(struct skcipher_request *req, unsigned long mod
if (rc == 0 || rc == -EKEYEXPIRED) { if (rc == 0 || rc == -EKEYEXPIRED) {
atomic_inc(&ctx->via_engine_ctr); atomic_inc(&ctx->via_engine_ctr);
rc = crypto_transfer_skcipher_request_to_engine(paes_crypto_engine, req); rc = crypto_transfer_skcipher_request_to_engine(paes_crypto_engine, req);
if (rc == -EINPROGRESS || rc == -EBUSY) if (rc != -EINPROGRESS)
cleanup = false;
else
atomic_dec(&ctx->via_engine_ctr); atomic_dec(&ctx->via_engine_ctr);
} }
if (cleanup && walk->nbytes) if (rc != -EINPROGRESS)
skcipher_walk_done(walk, rc); skcipher_walk_done(walk, rc);
out: out:
if (cleanup) if (rc != -EINPROGRESS)
memzero_explicit(&req_ctx->param, sizeof(req_ctx->param)); memzero_explicit(&req_ctx->param, sizeof(req_ctx->param));
pr_debug("rc=%d\n", rc); pr_debug("rc=%d\n", rc);
return rc; return rc;
@ -1582,7 +1539,7 @@ static int xts_paes_do_one_request(struct crypto_engine *engine, void *areq)
rc = xts_paes_do_crypt(ctx, req_ctx, tested, true); rc = xts_paes_do_crypt(ctx, req_ctx, tested, true);
if (rc == -EKEYEXPIRED) { if (rc == -EKEYEXPIRED) {
return pkey_handle_expired(); return pkey_handle_expired();
} else if (rc && walk->nbytes) { } else if (rc) {
skcipher_walk_done(walk, rc); skcipher_walk_done(walk, rc);
} }
@ -1592,7 +1549,7 @@ static int xts_paes_do_one_request(struct crypto_engine *engine, void *areq)
atomic_dec(&ctx->via_engine_ctr); atomic_dec(&ctx->via_engine_ctr);
crypto_finalize_skcipher_request(engine, req, rc); crypto_finalize_skcipher_request(engine, req, rc);
local_bh_enable(); local_bh_enable();
return 0; return rc;
} }
static struct skcipher_engine_alg xts_paes_alg = { static struct skcipher_engine_alg xts_paes_alg = {
@ -1600,7 +1557,6 @@ static struct skcipher_engine_alg xts_paes_alg = {
.base.cra_name = "xts(paes)", .base.cra_name = "xts(paes)",
.base.cra_driver_name = "xts-paes-s390", .base.cra_driver_name = "xts-paes-s390",
.base.cra_priority = 402, /* ecb-paes-s390 + 1 */ .base.cra_priority = 402, /* ecb-paes-s390 + 1 */
.base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NO_FALLBACK,
.base.cra_blocksize = AES_BLOCK_SIZE, .base.cra_blocksize = AES_BLOCK_SIZE,
.base.cra_ctxsize = sizeof(struct s390_pxts_ctx), .base.cra_ctxsize = sizeof(struct s390_pxts_ctx),
.base.cra_module = THIS_MODULE, .base.cra_module = THIS_MODULE,

View File

@ -62,10 +62,8 @@ static inline int hwh_prepare(struct ahash_request *req,
*/ */
static inline int hwh_advance(struct hash_walk_helper *hwh, int n) static inline int hwh_advance(struct hash_walk_helper *hwh, int n)
{ {
if (n < 0) { if (n < 0)
hwh->walkbytes = n;
return crypto_hash_walk_done(&hwh->walk, n); return crypto_hash_walk_done(&hwh->walk, n);
}
hwh->walkbytes -= n; hwh->walkbytes -= n;
hwh->walkaddr += n; hwh->walkaddr += n;
@ -341,10 +339,6 @@ static inline int convert_key(const u8 *key, unsigned int keylen,
xflags); xflags);
} }
/* But finally map -EBUSY to -EIO to indicate an IO failure */
if (rc == -EBUSY)
rc = -EIO;
out: out:
pr_debug("rc=%d\n", rc); pr_debug("rc=%d\n", rc);
return rc; return rc;
@ -612,7 +606,6 @@ static int phmac_update(struct ahash_request *req)
struct phmac_tfm_ctx *tfm_ctx = crypto_ahash_ctx(tfm); struct phmac_tfm_ctx *tfm_ctx = crypto_ahash_ctx(tfm);
struct kmac_sha2_ctx *kmac_ctx = &req_ctx->kmac_ctx; struct kmac_sha2_ctx *kmac_ctx = &req_ctx->kmac_ctx;
struct hash_walk_helper *hwh = &req_ctx->hwh; struct hash_walk_helper *hwh = &req_ctx->hwh;
bool cleanup = true;
int rc; int rc;
/* prep the walk in the request context */ /* prep the walk in the request context */
@ -636,15 +629,12 @@ static int phmac_update(struct ahash_request *req)
req_ctx->async_op = OP_UPDATE; req_ctx->async_op = OP_UPDATE;
atomic_inc(&tfm_ctx->via_engine_ctr); atomic_inc(&tfm_ctx->via_engine_ctr);
rc = crypto_transfer_hash_request_to_engine(phmac_crypto_engine, req); rc = crypto_transfer_hash_request_to_engine(phmac_crypto_engine, req);
if (rc == -EINPROGRESS || rc == -EBUSY) if (rc != -EINPROGRESS)
cleanup = false;
else
atomic_dec(&tfm_ctx->via_engine_ctr); atomic_dec(&tfm_ctx->via_engine_ctr);
} }
if (cleanup) { if (rc != -EINPROGRESS) {
if (hwh->walkbytes > 0) hwh_advance(hwh, rc);
hwh_advance(hwh, rc);
memzero_explicit(kmac_ctx, sizeof(*kmac_ctx)); memzero_explicit(kmac_ctx, sizeof(*kmac_ctx));
} }
@ -659,7 +649,6 @@ static int phmac_final(struct ahash_request *req)
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
struct phmac_tfm_ctx *tfm_ctx = crypto_ahash_ctx(tfm); struct phmac_tfm_ctx *tfm_ctx = crypto_ahash_ctx(tfm);
struct kmac_sha2_ctx *kmac_ctx = &req_ctx->kmac_ctx; struct kmac_sha2_ctx *kmac_ctx = &req_ctx->kmac_ctx;
bool cleanup = true;
int rc = 0; int rc = 0;
/* Try synchronous operation if no active engine usage */ /* Try synchronous operation if no active engine usage */
@ -678,14 +667,12 @@ static int phmac_final(struct ahash_request *req)
req_ctx->async_op = OP_FINAL; req_ctx->async_op = OP_FINAL;
atomic_inc(&tfm_ctx->via_engine_ctr); atomic_inc(&tfm_ctx->via_engine_ctr);
rc = crypto_transfer_hash_request_to_engine(phmac_crypto_engine, req); rc = crypto_transfer_hash_request_to_engine(phmac_crypto_engine, req);
if (rc == -EINPROGRESS || rc == -EBUSY) if (rc != -EINPROGRESS)
cleanup = false;
else
atomic_dec(&tfm_ctx->via_engine_ctr); atomic_dec(&tfm_ctx->via_engine_ctr);
} }
out: out:
if (cleanup) if (rc != -EINPROGRESS)
memzero_explicit(kmac_ctx, sizeof(*kmac_ctx)); memzero_explicit(kmac_ctx, sizeof(*kmac_ctx));
pr_debug("rc=%d\n", rc); pr_debug("rc=%d\n", rc);
return rc; return rc;
@ -698,7 +685,6 @@ static int phmac_finup(struct ahash_request *req)
struct phmac_tfm_ctx *tfm_ctx = crypto_ahash_ctx(tfm); struct phmac_tfm_ctx *tfm_ctx = crypto_ahash_ctx(tfm);
struct kmac_sha2_ctx *kmac_ctx = &req_ctx->kmac_ctx; struct kmac_sha2_ctx *kmac_ctx = &req_ctx->kmac_ctx;
struct hash_walk_helper *hwh = &req_ctx->hwh; struct hash_walk_helper *hwh = &req_ctx->hwh;
bool cleanup = true;
int rc; int rc;
/* prep the walk in the request context */ /* prep the walk in the request context */
@ -730,17 +716,15 @@ static int phmac_finup(struct ahash_request *req)
/* req->async_op has been set to either OP_FINUP or OP_FINAL */ /* req->async_op has been set to either OP_FINUP or OP_FINAL */
atomic_inc(&tfm_ctx->via_engine_ctr); atomic_inc(&tfm_ctx->via_engine_ctr);
rc = crypto_transfer_hash_request_to_engine(phmac_crypto_engine, req); rc = crypto_transfer_hash_request_to_engine(phmac_crypto_engine, req);
if (rc == -EINPROGRESS || rc == -EBUSY) if (rc != -EINPROGRESS)
cleanup = false;
else
atomic_dec(&tfm_ctx->via_engine_ctr); atomic_dec(&tfm_ctx->via_engine_ctr);
} }
if (cleanup && hwh->walkbytes > 0) if (rc != -EINPROGRESS)
hwh_advance(hwh, rc); hwh_advance(hwh, rc);
out: out:
if (cleanup) if (rc != -EINPROGRESS)
memzero_explicit(kmac_ctx, sizeof(*kmac_ctx)); memzero_explicit(kmac_ctx, sizeof(*kmac_ctx));
pr_debug("rc=%d\n", rc); pr_debug("rc=%d\n", rc);
return rc; return rc;
@ -930,7 +914,7 @@ static int phmac_do_one_request(struct crypto_engine *engine, void *areq)
atomic_dec(&tfm_ctx->via_engine_ctr); atomic_dec(&tfm_ctx->via_engine_ctr);
crypto_finalize_hash_request(engine, req, rc); crypto_finalize_hash_request(engine, req, rc);
local_bh_enable(); local_bh_enable();
return 0; return rc;
} }
#define S390_ASYNC_PHMAC_ALG(x) \ #define S390_ASYNC_PHMAC_ALG(x) \

View File

@ -301,7 +301,6 @@ static __always_inline void __cpacf_query(unsigned int opcode,
cpacf_mask_t *mask) cpacf_mask_t *mask)
{ {
__cpacf_query_insn(opcode, mask, CPACF_FC_QUERY); __cpacf_query_insn(opcode, mask, CPACF_FC_QUERY);
kmsan_unpoison_memory(mask, sizeof(*mask));
} }
static __always_inline int __cpacf_check_opcode(unsigned int opcode) static __always_inline int __cpacf_check_opcode(unsigned int opcode)
@ -371,7 +370,6 @@ static __always_inline int cpacf_query_func(unsigned int opcode,
static __always_inline void __cpacf_qai(unsigned int opcode, cpacf_qai_t *qai) static __always_inline void __cpacf_qai(unsigned int opcode, cpacf_qai_t *qai)
{ {
__cpacf_query_insn(opcode, qai, CPACF_FC_QUERY_AUTH_INFO); __cpacf_query_insn(opcode, qai, CPACF_FC_QUERY_AUTH_INFO);
kmsan_unpoison_memory(qai, sizeof(*qai));
} }
/** /**
@ -424,7 +422,6 @@ static inline int cpacf_km(unsigned long func, void *param,
[opc] "i" (CPACF_KM) [opc] "i" (CPACF_KM)
: "cc", "memory", "0", "1"); : "cc", "memory", "0", "1");
kmsan_unpoison_memory(dest, src_len - s.odd);
return src_len - s.odd; return src_len - s.odd;
} }
@ -457,7 +454,6 @@ static inline int cpacf_kmc(unsigned long func, void *param,
[opc] "i" (CPACF_KMC) [opc] "i" (CPACF_KMC)
: "cc", "memory", "0", "1"); : "cc", "memory", "0", "1");
kmsan_unpoison_memory(dest, src_len - s.odd);
return src_len - s.odd; return src_len - s.odd;
} }
@ -591,7 +587,6 @@ static inline int cpacf_kmctr(unsigned long func, void *param, u8 *dest,
[opc] "i" (CPACF_KMCTR) [opc] "i" (CPACF_KMCTR)
: "cc", "memory", "0", "1"); : "cc", "memory", "0", "1");
kmsan_unpoison_memory(dest, src_len - s.odd);
return src_len - s.odd; return src_len - s.odd;
} }
@ -624,7 +619,6 @@ static inline void cpacf_prno(unsigned long func, void *param,
: [fc] "d" (func), [pba] "d" ((unsigned long)param), : [fc] "d" (func), [pba] "d" ((unsigned long)param),
[seed] "d" (s.pair), [opc] "i" (CPACF_PRNO) [seed] "d" (s.pair), [opc] "i" (CPACF_PRNO)
: "cc", "memory", "0", "1"); : "cc", "memory", "0", "1");
kmsan_unpoison_memory(dest, dest_len);
} }
/** /**

View File

@ -76,6 +76,7 @@ static __always_inline void pai_kernel_exit(struct pt_regs *regs)
} }
#define PAI_SAVE_AREA(x) ((x)->hw.event_base) #define PAI_SAVE_AREA(x) ((x)->hw.event_base)
#define PAI_CPU_MASK(x) ((x)->hw.addr_filters)
#define PAI_PMU_IDX(x) ((x)->hw.last_tag) #define PAI_PMU_IDX(x) ((x)->hw.last_tag)
#define PAI_SWLIST(x) (&(x)->hw.tp_list) #define PAI_SWLIST(x) (&(x)->hw.tp_list)

View File

@ -46,6 +46,7 @@ struct pcpu {
unsigned long ec_mask; /* bit mask for ec_xxx functions */ unsigned long ec_mask; /* bit mask for ec_xxx functions */
unsigned long ec_clk; /* sigp timestamp for ec_xxx */ unsigned long ec_clk; /* sigp timestamp for ec_xxx */
unsigned long flags; /* per CPU flags */ unsigned long flags; /* per CPU flags */
unsigned long capacity; /* cpu capacity for scheduler */
signed char state; /* physical cpu state */ signed char state; /* physical cpu state */
signed char polarization; /* physical polarization */ signed char polarization; /* physical polarization */
u16 address; /* physical cpu address */ u16 address; /* physical cpu address */

View File

@ -30,7 +30,7 @@ static __always_inline unsigned int raw_smp_processor_id(void)
return cpu; return cpu;
} }
#define arch_scale_cpu_capacity topology_get_cpu_scale #define arch_scale_cpu_capacity smp_cpu_get_capacity
extern struct mutex smp_cpu_state_mutex; extern struct mutex smp_cpu_state_mutex;
extern unsigned int smp_cpu_mt_shift; extern unsigned int smp_cpu_mt_shift;
@ -53,7 +53,9 @@ extern void smp_save_dump_secondary_cpus(void);
extern void smp_yield_cpu(int cpu); extern void smp_yield_cpu(int cpu);
extern void smp_cpu_set_polarization(int cpu, int val); extern void smp_cpu_set_polarization(int cpu, int val);
extern int smp_cpu_get_polarization(int cpu); extern int smp_cpu_get_polarization(int cpu);
extern void smp_cpu_set_capacity(int cpu, unsigned long val);
extern void smp_set_core_capacity(int cpu, unsigned long val); extern void smp_set_core_capacity(int cpu, unsigned long val);
extern unsigned long smp_cpu_get_capacity(int cpu);
extern int smp_cpu_get_cpu_address(int cpu); extern int smp_cpu_get_cpu_address(int cpu);
extern void smp_fill_possible_mask(void); extern void smp_fill_possible_mask(void);
extern void smp_detect_cpus(void); extern void smp_detect_cpus(void);

View File

@ -182,7 +182,7 @@ static struct debug_param_t {
static int debug_param_num; static int debug_param_num;
/* functions */ /* functions */
static void debug_get_param(const char *name, int *level, int *pages, bool quiet) static void debug_get_param(const char *name, int *level, int *pages)
{ {
struct debug_param_t *p; struct debug_param_t *p;
int i; int i;
@ -192,13 +192,11 @@ static void debug_get_param(const char *name, int *level, int *pages, bool quiet
if (!glob_match(p->name, name)) if (!glob_match(p->name, name))
continue; continue;
if (level && p->level != PARAM_UNSET) { if (level && p->level != PARAM_UNSET) {
if (!quiet) pr_info("%s: override level to %d\n", name, p->level);
pr_info("%s: override level to %d\n", name, p->level);
*level = p->level; *level = p->level;
} }
if (pages && p->pages != PARAM_UNSET) { if (pages && p->pages != PARAM_UNSET) {
if (!quiet) pr_info("%s: override pages to %d\n", name, p->pages);
pr_info("%s: override pages to %d\n", name, p->pages);
*pages = p->pages; *pages = p->pages;
} }
} }
@ -253,7 +251,7 @@ static int __init s390dbf_parse(char *arg)
* regular memory allocations are possible. * regular memory allocations are possible.
*/ */
for (i = 0, id = __s390dbf_info; &id[i] < __s390dbf_info_end; i++) for (i = 0, id = __s390dbf_info; &id[i] < __s390dbf_info_end; i++)
debug_get_param(id[i]->name, &id[i]->level, NULL, false); debug_get_param(id[i]->name, &id[i]->level, NULL);
return rc; return rc;
} }
@ -397,7 +395,7 @@ static debug_info_t *debug_info_create(const char *name, int pages_per_area,
int level = DEBUG_DEFAULT_LEVEL; int level = DEBUG_DEFAULT_LEVEL;
debug_info_t *rc; debug_info_t *rc;
debug_get_param(name, &level, &pages_per_area, false); debug_get_param(name, &level, &pages_per_area);
rc = debug_info_alloc(name, pages_per_area, nr_areas, buf_size, level, ALL_AREAS); rc = debug_info_alloc(name, pages_per_area, nr_areas, buf_size, level, ALL_AREAS);
if (!rc) if (!rc)
goto out; goto out;
@ -962,7 +960,7 @@ void debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas)
return; return;
} }
debug_get_param(id->name, &id->level, &pages_per_area, false); debug_get_param(id->name, &id->level, &pages_per_area);
copy = debug_info_alloc("", pages_per_area, nr_areas, id->buf_size, copy = debug_info_alloc("", pages_per_area, nr_areas, id->buf_size,
id->level, ALL_AREAS); id->level, ALL_AREAS);
if (!copy) { if (!copy) {
@ -1076,6 +1074,9 @@ static void _debug_set_level(debug_info_t *id, int new_level)
{ {
unsigned long flags; unsigned long flags;
if (!id)
return;
if (new_level == DEBUG_OFF_LEVEL) { if (new_level == DEBUG_OFF_LEVEL) {
pr_info("%s: switched off\n", id->name); pr_info("%s: switched off\n", id->name);
} else if ((new_level > DEBUG_MAX_LEVEL) || (new_level < 0)) { } else if ((new_level > DEBUG_MAX_LEVEL) || (new_level < 0)) {
@ -1100,14 +1101,8 @@ static void _debug_set_level(debug_info_t *id, int new_level)
*/ */
void debug_set_level(debug_info_t *id, int new_level) void debug_set_level(debug_info_t *id, int new_level)
{ {
if (!id) /* Level specified via kernel parameter takes precedence */
return; debug_get_param(id->name, &new_level, NULL);
/*
* Level specified via kernel parameter takes precedence. The override
* was already announced during registration, so stay quiet here.
*/
debug_get_param(id->name, &new_level, NULL, true);
_debug_set_level(id, new_level); _debug_set_level(id, new_level);
} }
@ -1283,7 +1278,7 @@ void debug_set_critical(void)
debug_entry_t *debug_event_common(debug_info_t *id, int level, const void *buf, debug_entry_t *debug_event_common(debug_info_t *id, int level, const void *buf,
int len) int len)
{ {
debug_entry_t *active = NULL; debug_entry_t *active;
unsigned long flags; unsigned long flags;
if (!debug_active || !id->areas) if (!debug_active || !id->areas)
@ -1294,8 +1289,6 @@ debug_entry_t *debug_event_common(debug_info_t *id, int level, const void *buf,
} else { } else {
raw_spin_lock_irqsave(&id->lock, flags); raw_spin_lock_irqsave(&id->lock, flags);
} }
if (!id->areas)
goto out;
do { do {
active = get_active_entry(id); active = get_active_entry(id);
memcpy(DEBUG_DATA(active), buf, min(len, id->buf_size)); memcpy(DEBUG_DATA(active), buf, min(len, id->buf_size));
@ -1305,7 +1298,7 @@ debug_entry_t *debug_event_common(debug_info_t *id, int level, const void *buf,
len -= id->buf_size; len -= id->buf_size;
buf += id->buf_size; buf += id->buf_size;
} while (len > 0); } while (len > 0);
out:
raw_spin_unlock_irqrestore(&id->lock, flags); raw_spin_unlock_irqrestore(&id->lock, flags);
return active; return active;
} }
@ -1318,7 +1311,7 @@ EXPORT_SYMBOL(debug_event_common);
debug_entry_t *debug_exception_common(debug_info_t *id, int level, debug_entry_t *debug_exception_common(debug_info_t *id, int level,
const void *buf, int len) const void *buf, int len)
{ {
debug_entry_t *active = NULL; debug_entry_t *active;
unsigned long flags; unsigned long flags;
if (!debug_active || !id->areas) if (!debug_active || !id->areas)
@ -1329,8 +1322,6 @@ debug_entry_t *debug_exception_common(debug_info_t *id, int level,
} else { } else {
raw_spin_lock_irqsave(&id->lock, flags); raw_spin_lock_irqsave(&id->lock, flags);
} }
if (!id->areas)
goto out;
do { do {
active = get_active_entry(id); active = get_active_entry(id);
memcpy(DEBUG_DATA(active), buf, min(len, id->buf_size)); memcpy(DEBUG_DATA(active), buf, min(len, id->buf_size));
@ -1340,7 +1331,7 @@ debug_entry_t *debug_exception_common(debug_info_t *id, int level,
len -= id->buf_size; len -= id->buf_size;
buf += id->buf_size; buf += id->buf_size;
} while (len > 0); } while (len > 0);
out:
raw_spin_unlock_irqrestore(&id->lock, flags); raw_spin_unlock_irqrestore(&id->lock, flags);
return active; return active;
} }
@ -1366,7 +1357,7 @@ static inline int debug_count_numargs(char *string)
debug_entry_t *__debug_sprintf_event(debug_info_t *id, int level, char *string, ...) debug_entry_t *__debug_sprintf_event(debug_info_t *id, int level, char *string, ...)
{ {
debug_sprintf_entry_t *curr_event; debug_sprintf_entry_t *curr_event;
debug_entry_t *active = NULL; debug_entry_t *active;
unsigned long flags; unsigned long flags;
int numargs, idx; int numargs, idx;
va_list ap; va_list ap;
@ -1381,8 +1372,6 @@ debug_entry_t *__debug_sprintf_event(debug_info_t *id, int level, char *string,
} else { } else {
raw_spin_lock_irqsave(&id->lock, flags); raw_spin_lock_irqsave(&id->lock, flags);
} }
if (!id->areas)
goto out;
active = get_active_entry(id); active = get_active_entry(id);
curr_event = (debug_sprintf_entry_t *) DEBUG_DATA(active); curr_event = (debug_sprintf_entry_t *) DEBUG_DATA(active);
va_start(ap, string); va_start(ap, string);
@ -1391,7 +1380,6 @@ debug_entry_t *__debug_sprintf_event(debug_info_t *id, int level, char *string,
curr_event->args[idx] = va_arg(ap, long); curr_event->args[idx] = va_arg(ap, long);
va_end(ap); va_end(ap);
debug_finish_entry(id, active, level, 0); debug_finish_entry(id, active, level, 0);
out:
raw_spin_unlock_irqrestore(&id->lock, flags); raw_spin_unlock_irqrestore(&id->lock, flags);
return active; return active;
@ -1404,7 +1392,7 @@ EXPORT_SYMBOL(__debug_sprintf_event);
debug_entry_t *__debug_sprintf_exception(debug_info_t *id, int level, char *string, ...) debug_entry_t *__debug_sprintf_exception(debug_info_t *id, int level, char *string, ...)
{ {
debug_sprintf_entry_t *curr_event; debug_sprintf_entry_t *curr_event;
debug_entry_t *active = NULL; debug_entry_t *active;
unsigned long flags; unsigned long flags;
int numargs, idx; int numargs, idx;
va_list ap; va_list ap;
@ -1420,8 +1408,6 @@ debug_entry_t *__debug_sprintf_exception(debug_info_t *id, int level, char *stri
} else { } else {
raw_spin_lock_irqsave(&id->lock, flags); raw_spin_lock_irqsave(&id->lock, flags);
} }
if (!id->areas)
goto out;
active = get_active_entry(id); active = get_active_entry(id);
curr_event = (debug_sprintf_entry_t *)DEBUG_DATA(active); curr_event = (debug_sprintf_entry_t *)DEBUG_DATA(active);
va_start(ap, string); va_start(ap, string);
@ -1430,7 +1416,6 @@ debug_entry_t *__debug_sprintf_exception(debug_info_t *id, int level, char *stri
curr_event->args[idx] = va_arg(ap, long); curr_event->args[idx] = va_arg(ap, long);
va_end(ap); va_end(ap);
debug_finish_entry(id, active, level, 1); debug_finish_entry(id, active, level, 1);
out:
raw_spin_unlock_irqrestore(&id->lock, flags); raw_spin_unlock_irqrestore(&id->lock, flags);
return active; return active;
@ -1673,11 +1658,9 @@ static void debug_flush(debug_info_t *id, int area)
unsigned long flags; unsigned long flags;
int i, j; int i, j;
if (!id) if (!id || !id->areas)
return; return;
raw_spin_lock_irqsave(&id->lock, flags); raw_spin_lock_irqsave(&id->lock, flags);
if (!id->areas)
goto out;
if (area == DEBUG_FLUSH_ALL) { if (area == DEBUG_FLUSH_ALL) {
id->active_area = 0; id->active_area = 0;
memset(id->active_entries, 0, id->nr_areas * sizeof(int)); memset(id->active_entries, 0, id->nr_areas * sizeof(int));
@ -1692,7 +1675,6 @@ static void debug_flush(debug_info_t *id, int area)
for (i = 0; i < id->pages_per_area; i++) for (i = 0; i < id->pages_per_area; i++)
memset(id->areas[area][i], 0, PAGE_SIZE); memset(id->areas[area][i], 0, PAGE_SIZE);
} }
out:
raw_spin_unlock_irqrestore(&id->lock, flags); raw_spin_unlock_irqrestore(&id->lock, flags);
} }

View File

@ -182,7 +182,8 @@ long diag324_pibbuf(unsigned long arg)
goto out; goto out;
rc = copy_to_user((void __user *)address, data->pib, data->pib->len); rc = copy_to_user((void __user *)address, data->pib, data->pib->len);
rc |= put_user(data->sequence, &udata->sequence); rc |= put_user(data->sequence, &udata->sequence);
rc = rc ? -EFAULT : data->rc; if (rc)
rc = -EFAULT;
out: out:
mutex_unlock(&pibmutex); mutex_unlock(&pibmutex);
return rc; return rc;

View File

@ -1157,8 +1157,6 @@ static struct attribute_group reipl_nss_attr_group = {
void set_os_info_reipl_block(void) void set_os_info_reipl_block(void)
{ {
if (!reipl_block_actual)
return;
os_info_entry_add_data(OS_INFO_REIPL_BLOCK, reipl_block_actual, os_info_entry_add_data(OS_INFO_REIPL_BLOCK, reipl_block_actual,
reipl_block_actual->hdr.len); reipl_block_actual->hdr.len);
} }
@ -1929,8 +1927,7 @@ static struct shutdown_action __refdata dump_action = {
static void dump_reipl_run(struct shutdown_trigger *trigger) static void dump_reipl_run(struct shutdown_trigger *trigger)
{ {
struct lowcore *abs_lc; struct lowcore *abs_lc;
unsigned long ipib = 0; unsigned int csum;
unsigned int csum = 0;
/* /*
* Set REIPL_CLEAR flag in os_info flags entry indicating * Set REIPL_CLEAR flag in os_info flags entry indicating
@ -1946,12 +1943,9 @@ static void dump_reipl_run(struct shutdown_trigger *trigger)
reipl_type == IPL_TYPE_UNKNOWN) reipl_type == IPL_TYPE_UNKNOWN)
os_info_flags |= OS_INFO_FLAG_REIPL_CLEAR; os_info_flags |= OS_INFO_FLAG_REIPL_CLEAR;
os_info_entry_add_data(OS_INFO_FLAGS_ENTRY, &os_info_flags, sizeof(os_info_flags)); os_info_entry_add_data(OS_INFO_FLAGS_ENTRY, &os_info_flags, sizeof(os_info_flags));
if (reipl_block_actual) { csum = (__force unsigned int)cksm(reipl_block_actual, reipl_block_actual->hdr.len, 0);
ipib = __pa(reipl_block_actual);
csum = (__force unsigned int)cksm(reipl_block_actual, reipl_block_actual->hdr.len, 0);
}
abs_lc = get_abs_lowcore(); abs_lc = get_abs_lowcore();
abs_lc->ipib = ipib; abs_lc->ipib = __pa(reipl_block_actual);
abs_lc->ipib_checksum = csum; abs_lc->ipib_checksum = csum;
put_abs_lowcore(abs_lc); put_abs_lowcore(abs_lc);
dump_run(trigger); dump_run(trigger);

View File

@ -67,7 +67,6 @@ struct pai_mapptr {
static struct pai_root { /* Anchor to per CPU data */ static struct pai_root { /* Anchor to per CPU data */
refcount_t refcnt; /* Overall active events */ refcount_t refcnt; /* Overall active events */
atomic_t tskctx; /* Overall per-task events */
struct pai_mapptr __percpu *mapptr; struct pai_mapptr __percpu *mapptr;
} pai_root[PAI_PMU_MAX]; } pai_root[PAI_PMU_MAX];
@ -94,15 +93,14 @@ struct pai_pmu { /* Define PAI PMU characteristics */
static struct pai_pmu pai_pmu[]; /* Forward declaration */ static struct pai_pmu pai_pmu[]; /* Forward declaration */
/* Free per CPU data when the last event is removed. */ /* Free per CPU data when the last event is removed. */
static void pai_root_free(int idx, int tasks) static void pai_root_free(int idx)
{ {
if (refcount_sub_and_test(tasks, &pai_root[idx].refcnt)) { if (refcount_dec_and_test(&pai_root[idx].refcnt)) {
free_percpu(pai_root[idx].mapptr); free_percpu(pai_root[idx].mapptr);
pai_root[idx].mapptr = NULL; pai_root[idx].mapptr = NULL;
} }
debug_sprintf_event(paidbg, 5, "%s root[%d].refcount %d tskctx %d\n", debug_sprintf_event(paidbg, 5, "%s root[%d].refcount %d\n", __func__,
__func__, idx, refcount_read(&pai_root[idx].refcnt), idx, refcount_read(&pai_root[idx].refcnt));
atomic_read(&pai_root[idx].tskctx));
} }
/* /*
@ -139,54 +137,40 @@ static void pai_free(struct pai_mapptr *mp)
mp->mapptr = NULL; mp->mapptr = NULL;
} }
/* Called under mutex_lock */ /* Adjust usage counters and remove allocated memory when all users are
static void pai_event_destroy_cpu(int idx, int cpu, bool hotplug) * gone.
*/
static void pai_event_destroy_cpu(struct perf_event *event, int cpu)
{ {
struct pai_mapptr *mp; int idx = PAI_PMU_IDX(event);
struct pai_map *cpump; struct pai_mapptr *mp = per_cpu_ptr(pai_root[idx].mapptr, cpu);
int tasks = 1; struct pai_map *cpump = mp->mapptr;
/* Check reference count and return when all gone. mutex_lock(&pai_reserve_mutex);
* 1. An event is installed on online CPU X. debug_sprintf_event(paidbg, 5, "%s event %#llx idx %d cpu %d users %d "
* 2. CPU x is offlined and the per-CPU data is removed. "refcnt %u\n", __func__, event->attr.config, idx,
* 3. Event is destroyed via close system call. event->cpu, cpump->active_events,
*/ refcount_read(&cpump->refcnt));
if (!refcount_read(&pai_root[idx].refcnt)) if (refcount_dec_and_test(&cpump->refcnt))
return; /* No events at all */
mp = per_cpu_ptr(pai_root[idx].mapptr, cpu);
if (!mp || !mp->mapptr) /* No events on that CPU */
return;
/* When hotplug is true, invocation is from CPU hotplug callback.
* Delete per-CPU resource and adjust refcnt when per-task events
* are currently active. This can be more than one.
* In this case adjust counters.
*/
if (hotplug)
tasks = atomic_read(&pai_root[idx].tskctx);
cpump = mp->mapptr;
if (refcount_sub_and_test(tasks, &cpump->refcnt))
pai_free(mp); pai_free(mp);
pai_root_free(idx, tasks); pai_root_free(idx);
mutex_unlock(&pai_reserve_mutex);
} }
static void pai_event_destroy(struct perf_event *event) static void pai_event_destroy(struct perf_event *event)
{ {
int cpu = 0, idx = PAI_PMU_IDX(event); int cpu;
free_page(PAI_SAVE_AREA(event)); free_page(PAI_SAVE_AREA(event));
cpus_read_lock();
mutex_lock(&pai_reserve_mutex);
if (event->cpu == -1) { if (event->cpu == -1) {
atomic_dec(&pai_root[idx].tskctx); struct cpumask *mask = PAI_CPU_MASK(event);
for_each_online_cpu(cpu)
pai_event_destroy_cpu(idx, cpu, false); for_each_cpu(cpu, mask)
pai_event_destroy_cpu(event, cpu);
kfree(mask);
} else { } else {
pai_event_destroy_cpu(idx, event->cpu, false); pai_event_destroy_cpu(event, event->cpu);
} }
mutex_unlock(&pai_reserve_mutex);
cpus_read_unlock();
} }
static void paicrypt_event_destroy(struct perf_event *event) static void paicrypt_event_destroy(struct perf_event *event)
@ -250,30 +234,25 @@ static u64 paicrypt_getall(struct perf_event *event)
return sum; return sum;
} }
/* Called under mutex_lock */ /* Check concurrent access of counting and sampling for crypto events.
static int pai_alloc_cpu(int idx, int cpu, bool hotplug) * This function is called in process context and it is save to block.
* When the event initialization functions fails, no other call back will
* be invoked.
*
* Allocate the memory for the event.
*/
static int pai_alloc_cpu(struct perf_event *event, int cpu)
{ {
int rc, idx = PAI_PMU_IDX(event);
struct pai_map *cpump = NULL; struct pai_map *cpump = NULL;
bool need_paiext_cb = false; bool need_paiext_cb = false;
struct pai_mapptr *mp; struct pai_mapptr *mp;
int tasks = 1, rc = 0;
/* When hotplug is true, invocation is from CPU hotplug callback.
* Allocate per-CPU resource when per-task events are currently active.
* This can be more than one. In this case adjust all reference
* counters. Otherwise return, this ensures memory is only allocated
* when needed.
*/
if (hotplug) {
tasks = atomic_read(&pai_root[idx].tskctx);
if (!tasks)
goto out;
}
mutex_lock(&pai_reserve_mutex);
/* Allocate root node */ /* Allocate root node */
rc = pai_root_alloc(idx); rc = pai_root_alloc(idx);
if (rc) if (rc)
goto out; goto unlock;
/* Allocate node for this event */ /* Allocate node for this event */
mp = per_cpu_ptr(pai_root[idx].mapptr, cpu); mp = per_cpu_ptr(pai_root[idx].mapptr, cpu);
@ -317,45 +296,28 @@ static int pai_alloc_cpu(int idx, int cpu, bool hotplug)
goto undo; goto undo;
} }
INIT_LIST_HEAD(&cpump->syswide_list); INIT_LIST_HEAD(&cpump->syswide_list);
refcount_set(&cpump->refcnt, tasks); refcount_set(&cpump->refcnt, 1);
rc = 0; rc = 0;
} else { } else {
refcount_add(tasks, &cpump->refcnt); refcount_inc(&cpump->refcnt);
} }
/* If tasks is greater than 1, we are called from CPU hotplug path
* and need to adjust the pai_root[idx].refcnt by the number of
* per-process events. Function pai_root_alloc(idx) already
* incremented by one. Adjust for the rest.
*/
if (tasks > 1)
refcount_add(tasks - 1, &pai_root[idx].refcnt);
undo: undo:
if (rc) { if (rc) {
/* Error in allocation of event, decrement anchor. Since /* Error in allocation of event, decrement anchor. Since
* the event in not created, its destroy() function is never * the event in not created, its destroy() function is never
* invoked. Adjust the reference counter for the anchor. * invoked. Adjust the reference counter for the anchor.
* The failure happened in the case of variable
* cpump == NULL branch above. The pai_root[XXX].refcnt has
* been incremented by one. Then the per-CPU allocation
* failed, so decrement it by one, regardless of tasks.
*/ */
pai_root_free(idx, 1); pai_root_free(idx);
} }
out: unlock:
mutex_unlock(&pai_reserve_mutex);
/* If rc is non-zero, no increment of counter/sampler was done. */ /* If rc is non-zero, no increment of counter/sampler was done. */
return rc; return rc;
} }
/* Check concurrent access of counting and sampling for PAI events.
* This function is called in process context and it is safe to block.
* When the event initialization functions fails, no other call back will
* be invoked.
* Called under mutex_lock.
*/
static int pai_alloc(struct perf_event *event) static int pai_alloc(struct perf_event *event)
{ {
int idx = PAI_PMU_IDX(event);
struct cpumask *maskptr; struct cpumask *maskptr;
int cpu, rc = -ENOMEM; int cpu, rc = -ENOMEM;
@ -364,20 +326,24 @@ static int pai_alloc(struct perf_event *event)
goto out; goto out;
for_each_online_cpu(cpu) { for_each_online_cpu(cpu) {
rc = pai_alloc_cpu(idx, cpu, false); rc = pai_alloc_cpu(event, cpu);
if (rc) { if (rc) {
for_each_cpu(cpu, maskptr) for_each_cpu(cpu, maskptr)
pai_event_destroy_cpu(idx, cpu, false); pai_event_destroy_cpu(event, cpu);
goto undo; kfree(maskptr);
goto out;
} }
cpumask_set_cpu(cpu, maskptr); cpumask_set_cpu(cpu, maskptr);
} }
/*
* On error all cpumask are freed and all events have been destroyed.
* Save of which CPUs data structures have been allocated for.
* Release them in pai_event_destroy call back function
* for this event.
*/
PAI_CPU_MASK(event) = maskptr;
rc = 0; rc = 0;
/* Trace per-task events for CPU hotplug. */
atomic_inc(&pai_root[idx].tskctx);
undo:
kfree(maskptr);
out: out:
return rc; return rc;
} }
@ -425,14 +391,10 @@ static int pai_event_init(struct perf_event *event, int idx)
} }
} }
cpus_read_lock();
mutex_lock(&pai_reserve_mutex);
if (event->cpu >= 0) if (event->cpu >= 0)
rc = pai_alloc_cpu(idx, event->cpu, false); rc = pai_alloc_cpu(event, event->cpu);
else else
rc = pai_alloc(event); rc = pai_alloc(event);
mutex_unlock(&pai_reserve_mutex);
cpus_read_unlock();
if (rc) { if (rc) {
free_page(PAI_SAVE_AREA(event)); free_page(PAI_SAVE_AREA(event));
goto out; goto out;
@ -502,7 +464,6 @@ static void pai_start(struct perf_event *event, int flags,
cpump->event = event; cpump->event = event;
} }
} }
event->hw.state &= ~PERF_HES_STOPPED;
} }
static void paicrypt_start(struct perf_event *event, int flags) static void paicrypt_start(struct perf_event *event, int flags)
@ -549,13 +510,6 @@ static void pai_stop(struct perf_event *event, int flags)
struct pai_mapptr *mp = this_cpu_ptr(pai_root[idx].mapptr); struct pai_mapptr *mp = this_cpu_ptr(pai_root[idx].mapptr);
struct pai_map *cpump = mp->mapptr; struct pai_map *cpump = mp->mapptr;
/* Cope with multiple invocations:
* 1. perf_event_throttle() --> PMU->stop()
* 2. task schedules out --> PMU->stop()
* Check for event already stopped.
*/
if (event->hw.state & PERF_HES_STOPPED)
return;
if (!event->attr.sample_period) { /* Counting */ if (!event->attr.sample_period) { /* Counting */
pai_pmu[idx].pmu->read(event); pai_pmu[idx].pmu->read(event);
} else { /* Sampling */ } else { /* Sampling */
@ -718,9 +672,9 @@ static void pai_have_samples(int idx)
{ {
struct pai_mapptr *mp = this_cpu_ptr(pai_root[idx].mapptr); struct pai_mapptr *mp = this_cpu_ptr(pai_root[idx].mapptr);
struct pai_map *cpump = mp->mapptr; struct pai_map *cpump = mp->mapptr;
struct perf_event *event, *e2; struct perf_event *event;
list_for_each_entry_safe(event, e2, &cpump->syswide_list, hw.tp_list) list_for_each_entry(event, &cpump->syswide_list, hw.tp_list)
pai_have_sample(event, cpump); pai_have_sample(event, cpump);
} }
@ -737,17 +691,6 @@ static void paicrypt_sched_task(struct perf_event_pmu_context *pmu_ctx,
pai_have_samples(PAI_PMU_CRYPTO); pai_have_samples(PAI_PMU_CRYPTO);
} }
/* Prevent ioctl(fd, PERF_EVENT_IOC_PERIOD, ...) call.
* It sets perf_event::event_limit to a positive value and causes
* perf_event_overflow() to invoke pai_stop() call back function when
* perf_event::event_limit hits zero. This is not supported because the
* sample events CRYPTO_ALL and NNPA_ALL are always taken at schedule out
* of a task.
*/
static int pai_check_period(struct perf_event *event, u64 value)
{
return -EINVAL;
}
/* ============================= paiext ====================================*/ /* ============================= paiext ====================================*/
static void paiext_event_destroy(struct perf_event *event) static void paiext_event_destroy(struct perf_event *event)
@ -861,7 +804,6 @@ static struct pmu paicrypt = {
.stop = paicrypt_stop, .stop = paicrypt_stop,
.read = paicrypt_read, .read = paicrypt_read,
.sched_task = paicrypt_sched_task, .sched_task = paicrypt_sched_task,
.check_period = pai_check_period,
.attr_groups = paicrypt_attr_groups .attr_groups = paicrypt_attr_groups
}; };
@ -1073,7 +1015,6 @@ static struct pmu paiext = {
.stop = paiext_stop, .stop = paiext_stop,
.read = paiext_read, .read = paiext_read,
.sched_task = paiext_sched_task, .sched_task = paiext_sched_task,
.check_period = pai_check_period,
.attr_groups = paiext_attr_groups, .attr_groups = paiext_attr_groups,
}; };
@ -1277,61 +1218,23 @@ static int __init paipmu_setup(void)
return install_ok; return install_ok;
} }
static int pai_online_cpu(unsigned int cpu)
{
int rc;
mutex_lock(&pai_reserve_mutex);
rc = pai_alloc_cpu(PAI_PMU_CRYPTO, cpu, true);
if (rc)
goto out;
rc = pai_alloc_cpu(PAI_PMU_EXT, cpu, true);
if (rc)
pai_event_destroy_cpu(PAI_PMU_CRYPTO, cpu, true);
out:
mutex_unlock(&pai_reserve_mutex);
return rc;
}
static int pai_offline_cpu(unsigned int cpu)
{
mutex_lock(&pai_reserve_mutex);
pai_event_destroy_cpu(PAI_PMU_CRYPTO, cpu, true);
pai_event_destroy_cpu(PAI_PMU_EXT, cpu, true);
mutex_unlock(&pai_reserve_mutex);
return 0;
}
static int __init pai_init(void) static int __init pai_init(void)
{ {
int state, rc;
/* Setup s390dbf facility */ /* Setup s390dbf facility */
paidbg = debug_register("pai", 1, 1, 128); paidbg = debug_register("pai", 32, 256, 128);
if (!paidbg) { if (!paidbg) {
pr_err("Registration of s390dbf pai failed\n"); pr_err("Registration of s390dbf pai failed\n");
return -ENOMEM; return -ENOMEM;
} }
debug_register_view(paidbg, &debug_sprintf_view); debug_register_view(paidbg, &debug_sprintf_view);
/* CPUHP_BP_PREPARE_DYN --> before CPU is brought online */ if (!paipmu_setup()) {
state = cpuhp_setup_state(CPUHP_BP_PREPARE_DYN, "perf/pai:prepare", /* No PMU registration, no need for debug buffer */
pai_online_cpu, pai_offline_cpu); debug_unregister_view(paidbg, &debug_sprintf_view);
rc = state < 0 ? state : 0; debug_unregister(paidbg);
if (rc < 0) return -ENODEV;
goto out_debug; }
rc = -ENODEV;
if (!paipmu_setup())
goto out_cpuhp;
return 0; return 0;
out_cpuhp:
cpuhp_remove_state(state);
out_debug:
debug_unregister_view(paidbg, &debug_sprintf_view);
debug_unregister(paidbg);
return rc;
} }
device_initcall(pai_init); device_initcall(pai_init);

View File

@ -659,13 +659,23 @@ int smp_cpu_get_polarization(int cpu)
return per_cpu(pcpu_devices, cpu).polarization; return per_cpu(pcpu_devices, cpu).polarization;
} }
void smp_cpu_set_capacity(int cpu, unsigned long val)
{
per_cpu(pcpu_devices, cpu).capacity = val;
}
unsigned long smp_cpu_get_capacity(int cpu)
{
return per_cpu(pcpu_devices, cpu).capacity;
}
void smp_set_core_capacity(int cpu, unsigned long val) void smp_set_core_capacity(int cpu, unsigned long val)
{ {
int i; int i;
cpu = smp_get_base_cpu(cpu); cpu = smp_get_base_cpu(cpu);
for (i = cpu; (i <= cpu + smp_cpu_mtid) && (i < nr_cpu_ids); i++) for (i = cpu; (i <= cpu + smp_cpu_mtid) && (i < nr_cpu_ids); i++)
topology_set_cpu_scale(i, val); smp_cpu_set_capacity(i, val);
} }
int smp_cpu_get_cpu_address(int cpu) int smp_cpu_get_cpu_address(int cpu)
@ -717,7 +727,7 @@ static int smp_add_core(struct sclp_core_entry *core, cpumask_t *avail,
else else
pcpu->state = CPU_STATE_STANDBY; pcpu->state = CPU_STATE_STANDBY;
smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
topology_set_cpu_scale(cpu, CPU_CAPACITY_HIGH); smp_cpu_set_capacity(cpu, CPU_CAPACITY_HIGH);
set_cpu_present(cpu, true); set_cpu_present(cpu, true);
if (!early && arch_register_cpu(cpu)) if (!early && arch_register_cpu(cpu))
set_cpu_present(cpu, false); set_cpu_present(cpu, false);
@ -957,7 +967,7 @@ void __init smp_prepare_boot_cpu(void)
ipl_pcpu->state = CPU_STATE_CONFIGURED; ipl_pcpu->state = CPU_STATE_CONFIGURED;
lc->pcpu = (unsigned long)ipl_pcpu; lc->pcpu = (unsigned long)ipl_pcpu;
smp_cpu_set_polarization(0, POLARIZATION_UNKNOWN); smp_cpu_set_polarization(0, POLARIZATION_UNKNOWN);
topology_set_cpu_scale(0, CPU_CAPACITY_HIGH); smp_cpu_set_capacity(0, CPU_CAPACITY_HIGH);
} }
void __init smp_setup_processor_id(void) void __init smp_setup_processor_id(void)

View File

@ -147,7 +147,7 @@ static void add_cpus_to_mask(struct topology_core *tl_core,
cpumask_set_cpu(cpu, &book->mask); cpumask_set_cpu(cpu, &book->mask);
cpumask_set_cpu(cpu, &socket->mask); cpumask_set_cpu(cpu, &socket->mask);
smp_cpu_set_polarization(cpu, tl_core->pp); smp_cpu_set_polarization(cpu, tl_core->pp);
topology_set_cpu_scale(cpu, CPU_CAPACITY_HIGH); smp_cpu_set_capacity(cpu, CPU_CAPACITY_HIGH);
} }
} }
} }

View File

@ -32,7 +32,7 @@ static atomic64_t virt_timer_elapsed;
DEFINE_PER_CPU(u64, mt_cycles[8]); DEFINE_PER_CPU(u64, mt_cycles[8]);
static DEFINE_PER_CPU(u64, mt_scaling_mult) = { 1 }; static DEFINE_PER_CPU(u64, mt_scaling_mult) = { 1 };
static DEFINE_PER_CPU(u64, mt_scaling_div) = { 1 }; static DEFINE_PER_CPU(u64, mt_scaling_div) = { 1 };
static DEFINE_PER_CPU(unsigned long, mt_scaling_jiffies); static DEFINE_PER_CPU(u64, mt_scaling_jiffies);
static inline void set_vtimer(u64 expires) static inline void set_vtimer(u64 expires)
{ {
@ -81,7 +81,7 @@ static void update_mt_scaling(void)
memcpy(cycles_old, cycles_new, memcpy(cycles_old, cycles_new,
sizeof(u64) * (smp_cpu_mtid + 1)); sizeof(u64) * (smp_cpu_mtid + 1));
} }
__this_cpu_write(mt_scaling_jiffies, jiffies); __this_cpu_write(mt_scaling_jiffies, jiffies_64);
} }
static inline u64 update_tsk_timer(unsigned long *tsk_vtime, u64 new) static inline u64 update_tsk_timer(unsigned long *tsk_vtime, u64 new)
@ -144,7 +144,7 @@ static int do_account_vtime(struct task_struct *tsk)
lc->system_timer += timer; lc->system_timer += timer;
/* Update MT utilization calculation */ /* Update MT utilization calculation */
if (smp_cpu_mtid && time_after(jiffies, __this_cpu_read(mt_scaling_jiffies))) if (smp_cpu_mtid && time_after64(jiffies_64, __this_cpu_read(mt_scaling_jiffies)))
update_mt_scaling(); update_mt_scaling();
/* Calculate cputime delta */ /* Calculate cputime delta */

View File

@ -2168,7 +2168,7 @@ static int kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
if (args->count < 1 || args->count > KVM_S390_SKEYS_MAX) if (args->count < 1 || args->count > KVM_S390_SKEYS_MAX)
return -EINVAL; return -EINVAL;
keys = kvmalloc_objs(*keys, args->count, GFP_KERNEL_ACCOUNT); keys = kvmalloc_array(args->count, sizeof(*keys), GFP_KERNEL_ACCOUNT);
if (!keys) if (!keys)
return -ENOMEM; return -ENOMEM;
@ -2205,7 +2205,7 @@ static int kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
if (args->count < 1 || args->count > KVM_S390_SKEYS_MAX) if (args->count < 1 || args->count > KVM_S390_SKEYS_MAX)
return -EINVAL; return -EINVAL;
keys = kvmalloc_objs(*keys, args->count, GFP_KERNEL_ACCOUNT); keys = kvmalloc_array(args->count, sizeof(*keys), GFP_KERNEL_ACCOUNT);
if (!keys) if (!keys)
return -ENOMEM; return -ENOMEM;

View File

@ -55,46 +55,63 @@ static void __crst_table_upgrade(void *arg)
int crst_table_upgrade(struct mm_struct *mm, unsigned long end) int crst_table_upgrade(struct mm_struct *mm, unsigned long end)
{ {
unsigned long *table, *pgd; unsigned long *pgd = NULL, *p4d = NULL, *__pgd;
int rc, notify; unsigned long asce_limit = mm->context.asce_limit;
mmap_assert_write_locked(mm); mmap_assert_write_locked(mm);
/* upgrade should only happen from 3 to 4, 3 to 5, or 4 to 5 levels */ /* upgrade should only happen from 3 to 4, 3 to 5, or 4 to 5 levels */
VM_BUG_ON(mm->context.asce_limit < _REGION2_SIZE); VM_BUG_ON(asce_limit < _REGION2_SIZE);
rc = 0;
notify = 0; if (end <= asce_limit)
while (mm->context.asce_limit < end) { return 0;
table = crst_table_alloc(mm);
if (!table) { if (asce_limit == _REGION2_SIZE) {
rc = -ENOMEM; p4d = crst_table_alloc(mm);
break; if (unlikely(!p4d))
} goto err_p4d;
spin_lock_bh(&mm->page_table_lock); crst_table_init(p4d, _REGION2_ENTRY_EMPTY);
pgd = (unsigned long *)mm->pgd; pagetable_p4d_ctor(virt_to_ptdesc(p4d));
if (mm->context.asce_limit == _REGION2_SIZE) {
crst_table_init(table, _REGION2_ENTRY_EMPTY);
p4d_populate(mm, (p4d_t *)table, (pud_t *)pgd);
pagetable_p4d_ctor(virt_to_ptdesc(table));
mm->pgd = (pgd_t *)table;
mm->context.asce_limit = _REGION1_SIZE;
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
_ASCE_USER_BITS | _ASCE_TYPE_REGION2;
mm_inc_nr_puds(mm);
} else {
crst_table_init(table, _REGION1_ENTRY_EMPTY);
pgd_populate(mm, (pgd_t *)table, (p4d_t *)pgd);
pagetable_pgd_ctor(virt_to_ptdesc(table));
mm->pgd = (pgd_t *)table;
mm->context.asce_limit = TASK_SIZE_MAX;
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
_ASCE_USER_BITS | _ASCE_TYPE_REGION1;
}
notify = 1;
spin_unlock_bh(&mm->page_table_lock);
} }
if (notify) if (end > _REGION1_SIZE) {
on_each_cpu(__crst_table_upgrade, mm, 0); pgd = crst_table_alloc(mm);
return rc; if (unlikely(!pgd))
goto err_pgd;
crst_table_init(pgd, _REGION1_ENTRY_EMPTY);
pagetable_pgd_ctor(virt_to_ptdesc(pgd));
}
spin_lock_bh(&mm->page_table_lock);
if (p4d) {
__pgd = (unsigned long *) mm->pgd;
p4d_populate(mm, (p4d_t *) p4d, (pud_t *) __pgd);
mm->pgd = (pgd_t *) p4d;
mm->context.asce_limit = _REGION1_SIZE;
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
_ASCE_USER_BITS | _ASCE_TYPE_REGION2;
mm_inc_nr_puds(mm);
}
if (pgd) {
__pgd = (unsigned long *) mm->pgd;
pgd_populate(mm, (pgd_t *) pgd, (p4d_t *) __pgd);
mm->pgd = (pgd_t *) pgd;
mm->context.asce_limit = TASK_SIZE_MAX;
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
_ASCE_USER_BITS | _ASCE_TYPE_REGION1;
}
spin_unlock_bh(&mm->page_table_lock);
on_each_cpu(__crst_table_upgrade, mm, 0);
return 0;
err_pgd:
pagetable_dtor(virt_to_ptdesc(p4d));
crst_table_free(mm, p4d);
err_p4d:
return -ENOMEM;
} }
unsigned long *page_table_alloc_noprof(struct mm_struct *mm) unsigned long *page_table_alloc_noprof(struct mm_struct *mm)

View File

@ -153,9 +153,6 @@ static ssize_t report_error_write(struct file *filp, struct kobject *kobj,
if (off || (count < sizeof(*report))) if (off || (count < sizeof(*report)))
return -EINVAL; return -EINVAL;
if (count < (report->length + sizeof(*report)))
return -EINVAL;
ret = sclp_pci_report(report, zdev->fh, zdev->fid); ret = sclp_pci_report(report, zdev->fh, zdev->fid);
return ret ? ret : count; return ret ? ret : count;

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